Skip to content

Commit

Permalink
tui: Scroll left when there's room in tab bar after closing tabs
Browse files Browse the repository at this point in the history
Fixes #164
  • Loading branch information
osa1 committed Jan 10, 2020
1 parent 9a4161b commit aef5149
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Unreleased

- TUI: Tab bar scrolls to left after closing tabs to fit more tabs into the
visible part of the tab bar (#164). See #164 for an example of previous
behavior.

# 2020/01/08: 0.5.1

- When a domain name resolves to multiple IP addresses tiny now tries connecting
Expand Down
45 changes: 45 additions & 0 deletions libtiny_tui/src/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ impl TUI {
self.select_tab(if tab_idx == 0 { 0 } else { tab_idx - 1 });
}
}
self.fix_scroll_after_close();
}

/// Returns index of the new tab if a new tab is created.
Expand Down Expand Up @@ -354,6 +355,7 @@ impl TUI {
self.select_tab(if tab_idx == 0 { 0 } else { tab_idx - 1 });
}
}
self.fix_scroll_after_close();
}

/// Returns index of the new tab if a new tab is created.
Expand Down Expand Up @@ -392,6 +394,7 @@ impl TUI {
self.select_tab(if tab_idx == 0 { 0 } else { tab_idx - 1 });
}
}
self.fix_scroll_after_close();
}

pub(crate) fn handle_input_event(&mut self, ev: Event) -> TUIRet {
Expand Down Expand Up @@ -789,6 +792,48 @@ impl TUI {
self.tabs[self.active_idx].set_style(TabStyle::Normal);
}

/// After closing a tab scroll left if there is space on the right and we can fit more tabs
/// from the left into the visible part of the tab bar.
fn fix_scroll_after_close(&mut self) {
let (tab_left, tab_right) = self.rendered_tabs();

if tab_left == 0 {
return;
}

// Size of shown part of the tab bar. DOES NOT include LEFT_ARROW.
let mut shown_width = 0;
for (tab_idx, tab) in self.tabs[tab_left..tab_right].iter().enumerate() {
shown_width += tab.width();
if tab_idx != tab_right - 1 {
shown_width += 1; // space between tabs
}
}

// How much space left in tab bar. Not accounting for LEFT_ARROW here!
let mut space_left = self.width - shown_width;

// How much to scroll left
let mut scroll_left = 0;

// Start iterating tabs on the left, add the tab size to `scroll_left` as long as scrolling
// doesn't make the right-most tab go out of bounds
for left_tab_idx in (0..=tab_left - 1).rev() {
let tab_width = self.tabs[left_tab_idx].width() + 1; // 1 for space
let draw_arrow = left_tab_idx != 0;
let tab_with_arrow_w = tab_width + if draw_arrow { 2 } else { 0 };

if tab_with_arrow_w <= space_left {
scroll_left += tab_width;
space_left -= tab_width;
} else {
break;
}
}

self.h_scroll -= scroll_left;
}

pub(crate) fn switch(&mut self, string: &str) {
let mut next_idx = self.active_idx;
for (tab_idx, tab) in self.tabs.iter().enumerate() {
Expand Down

0 comments on commit aef5149

Please sign in to comment.