use crate::SettingsUI;
use crate::section::collapsing_section;
use par_term_config::{
NewTabPosition, RemoteTabTitleFormat, TabBarMode, TabBarPosition, TabStyle, TabTitleMode,
};
use std::collections::HashSet;
pub(super) fn show_tab_bar_section(
ui: &mut egui::Ui,
settings: &mut SettingsUI,
changes_this_frame: &mut bool,
collapsed: &mut HashSet<String>,
) {
collapsing_section(ui, "Tab Bar", "window_tab_bar", true, collapsed, |ui| {
ui.horizontal(|ui| {
ui.label("Tab style:");
let current_style = settings.config.tab_style;
egui::ComboBox::from_id_salt("window_tab_style")
.selected_text(current_style.display_name())
.show_ui(ui, |ui| {
for style in TabStyle::all() {
if ui
.selectable_value(
&mut settings.config.tab_style,
*style,
style.display_name(),
)
.changed()
{
settings.config.apply_tab_style();
settings.has_changes = true;
*changes_this_frame = true;
}
}
});
});
if settings.config.tab_style == TabStyle::Automatic {
ui.indent("auto_tab_style_indent", |ui| {
ui.horizontal(|ui| {
ui.label("Light tab style:");
let current = settings.config.light_tab_style;
egui::ComboBox::from_id_salt("window_light_tab_style")
.selected_text(current.display_name())
.show_ui(ui, |ui| {
for style in TabStyle::all_concrete() {
if ui
.selectable_value(
&mut settings.config.light_tab_style,
*style,
style.display_name(),
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
}
});
});
ui.horizontal(|ui| {
ui.label("Dark tab style:");
let current = settings.config.dark_tab_style;
egui::ComboBox::from_id_salt("window_dark_tab_style")
.selected_text(current.display_name())
.show_ui(ui, |ui| {
for style in TabStyle::all_concrete() {
if ui
.selectable_value(
&mut settings.config.dark_tab_style,
*style,
style.display_name(),
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
}
});
});
});
}
ui.horizontal(|ui| {
ui.label("Show tab bar:");
let current = match settings.config.tab_bar_mode {
TabBarMode::Always => 0,
TabBarMode::WhenMultiple => 1,
TabBarMode::Never => 2,
};
let mut selected = current;
egui::ComboBox::from_id_salt("window_tab_bar_mode")
.selected_text(match current {
0 => "Always",
1 => "When multiple tabs",
2 => "Never",
_ => "Unknown",
})
.show_ui(ui, |ui| {
ui.selectable_value(&mut selected, 0, "Always");
ui.selectable_value(&mut selected, 1, "When multiple tabs");
ui.selectable_value(&mut selected, 2, "Never");
});
if selected != current {
settings.config.tab_bar_mode = match selected {
0 => TabBarMode::Always,
1 => TabBarMode::WhenMultiple,
2 => TabBarMode::Never,
_ => TabBarMode::WhenMultiple,
};
settings.has_changes = true;
*changes_this_frame = true;
}
});
ui.horizontal(|ui| {
ui.label("Tab title mode:");
let current = match settings.config.tab_title_mode {
TabTitleMode::Auto => 0,
TabTitleMode::OscOnly => 1,
};
let mut selected = current;
egui::ComboBox::from_id_salt("window_tab_title_mode")
.selected_text(match current {
0 => "Auto (OSC + CWD)",
1 => "OSC only",
_ => "Unknown",
})
.show_ui(ui, |ui| {
ui.selectable_value(&mut selected, 0, "Auto (OSC + CWD)")
.on_hover_text("Use OSC title, fall back to working directory");
ui.selectable_value(&mut selected, 1, "OSC only")
.on_hover_text("Only use titles set by OSC escape sequences");
});
if selected != current {
settings.config.tab_title_mode = match selected {
0 => TabTitleMode::Auto,
1 => TabTitleMode::OscOnly,
_ => TabTitleMode::Auto,
};
settings.has_changes = true;
*changes_this_frame = true;
}
});
ui.horizontal(|ui| {
ui.label("Remote tab title format:");
egui::ComboBox::from_id_salt("window_remote_tab_title_format")
.selected_text(settings.config.remote_tab_title_format.display_name())
.show_ui(ui, |ui| {
for &fmt in RemoteTabTitleFormat::all() {
if ui
.selectable_value(
&mut settings.config.remote_tab_title_format,
fmt,
fmt.display_name(),
)
.on_hover_text(match fmt {
RemoteTabTitleFormat::UserAtHost => {
"Show username and hostname (e.g. paul@server)"
}
RemoteTabTitleFormat::Host => "Show hostname only",
RemoteTabTitleFormat::HostAndCwd => {
"Show hostname and current directory (e.g. server:~/projects)"
}
})
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
}
});
});
if ui
.checkbox(
&mut settings.config.remote_tab_title_osc_priority,
"OSC title takes priority on remote hosts",
)
.on_hover_text(
"When checked, explicit OSC title sequences (\\033]0;) \
override the remote tab title format",
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
ui.horizontal(|ui| {
ui.label("Position:");
let current_position = settings.config.tab_bar_position;
egui::ComboBox::from_id_salt("window_tab_bar_position")
.selected_text(current_position.display_name())
.show_ui(ui, |ui| {
for &pos in TabBarPosition::all() {
if ui
.selectable_value(
&mut settings.config.tab_bar_position,
pos,
pos.display_name(),
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
}
});
});
if settings.config.tab_bar_position == TabBarPosition::Left {
ui.horizontal(|ui| {
ui.label("Tab bar width:");
if ui
.add(
egui::Slider::new(&mut settings.config.tab_bar_width, 100.0..=300.0)
.step_by(1.0)
.suffix("px"),
)
.on_hover_text("Width of the left tab bar panel")
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
});
}
ui.horizontal(|ui| {
ui.label("Tab bar height:");
if ui
.add(
egui::Slider::new(&mut settings.config.tab_bar_height, 20.0..=50.0)
.step_by(1.0)
.suffix("px"),
)
.on_hover_text("Height of the tab bar in pixels")
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
});
if ui
.checkbox(
&mut settings.config.tab_show_index,
"Show tab index numbers",
)
.on_hover_text("Display tab numbers (1, 2, 3...) in tab titles for keyboard navigation")
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
if ui
.checkbox(
&mut settings.config.tab_show_close_button,
"Show close button on tabs",
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
if ui
.checkbox(
&mut settings.config.tab_stretch_to_fill,
"Stretch tabs to fill bar",
)
.on_hover_text("Make tabs share available width evenly when they fit without scrolling")
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
if ui
.checkbox(&mut settings.config.tab_html_titles, "HTML tab titles")
.on_hover_text(
"Render limited HTML in tab titles: <b>, <i>, <u>, <span style=\"color:...\">",
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
ui.add_space(8.0);
if ui
.checkbox(
&mut settings.config.tab_inherit_cwd,
"New tabs inherit current directory",
)
.on_hover_text("When opening a new tab, start in the same directory as the current tab")
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
ui.add_space(4.0);
ui.horizontal(|ui| {
ui.label("New tab position:");
egui::ComboBox::from_id_salt("window_new_tab_position")
.selected_text(settings.config.new_tab_position.display_name())
.show_ui(ui, |ui| {
for &pos in NewTabPosition::all() {
if ui
.selectable_value(
&mut settings.config.new_tab_position,
pos,
pos.display_name(),
)
.on_hover_text(match pos {
NewTabPosition::End => {
"New tabs are added to the end of the tab bar"
}
NewTabPosition::AfterActive => {
"New tabs open immediately to the right of the active tab"
}
})
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
}
});
});
if ui
.checkbox(
&mut settings.config.show_profile_drawer_button,
"Show profile drawer button",
)
.on_hover_text(
"Show the profile drawer toggle button on the right edge of the terminal window",
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
if ui
.checkbox(
&mut settings.config.new_tab_shortcut_shows_profiles,
"New tab shortcut shows profile picker",
)
.on_hover_text(
"When enabled, the new tab keyboard shortcut (Cmd+T / Ctrl+Shift+T) shows a profile selection dropdown instead of immediately creating a default tab",
)
.changed()
{
settings.has_changes = true;
*changes_this_frame = true;
}
ui.horizontal(|ui| {
ui.label("Maximum tabs:");
let mut max_tabs = settings.config.max_tabs as u32;
if ui
.add(egui::Slider::new(&mut max_tabs, 0..=50))
.on_hover_text("Maximum number of tabs allowed (0 = unlimited)")
.changed()
{
settings.config.max_tabs = max_tabs as usize;
settings.has_changes = true;
*changes_this_frame = true;
}
if settings.config.max_tabs == 0 {
ui.label("(unlimited)");
}
});
});
}