Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Allow styling of the whole new tab button #950

Merged
merged 1 commit into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions config/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ pub struct TabBarColors {
/// Styling for an inactive tab with a mouse hovering
#[serde(default = "default_inactive_tab_hover")]
pub inactive_tab_hover: TabBarColor,

/// Styling for the new tab button
#[serde(default = "default_inactive_tab")]
pub new_tab: TabBarColor,

/// Styling for the new tab button with a mouse hovering
#[serde(default = "default_inactive_tab_hover")]
pub new_tab_hover: TabBarColor,
}
impl_lua_conversion!(TabBarColors);

Expand Down Expand Up @@ -178,39 +186,31 @@ impl Default for TabBarColors {
inactive_tab: default_inactive_tab(),
inactive_tab_hover: default_inactive_tab_hover(),
active_tab: default_active_tab(),
new_tab: default_inactive_tab(),
new_tab_hover: default_inactive_tab_hover(),
}
}
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct TabBarStyle {
#[serde(default = "default_tab_left")]
pub new_tab_left: String,
#[serde(default = "default_tab_right")]
pub new_tab_right: String,
#[serde(default = "default_tab_left")]
pub new_tab_hover_left: String,
#[serde(default = "default_tab_right")]
pub new_tab_hover_right: String,
#[serde(default = "default_new_tab")]
pub new_tab: String,
#[serde(default = "default_new_tab")]
pub new_tab_hover: String,
}

impl Default for TabBarStyle {
fn default() -> Self {
Self {
new_tab_left: default_tab_left(),
new_tab_right: default_tab_right(),
new_tab_hover_left: default_tab_left(),
new_tab_hover_right: default_tab_right(),
new_tab: default_new_tab(),
new_tab_hover: default_new_tab(),
}
}
}

fn default_tab_left() -> String {
format_as_escapes(vec![FormatItem::Text(" ".to_string())]).unwrap()
}

fn default_tab_right() -> String {
format_as_escapes(vec![FormatItem::Text(" ".to_string())]).unwrap()
fn default_new_tab() -> String {
format_as_escapes(vec![FormatItem::Text(" + ".to_string())]).unwrap()
}

#[derive(Debug, Deserialize, Serialize, Clone)]
Expand Down
20 changes: 20 additions & 0 deletions docs/config/appearance.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,26 @@ return {

-- The same options that were listed under the `active_tab` section above
-- can also be used for `inactive_tab_hover`.
},

-- The new tab button that let you create new tabs
new_tab = {
bg_color = "#1b1032",
fg_color = "#808080",

-- The same options that were listed under the `active_tab` section above
-- can also be used for `new_tab`.
},

-- You can configure some alternate styling when the mouse pointer
-- moves over the new tab button
new_tab_hover = {
bg_color = "#3b3052",
fg_color = "#909090",
italic = true,

-- The same options that were listed under the `active_tab` section above
-- can also be used for `new_tab_hover`.
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions docs/config/lua/config/tab_bar_style.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# `tab_bar_style`

*Since: nightly builds only*

`new_tab_left`, `new_tab_right`, `new_tab_hover_left`, `new_tab_hover_right`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a since line here; when I cut a release, I will fill in the release identifier across the docs.

Suggested change
`new_tab_left`, `new_tab_right`, `new_tab_hover_left`, `new_tab_hover_right`
*Since: nightly builds only*
`new_tab_left`, `new_tab_right`, `new_tab_hover_left`, `new_tab_hover_right`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change applied and force-pushed.

have been removed and replaced by the more flexible `new_tab` and `new_tab_hover` elements.

*Since: 20210502-154244-3f7122cb*

`active_tab_left`, `active_tab_right`, `inactive_tab_left`,
Expand Down
68 changes: 21 additions & 47 deletions wezterm-gui/src/tabbar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ fn compute_tab_title(
}
}

fn is_tab_hover(mouse_x: Option<usize>, x: usize, tab_title_len: usize) -> bool {
return mouse_x
.map(|mouse_x| mouse_x >= x && mouse_x < x + tab_title_len)
.unwrap_or(false);
}

impl TabBarState {
pub fn default() -> Self {
Self {
Expand Down Expand Up @@ -173,22 +179,13 @@ impl TabBarState {
let active_cell_attrs = colors.active_tab.as_cell_attributes();
let inactive_hover_attrs = colors.inactive_tab_hover.as_cell_attributes();
let inactive_cell_attrs = colors.inactive_tab.as_cell_attributes();
let new_tab_hover_attrs = colors.new_tab_hover.as_cell_attributes();
let new_tab_attrs = colors.new_tab.as_cell_attributes();

let new_tab_left = parse_status_text(
&config.tab_bar_style.new_tab_left,
inactive_cell_attrs.clone(),
);
let new_tab_right = parse_status_text(
&config.tab_bar_style.new_tab_right,
inactive_cell_attrs.clone(),
);
let new_tab_hover_left = parse_status_text(
&config.tab_bar_style.new_tab_hover_left,
inactive_hover_attrs.clone(),
);
let new_tab_hover_right = parse_status_text(
&config.tab_bar_style.new_tab_hover_right,
inactive_hover_attrs.clone(),
let new_tab = parse_status_text(&config.tab_bar_style.new_tab, new_tab_attrs.clone());
let new_tab_hover = parse_status_text(
&config.tab_bar_style.new_tab_hover,
new_tab_hover_attrs.clone(),
);

// We ultimately want to produce a line looking like this:
Expand Down Expand Up @@ -218,9 +215,8 @@ impl TabBarState {
let titles_len: usize = tab_titles.iter().map(|s| s.len).sum();
let number_of_tabs = tab_titles.len();

let available_cells = title_width.saturating_sub(
(number_of_tabs.saturating_sub(1)) + (new_tab_left.len() + new_tab_right.len() + 1),
);
let available_cells =
title_width.saturating_sub((number_of_tabs.saturating_sub(1)) + (new_tab.len()));
let tab_width_max = if available_cells >= titles_len {
// We can render each title with its full width
usize::max_value()
Expand All @@ -238,10 +234,7 @@ impl TabBarState {
for (tab_idx, tab_title) in tab_titles.iter().enumerate() {
let tab_title_len = tab_title.len.min(tab_width_max);
let active = tab_idx == active_tab_no;
let hover = !active
&& mouse_x
.map(|mouse_x| mouse_x >= x && mouse_x < x + tab_title_len)
.unwrap_or(false);
let hover = !active && is_tab_hover(mouse_x, x, tab_title_len);

// Recompute the title so that it factors in both the hover state
// and the adjusted maximum tab width based on available space.
Expand Down Expand Up @@ -286,35 +279,16 @@ impl TabBarState {

// New tab button
{
let hover = mouse_x
.map(|mouse_x| {
mouse_x >= x
&& mouse_x < x + new_tab_hover_left.len() + new_tab_hover_right.len() + 1
})
.unwrap_or(false);

let (cell_attrs, left, right) = if hover {
(
&inactive_hover_attrs,
&new_tab_hover_left,
&new_tab_hover_right,
)
} else {
(&inactive_cell_attrs, &new_tab_left, &new_tab_right)
};
let hover = is_tab_hover(mouse_x, x, new_tab_hover.len());

let button_start = x;
let cells = if hover { &new_tab_hover } else { &new_tab };

for c in left {
line.set_cell(x, c.clone());
x += 1;
}
line.set_cell(x, Cell::new('+', cell_attrs.clone()));
x += 1;
let button_start = x;

for c in right {
for c in cells {
let len = c.width();
line.set_cell(x, c.clone());
x += 1;
x += len;
}

items.push(TabEntry {
Expand Down