mirror of
https://github.com/TaKO8Ki/gobang.git
synced 2021-09-19 22:32:56 +03:00
move table_status under table
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
[[conn]]
|
||||
type = "mysql"
|
||||
name = "sample"
|
||||
user = "root"
|
||||
host = "localhost"
|
||||
database = "world"
|
||||
port = 3306
|
||||
|
||||
[[conn]]
|
||||
type = "mysql"
|
||||
user = "root"
|
||||
host = "localhost"
|
||||
port = 3306
|
||||
|
||||
11
src/app.rs
11
src/app.rs
@@ -33,7 +33,6 @@ pub struct App {
|
||||
help: HelpComponent,
|
||||
databases: DatabasesComponent,
|
||||
connections: ConnectionsComponent,
|
||||
table_status: TableStatusComponent,
|
||||
pool: Option<Box<dyn Pool>>,
|
||||
pub config: Config,
|
||||
pub error: ErrorComponent,
|
||||
@@ -52,7 +51,6 @@ impl App {
|
||||
tab: TabComponent::new(config.key_config.clone()),
|
||||
help: HelpComponent::new(config.key_config.clone()),
|
||||
databases: DatabasesComponent::new(config.key_config.clone()),
|
||||
table_status: TableStatusComponent::default(),
|
||||
error: ErrorComponent::new(config.key_config),
|
||||
focus: Focus::ConnectionList,
|
||||
pool: None,
|
||||
@@ -77,15 +75,10 @@ impl App {
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(15), Constraint::Percentage(85)])
|
||||
.split(f.size());
|
||||
let left_chunks = Layout::default()
|
||||
.constraints([Constraint::Min(8), Constraint::Length(7)].as_ref())
|
||||
.split(main_chunks[0]);
|
||||
|
||||
self.databases
|
||||
.draw(f, left_chunks[0], matches!(self.focus, Focus::DabataseList))
|
||||
.draw(f, main_chunks[0], matches!(self.focus, Focus::DabataseList))
|
||||
.unwrap();
|
||||
self.table_status
|
||||
.draw(f, left_chunks[1], matches!(self.focus, Focus::DabataseList))?;
|
||||
|
||||
let right_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
@@ -268,8 +261,6 @@ impl App {
|
||||
table.clone(),
|
||||
);
|
||||
}
|
||||
self.table_status
|
||||
.update(self.record_table.len() as u64, table);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ impl DatabasesComponent {
|
||||
Self {
|
||||
tree: DatabaseTree::default(),
|
||||
filterd_tree: None,
|
||||
scroll: VerticalScroll::new(),
|
||||
scroll: VerticalScroll::new(true, true),
|
||||
input: Vec::new(),
|
||||
input_idx: 0,
|
||||
input_cursor_position: 0,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
utils::scroll_vertical::VerticalScroll, Component, DrawableComponent, EventState,
|
||||
TableValueComponent,
|
||||
TableStatusComponent, TableValueComponent,
|
||||
};
|
||||
use crate::components::command::{self, CommandInfo};
|
||||
use crate::config::KeyConfig;
|
||||
@@ -40,7 +40,7 @@ impl TableComponent {
|
||||
selected_column: 0,
|
||||
selection_area_corner: None,
|
||||
column_page_start: std::cell::Cell::new(0),
|
||||
scroll: VerticalScroll::new(),
|
||||
scroll: VerticalScroll::new(false, false),
|
||||
eod: false,
|
||||
key_config,
|
||||
}
|
||||
@@ -68,7 +68,7 @@ impl TableComponent {
|
||||
self.selected_column = 0;
|
||||
self.selection_area_corner = None;
|
||||
self.column_page_start = std::cell::Cell::new(0);
|
||||
self.scroll = VerticalScroll::new();
|
||||
self.scroll = VerticalScroll::new(false, false);
|
||||
self.eod = false;
|
||||
self.table = Some((database, table));
|
||||
}
|
||||
@@ -80,7 +80,7 @@ impl TableComponent {
|
||||
self.selected_column = 0;
|
||||
self.selection_area_corner = None;
|
||||
self.column_page_start = std::cell::Cell::new(0);
|
||||
self.scroll = VerticalScroll::new();
|
||||
self.scroll = VerticalScroll::new(false, false);
|
||||
self.eod = false;
|
||||
self.table = None;
|
||||
}
|
||||
@@ -406,6 +406,25 @@ impl DrawableComponent for TableComponent {
|
||||
.constraints(vec![Constraint::Length(3), Constraint::Length(5)])
|
||||
.split(area);
|
||||
|
||||
f.render_widget(
|
||||
Block::default()
|
||||
.title(self.title())
|
||||
.borders(Borders::ALL)
|
||||
.style(if focused {
|
||||
Style::default()
|
||||
} else {
|
||||
Style::default().fg(Color::DarkGray)
|
||||
}),
|
||||
layout[1],
|
||||
);
|
||||
|
||||
let chunks = Layout::default()
|
||||
.vertical_margin(1)
|
||||
.horizontal_margin(1)
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Min(1), Constraint::Length(2)].as_ref())
|
||||
.split(layout[1]);
|
||||
|
||||
self.selected_row.selected().map_or_else(
|
||||
|| {
|
||||
self.scroll.reset();
|
||||
@@ -422,9 +441,9 @@ impl DrawableComponent for TableComponent {
|
||||
TableValueComponent::new(self.selected_cells().unwrap_or_default())
|
||||
.draw(f, layout[0], focused)?;
|
||||
|
||||
let block = Block::default().borders(Borders::ALL).title(self.title());
|
||||
let block = Block::default().borders(Borders::NONE);
|
||||
let (selected_column_index, headers, rows, constraints) =
|
||||
self.calculate_cell_widths(block.inner(layout[1]).width);
|
||||
self.calculate_cell_widths(block.inner(chunks[0]).width);
|
||||
let header_cells = headers.iter().enumerate().map(|(column_index, h)| {
|
||||
Cell::from(h.to_string()).style(if selected_column_index == column_index {
|
||||
Style::default().add_modifier(Modifier::BOLD)
|
||||
@@ -466,7 +485,7 @@ impl DrawableComponent for TableComponent {
|
||||
let mut state = self.selected_row.clone();
|
||||
f.render_stateful_widget(
|
||||
table,
|
||||
layout[1],
|
||||
chunks[0],
|
||||
if let Some((_, y)) = self.selection_area_corner {
|
||||
state.select(Some(y));
|
||||
&mut state
|
||||
@@ -475,7 +494,22 @@ impl DrawableComponent for TableComponent {
|
||||
},
|
||||
);
|
||||
|
||||
self.scroll.draw(f, layout[1]);
|
||||
TableStatusComponent::new(
|
||||
if self.rows.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.rows.len())
|
||||
},
|
||||
if self.headers.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.headers.len())
|
||||
},
|
||||
self.table.as_ref().map_or(None, |t| Some(t.1.clone())),
|
||||
)
|
||||
.draw(f, chunks[1], focused)?;
|
||||
|
||||
self.scroll.draw(f, chunks[0]);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,79 +8,65 @@ use tui::{
|
||||
layout::Rect,
|
||||
style::{Color, Style},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Borders, List, ListItem},
|
||||
widgets::{Block, Borders, Paragraph, Wrap},
|
||||
Frame,
|
||||
};
|
||||
|
||||
pub struct TableStatusComponent {
|
||||
rows_count: u64,
|
||||
column_count: Option<usize>,
|
||||
row_count: Option<usize>,
|
||||
table: Option<Table>,
|
||||
}
|
||||
|
||||
impl Default for TableStatusComponent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
rows_count: 0,
|
||||
row_count: None,
|
||||
column_count: None,
|
||||
table: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TableStatusComponent {
|
||||
pub fn update(&mut self, count: u64, table: Table) {
|
||||
self.rows_count = count;
|
||||
self.table = Some(table);
|
||||
}
|
||||
|
||||
fn status_str(&self) -> Vec<String> {
|
||||
if let Some(table) = self.table.as_ref() {
|
||||
return vec![
|
||||
format!(
|
||||
"created: {}",
|
||||
table
|
||||
.create_time
|
||||
.map(|time| time.to_string())
|
||||
.unwrap_or_default()
|
||||
),
|
||||
format!(
|
||||
"updated: {}",
|
||||
table
|
||||
.update_time
|
||||
.map(|time| time.to_string())
|
||||
.unwrap_or_default()
|
||||
),
|
||||
format!(
|
||||
"engine: {}",
|
||||
table
|
||||
.engine
|
||||
.as_ref()
|
||||
.map(|engine| engine.to_string())
|
||||
.unwrap_or_default()
|
||||
),
|
||||
format!("rows: {}", self.rows_count),
|
||||
];
|
||||
pub fn new(
|
||||
row_count: Option<usize>,
|
||||
column_count: Option<usize>,
|
||||
table: Option<Table>,
|
||||
) -> Self {
|
||||
Self {
|
||||
row_count,
|
||||
column_count,
|
||||
table,
|
||||
}
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DrawableComponent for TableStatusComponent {
|
||||
fn draw<B: Backend>(&mut self, f: &mut Frame<B>, area: Rect, focused: bool) -> Result<()> {
|
||||
let table_status: Vec<ListItem> = self
|
||||
.status_str()
|
||||
.iter()
|
||||
.map(|i| {
|
||||
ListItem::new(vec![Spans::from(Span::raw(i.to_string()))]).style(Style::default())
|
||||
})
|
||||
.collect();
|
||||
let tasks = List::new(table_status).block(Block::default().borders(Borders::ALL).style(
|
||||
if focused {
|
||||
Style::default()
|
||||
} else {
|
||||
Style::default().fg(Color::DarkGray)
|
||||
},
|
||||
));
|
||||
f.render_widget(tasks, area);
|
||||
let status = Paragraph::new(Spans::from(vec![
|
||||
Span::from("rows: "),
|
||||
Span::from(format!(
|
||||
"{}, ",
|
||||
self.row_count.map_or("-".to_string(), |c| c.to_string())
|
||||
)),
|
||||
Span::from("columns: "),
|
||||
Span::from(format!(
|
||||
"{}, ",
|
||||
self.column_count.map_or("-".to_string(), |c| c.to_string())
|
||||
)),
|
||||
Span::from("engine: "),
|
||||
Span::from(self.table.as_ref().map_or("-".to_string(), |c| {
|
||||
c.engine.as_ref().map_or("-".to_string(), |e| e.to_string())
|
||||
})),
|
||||
]))
|
||||
.block(Block::default().borders(Borders::TOP).style(if focused {
|
||||
Style::default()
|
||||
} else {
|
||||
Style::default().fg(Color::DarkGray)
|
||||
}))
|
||||
.wrap(Wrap { trim: true });
|
||||
f.render_widget(status, area);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,17 @@ use tui::{backend::Backend, layout::Rect, Frame};
|
||||
pub struct VerticalScroll {
|
||||
top: Cell<usize>,
|
||||
max_top: Cell<usize>,
|
||||
inside: bool,
|
||||
border: bool,
|
||||
}
|
||||
|
||||
impl VerticalScroll {
|
||||
pub const fn new() -> Self {
|
||||
pub const fn new(border: bool, inside: bool) -> Self {
|
||||
Self {
|
||||
top: Cell::new(0),
|
||||
max_top: Cell::new(0),
|
||||
border,
|
||||
inside,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +42,14 @@ impl VerticalScroll {
|
||||
}
|
||||
|
||||
pub fn draw<B: Backend>(&self, f: &mut Frame<B>, r: Rect) {
|
||||
draw_scrollbar(f, r, self.max_top.get(), self.top.get());
|
||||
draw_scrollbar(
|
||||
f,
|
||||
r,
|
||||
self.max_top.get(),
|
||||
self.top.get(),
|
||||
self.border,
|
||||
self.inside,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,19 @@ struct Scrollbar {
|
||||
pos: u16,
|
||||
style_bar: Style,
|
||||
style_pos: Style,
|
||||
inside: bool,
|
||||
border: bool,
|
||||
}
|
||||
|
||||
impl Scrollbar {
|
||||
fn new(max: usize, pos: usize) -> Self {
|
||||
fn new(max: usize, pos: usize, border: bool, inside: bool) -> Self {
|
||||
Self {
|
||||
max: u16::try_from(max).unwrap_or_default(),
|
||||
pos: u16::try_from(pos).unwrap_or_default(),
|
||||
style_pos: Style::default(),
|
||||
style_bar: Style::default(),
|
||||
inside,
|
||||
border,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +42,11 @@ impl Widget for Scrollbar {
|
||||
return;
|
||||
}
|
||||
|
||||
let right = area.right().saturating_sub(1);
|
||||
let right = if self.inside {
|
||||
area.right().saturating_sub(1)
|
||||
} else {
|
||||
area.right()
|
||||
};
|
||||
if right <= area.left() {
|
||||
return;
|
||||
};
|
||||
@@ -46,7 +54,7 @@ impl Widget for Scrollbar {
|
||||
let (bar_top, bar_height) = {
|
||||
let scrollbar_area = area.inner(&Margin {
|
||||
horizontal: 0,
|
||||
vertical: 1,
|
||||
vertical: if self.border { 1 } else { 0 },
|
||||
});
|
||||
|
||||
(scrollbar_area.top(), scrollbar_area.height)
|
||||
@@ -67,8 +75,15 @@ impl Widget for Scrollbar {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_scrollbar<B: Backend>(f: &mut Frame<B>, r: Rect, max: usize, pos: usize) {
|
||||
let mut widget = Scrollbar::new(max, pos);
|
||||
pub fn draw_scrollbar<B: Backend>(
|
||||
f: &mut Frame<B>,
|
||||
r: Rect,
|
||||
max: usize,
|
||||
pos: usize,
|
||||
border: bool,
|
||||
inside: bool,
|
||||
) {
|
||||
let mut widget = Scrollbar::new(max, pos, border, inside);
|
||||
widget.style_pos = Style::default().fg(Color::Blue);
|
||||
f.render_widget(widget, r);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user