Scrolling multiple lines in databases and connections (#37)

* scrolling multiple line in databases and connections

* multiple lines scrolling in databases
pull/40/head
Takayuki Maeda 3 years ago committed by GitHub
parent d493f46875
commit f3e2436a1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,8 @@ use std::{collections::BTreeSet, usize};
pub enum MoveSelection {
Up,
Down,
MultipleUp,
MultipleDown,
Left,
Right,
Top,
@ -102,8 +104,10 @@ impl DatabaseTree {
pub fn move_selection(&mut self, dir: MoveSelection) -> bool {
self.selection.map_or(false, |selection| {
let new_index = match dir {
MoveSelection::Up => self.selection_updown(selection, true),
MoveSelection::Down => self.selection_updown(selection, false),
MoveSelection::Up => self.selection_up(selection, 1),
MoveSelection::Down => self.selection_down(selection, 1),
MoveSelection::MultipleUp => self.selection_up(selection, 10),
MoveSelection::MultipleDown => self.selection_down(selection, 10),
MoveSelection::Left => self.selection_left(selection),
MoveSelection::Right => self.selection_right(selection),
MoveSelection::Top => Self::selection_start(selection),
@ -188,6 +192,59 @@ impl DatabaseTree {
}
}
fn selection_up(&self, current_index: usize, lines: usize) -> Option<usize> {
let mut index = current_index;
'a: for _ in 0..lines {
loop {
if index == 0 {
break 'a;
}
index = index.saturating_sub(1);
if self.is_visible_index(index) {
break;
}
}
}
if index == current_index {
None
} else {
Some(index)
}
}
fn selection_down(&self, current_index: usize, lines: usize) -> Option<usize> {
let mut index = current_index;
let last_visible_item_index = self
.items
.tree_items
.iter()
.rposition(|x| x.info().is_visible())?;
'a: for _ in 0..lines {
loop {
if index >= last_visible_item_index {
break 'a;
}
index = index.saturating_add(1);
if self.is_visible_index(index) {
break;
}
}
}
if index == current_index {
None
} else {
Some(index)
}
}
fn selection_updown(&self, current_index: usize, up: bool) -> Option<usize> {
let mut index = current_index;
@ -207,22 +264,6 @@ impl DatabaseTree {
break;
}
let item = self
.items
.tree_items
.iter()
.filter(|item| item.info().is_visible())
.last()
.unwrap();
if !up
&& (self.selected_item().unwrap().kind().is_database()
|| self.selected_item().unwrap().kind().is_schema())
&& self.selected_item().unwrap() == item
{
break;
}
new_index
};
@ -374,6 +415,62 @@ mod test {
assert_eq!(tree.selection, Some(2));
}
#[test]
fn test_selection_multiple_up_down() {
let items = vec![Database::new(
"a".to_string(),
vec!["b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]
.iter()
.map(|x| Table::new(x.to_string()).into())
.collect(),
)];
// a
// b
// ...
// j
let mut tree = DatabaseTree::new(&items, &BTreeSet::new()).unwrap();
assert!(tree.move_selection(MoveSelection::Right));
assert_eq!(tree.selection, Some(0));
assert!(tree.move_selection(MoveSelection::MultipleDown));
assert_eq!(tree.selection, Some(10));
tree.selection = Some(11);
assert!(tree.move_selection(MoveSelection::MultipleUp));
assert_eq!(tree.selection, Some(1));
let items = vec![Database::new(
"a".to_string(),
vec![Schema {
name: "b".to_string(),
tables: vec!["c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]
.iter()
.map(|x| Table::new(x.to_string()).into())
.collect(),
}
.into()],
)];
// a
// b
// c
// ...
// l
let mut tree = DatabaseTree::new(&items, &BTreeSet::new()).unwrap();
assert!(tree.move_selection(MoveSelection::Right));
assert_eq!(tree.selection, Some(0));
assert!(tree.move_selection(MoveSelection::MultipleDown));
assert_eq!(tree.selection, Some(10));
tree.selection = Some(11);
assert!(tree.move_selection(MoveSelection::MultipleUp));
assert_eq!(tree.selection, Some(1));
}
#[test]
fn test_selection_skips_collapsed() {
let items = vec![

@ -24,7 +24,9 @@ impl DatabaseTreeItems {
tree_items: self
.tree_items
.iter()
.filter(|item| item.is_database() || item.is_match(&filter_text))
.filter(|item| {
item.is_database() || item.kind().is_schema() || item.is_match(&filter_text)
})
.map(|item| {
let mut item = item.clone();
if item.is_database() {

@ -31,32 +31,46 @@ impl ConnectionsComponent {
}
}
fn next_connection(&mut self) {
fn next_connection(&mut self, lines: usize) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.connections.len() - 1 {
self.connections.len() - 1
if i + lines >= self.connections.len() {
Some(self.connections.len() - 1)
} else {
i + 1
Some(i + lines)
}
}
None => 0,
None => None,
};
self.state.select(Some(i));
self.state.select(i);
}
fn previous_connection(&mut self) {
fn previous_connection(&mut self, lines: usize) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
0
if i <= lines {
Some(0)
} else {
i - 1
Some(i - lines)
}
}
None => 0,
None => None,
};
self.state.select(Some(i));
self.state.select(i);
}
fn scroll_to_top(&mut self) {
if self.connections.is_empty() {
return;
}
self.state.select(Some(0));
}
fn scroll_to_bottom(&mut self) {
if self.connections.is_empty() {
return;
}
self.state.select(Some(self.connections.len() - 1));
}
pub fn selected_connection(&self) -> Option<&Connection> {
@ -101,10 +115,22 @@ impl Component for ConnectionsComponent {
fn event(&mut self, key: Key) -> Result<EventState> {
if key == self.key_config.scroll_down {
self.next_connection();
self.next_connection(1);
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_up {
self.previous_connection();
self.previous_connection(1);
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_down_multiple_lines {
self.next_connection(10);
return Ok(EventState::NotConsumed);
} else if key == self.key_config.scroll_up_multiple_lines {
self.previous_connection(10);
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_to_top {
self.scroll_to_top();
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_to_bottom {
self.scroll_to_bottom();
return Ok(EventState::Consumed);
}
Ok(EventState::NotConsumed)

@ -123,7 +123,7 @@ impl TableComponent {
self.selected_row.select(i);
}
fn scroll_top(&mut self) {
fn scroll_to_top(&mut self) {
if self.rows.is_empty() {
return;
}
@ -131,7 +131,7 @@ impl TableComponent {
self.selected_row.select(Some(0));
}
fn scroll_bottom(&mut self) {
fn scroll_to_bottom(&mut self) {
if self.rows.is_empty() {
return;
}
@ -504,10 +504,10 @@ impl Component for TableComponent {
self.previous_row(10);
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_to_top {
self.scroll_top();
self.scroll_to_top();
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_to_bottom {
self.scroll_bottom();
self.scroll_to_bottom();
return Ok(EventState::Consumed);
} else if key == self.key_config.scroll_right {
self.next_column();

@ -10,6 +10,10 @@ pub fn common_nav(key: Key, key_config: &KeyConfig) -> Option<MoveSelection> {
Some(MoveSelection::Down)
} else if key == key_config.scroll_up {
Some(MoveSelection::Up)
} else if key == key_config.scroll_down_multiple_lines {
Some(MoveSelection::MultipleDown)
} else if key == key_config.scroll_up_multiple_lines {
Some(MoveSelection::MultipleUp)
} else if key == key_config.scroll_right {
Some(MoveSelection::Right)
} else if key == key_config.scroll_left {

Loading…
Cancel
Save