Enable to change database tree width (#99)

* add a border width

* add a left_chunk_percentage field

* add keys for extending widget width

* fix completion pop-ups so that they do not protrude from frame

* use expand_or_shorten_widget_width

* handle extend shorten widget width event after component events

* add tests

* add command description

* add tests

* change commands help order

* fix extend_or_shorten_widget_width help

* change left_chunk_percentage to left_main_chunk_percentage
pull/118/head
Takayuki Maeda 3 years ago committed by GitHub
parent 3b7f837724
commit 950992df8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -34,6 +34,7 @@ pub struct App {
databases: DatabasesComponent, databases: DatabasesComponent,
connections: ConnectionsComponent, connections: ConnectionsComponent,
pool: Option<Box<dyn Pool>>, pool: Option<Box<dyn Pool>>,
left_main_chunk_percentage: u16,
pub config: Config, pub config: Config,
pub error: ErrorComponent, pub error: ErrorComponent,
} }
@ -54,6 +55,7 @@ impl App {
error: ErrorComponent::new(config.key_config), error: ErrorComponent::new(config.key_config),
focus: Focus::ConnectionList, focus: Focus::ConnectionList,
pool: None, pool: None,
left_main_chunk_percentage: 15,
} }
} }
@ -73,7 +75,10 @@ impl App {
let main_chunks = Layout::default() let main_chunks = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints([Constraint::Percentage(15), Constraint::Percentage(85)]) .constraints([
Constraint::Percentage(self.left_main_chunk_percentage),
Constraint::Percentage((100_u16).saturating_sub(self.left_main_chunk_percentage)),
])
.split(f.size()); .split(f.size());
self.databases self.databases
@ -122,15 +127,18 @@ impl App {
fn commands(&self) -> Vec<CommandInfo> { fn commands(&self) -> Vec<CommandInfo> {
let mut res = vec![ let mut res = vec![
CommandInfo::new(command::filter(&self.config.key_config)),
CommandInfo::new(command::help(&self.config.key_config)),
CommandInfo::new(command::toggle_tabs(&self.config.key_config)),
CommandInfo::new(command::scroll(&self.config.key_config)), CommandInfo::new(command::scroll(&self.config.key_config)),
CommandInfo::new(command::scroll_to_top_bottom(&self.config.key_config)), CommandInfo::new(command::scroll_to_top_bottom(&self.config.key_config)),
CommandInfo::new(command::scroll_up_down_multiple_lines( CommandInfo::new(command::scroll_up_down_multiple_lines(
&self.config.key_config, &self.config.key_config,
)), )),
CommandInfo::new(command::move_focus(&self.config.key_config)), CommandInfo::new(command::move_focus(&self.config.key_config)),
CommandInfo::new(command::filter(&self.config.key_config)), CommandInfo::new(command::extend_or_shorten_widget_width(
CommandInfo::new(command::help(&self.config.key_config)), &self.config.key_config,
CommandInfo::new(command::toggle_tabs(&self.config.key_config)), )),
]; ];
self.databases.commands(&mut res); self.databases.commands(&mut res);
@ -301,7 +309,7 @@ impl App {
Ok(EventState::NotConsumed) Ok(EventState::NotConsumed)
} }
pub async fn components_event(&mut self, key: Key) -> anyhow::Result<EventState> { async fn components_event(&mut self, key: Key) -> anyhow::Result<EventState> {
if self.error.event(key)?.is_consumed() { if self.error.event(key)?.is_consumed() {
return Ok(EventState::Consumed); return Ok(EventState::Consumed);
} }
@ -329,7 +337,9 @@ impl App {
return Ok(EventState::Consumed); return Ok(EventState::Consumed);
} }
return Ok(state); if state.is_consumed() {
return Ok(EventState::Consumed);
}
} }
Focus::Table => { Focus::Table => {
match self.tab.selected_tab { match self.tab.selected_tab {
@ -430,10 +440,37 @@ impl App {
}; };
} }
} }
if self.extend_or_shorten_widget_width(key)?.is_consumed() {
return Ok(EventState::Consumed);
};
Ok(EventState::NotConsumed) Ok(EventState::NotConsumed)
} }
pub fn move_focus(&mut self, key: Key) -> anyhow::Result<EventState> { fn extend_or_shorten_widget_width(&mut self, key: Key) -> anyhow::Result<EventState> {
if key
== self
.config
.key_config
.extend_or_shorten_widget_width_to_left
{
self.left_main_chunk_percentage =
self.left_main_chunk_percentage.saturating_sub(5).max(15);
return Ok(EventState::Consumed);
} else if key
== self
.config
.key_config
.extend_or_shorten_widget_width_to_right
{
self.left_main_chunk_percentage = (self.left_main_chunk_percentage + 5).min(70);
return Ok(EventState::Consumed);
}
Ok(EventState::NotConsumed)
}
fn move_focus(&mut self, key: Key) -> anyhow::Result<EventState> {
if key == self.config.key_config.focus_connections { if key == self.config.key_config.focus_connections {
self.focus = Focus::ConnectionList; self.focus = Focus::ConnectionList;
return Ok(EventState::Consumed); return Ok(EventState::Consumed);
@ -464,3 +501,38 @@ impl App {
Ok(EventState::NotConsumed) Ok(EventState::NotConsumed)
} }
} }
#[cfg(test)]
mod test {
use super::{App, Config, EventState, Key};
#[test]
fn test_extend_or_shorten_widget_width() {
let mut app = App::new(Config::default());
assert_eq!(
app.extend_or_shorten_widget_width(Key::Char('>')).unwrap(),
EventState::Consumed
);
assert_eq!(app.left_main_chunk_percentage, 20);
app.left_main_chunk_percentage = 70;
assert_eq!(
app.extend_or_shorten_widget_width(Key::Char('>')).unwrap(),
EventState::Consumed
);
assert_eq!(app.left_main_chunk_percentage, 70);
assert_eq!(
app.extend_or_shorten_widget_width(Key::Char('<')).unwrap(),
EventState::Consumed
);
assert_eq!(app.left_main_chunk_percentage, 65);
app.left_main_chunk_percentage = 15;
assert_eq!(
app.extend_or_shorten_widget_width(Key::Char('<')).unwrap(),
EventState::Consumed
);
assert_eq!(app.left_main_chunk_percentage, 15);
}
}

@ -95,6 +95,16 @@ pub fn extend_selection_by_one_cell(key: &KeyConfig) -> CommandText {
) )
} }
pub fn extend_or_shorten_widget_width(key: &KeyConfig) -> CommandText {
CommandText::new(
format!(
"Extend/shorten widget width to left/right [{},{}]",
key.extend_or_shorten_widget_width_to_left, key.extend_or_shorten_widget_width_to_right
),
CMD_GROUP_GENERAL,
)
}
pub fn tab_records(key: &KeyConfig) -> CommandText { pub fn tab_records(key: &KeyConfig) -> CommandText {
CommandText::new(format!("Records [{}]", key.tab_records), CMD_GROUP_TABLE) CommandText::new(format!("Records [{}]", key.tab_records), CMD_GROUP_TABLE)
} }

@ -110,8 +110,11 @@ impl MovableComponent for CompletionComponent {
let area = Rect::new( let area = Rect::new(
area.x + x, area.x + x,
area.y + y + 2, area.y + y + 2,
width.min(f.size().width), width
candidates.len().min(5) as u16 + 2, .min(f.size().width)
.min(f.size().right().saturating_sub(area.x + x)),
(candidates.len().min(5) as u16 + 2)
.min(f.size().bottom().saturating_sub(area.y + y + 2)),
); );
f.render_widget(Clear, area); f.render_widget(Clear, area);
f.render_stateful_widget(candidate_list, area, &mut self.state); f.render_stateful_widget(candidate_list, area, &mut self.state);

@ -37,7 +37,7 @@ use std::convert::TryInto;
use tui::{backend::Backend, layout::Rect, Frame}; use tui::{backend::Backend, layout::Rect, Frame};
use unicode_width::UnicodeWidthChar; use unicode_width::UnicodeWidthChar;
#[derive(PartialEq)] #[derive(PartialEq, Debug)]
pub enum EventState { pub enum EventState {
Consumed, Consumed,
NotConsumed, NotConsumed,

@ -314,7 +314,7 @@ impl TableComponent {
) )
.clamp(&3, &20) .clamp(&3, &20)
}); });
if widths.iter().map(|(_, width)| width).sum::<usize>() + length + widths.len() if widths.iter().map(|(_, width)| width).sum::<usize>() + length + widths.len() + 1
>= area_width.saturating_sub(number_column_width) as usize >= area_width.saturating_sub(number_column_width) as usize
{ {
column_index += 1; column_index += 1;
@ -332,7 +332,7 @@ impl TableComponent {
let selected_column_index = widths.len().saturating_sub(1); let selected_column_index = widths.len().saturating_sub(1);
let mut column_index = far_right_column_index + 1; let mut column_index = far_right_column_index + 1;
while widths.iter().map(|(_, width)| width).sum::<usize>() + widths.len() while widths.iter().map(|(_, width)| width).sum::<usize>() + widths.len()
<= area_width.saturating_sub(number_column_width) as usize < area_width.saturating_sub(number_column_width) as usize
{ {
let length = self let length = self
.rows .rows

@ -102,6 +102,8 @@ pub struct KeyConfig {
pub tab_constraints: Key, pub tab_constraints: Key,
pub tab_foreign_keys: Key, pub tab_foreign_keys: Key,
pub tab_indexes: Key, pub tab_indexes: Key,
pub extend_or_shorten_widget_width_to_right: Key,
pub extend_or_shorten_widget_width_to_left: Key,
} }
impl Default for KeyConfig { impl Default for KeyConfig {
@ -136,6 +138,8 @@ impl Default for KeyConfig {
tab_constraints: Key::Char('3'), tab_constraints: Key::Char('3'),
tab_foreign_keys: Key::Char('4'), tab_foreign_keys: Key::Char('4'),
tab_indexes: Key::Char('5'), tab_indexes: Key::Char('5'),
extend_or_shorten_widget_width_to_right: Key::Char('>'),
extend_or_shorten_widget_width_to_left: Key::Char('<'),
} }
} }
} }

Loading…
Cancel
Save