table: Set fixed height to table head to fix some case table head disappear bug. (#300)
Closes #299 - Improved sort icon to better color. - Improved table story. - Disable `horizontal_scroll_handle.scroll_to_item` on select_col, there have a bug need to fix.
This commit is contained in:
parent
494e6d15f3
commit
ce10a0340c
4 changed files with 128 additions and 61 deletions
|
|
@ -2,9 +2,11 @@ use std::time::{self, Duration};
|
|||
|
||||
use fake::{Fake, Faker};
|
||||
use gpui::{
|
||||
div, AnyElement, ClickEvent, IntoElement, ParentElement, Pixels, Render, SharedString, Styled,
|
||||
Timer, View, ViewContext, VisualContext as _, WindowContext,
|
||||
div, impl_actions, AnyElement, ClickEvent, InteractiveElement, IntoElement, ParentElement,
|
||||
Pixels, Render, SharedString, Styled, Timer, View, ViewContext, VisualContext as _,
|
||||
WindowContext,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use ui::{
|
||||
button::{Button, ButtonStyled},
|
||||
checkbox::Checkbox,
|
||||
|
|
@ -12,11 +14,17 @@ use ui::{
|
|||
indicator::Indicator,
|
||||
input::{InputEvent, TextInput},
|
||||
label::Label,
|
||||
popup_menu::PopupMenuExt,
|
||||
prelude::FluentBuilder as _,
|
||||
table::{ColFixed, ColSort, Table, TableDelegate, TableEvent},
|
||||
v_flex, Selectable, Sizable, Size,
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Deserialize)]
|
||||
struct ChangeSize(Size);
|
||||
|
||||
impl_actions!(table_story, [ChangeSize]);
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct Stock {
|
||||
id: usize,
|
||||
|
|
@ -166,6 +174,7 @@ struct StockTableDelegate {
|
|||
col_sort: bool,
|
||||
col_selection: bool,
|
||||
loading: bool,
|
||||
fixed_cols: bool,
|
||||
is_eof: bool,
|
||||
}
|
||||
|
||||
|
|
@ -232,6 +241,7 @@ impl StockTableDelegate {
|
|||
col_order: true,
|
||||
col_sort: true,
|
||||
col_selection: true,
|
||||
fixed_cols: false,
|
||||
loading: false,
|
||||
is_eof: false,
|
||||
}
|
||||
|
|
@ -250,9 +260,10 @@ impl StockTableDelegate {
|
|||
let right_num = ((val - val.floor()) * 1000.).floor() as i32;
|
||||
|
||||
let this = if right_num % 3 == 0 {
|
||||
this.text_color(ui::red_600()).bg(ui::red_50())
|
||||
this.text_color(ui::red_600()).bg(ui::red_50().opacity(0.6))
|
||||
} else if right_num % 3 == 1 {
|
||||
this.text_color(ui::green_600()).bg(ui::green_50())
|
||||
this.text_color(ui::green_600())
|
||||
.bg(ui::green_50().opacity(0.6))
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
|
@ -287,6 +298,10 @@ impl TableDelegate for StockTableDelegate {
|
|||
}
|
||||
|
||||
fn col_fixed(&self, col_ix: usize) -> Option<ui::table::ColFixed> {
|
||||
if !self.fixed_cols {
|
||||
return None;
|
||||
}
|
||||
|
||||
if col_ix < 4 {
|
||||
Some(ColFixed::Left)
|
||||
} else {
|
||||
|
|
@ -548,40 +563,35 @@ impl TableStory {
|
|||
}
|
||||
|
||||
fn toggle_loop_selection(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
let table = self.table.clone();
|
||||
table.update(cx, |table, cx| {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.delegate_mut().loop_selection = *checked;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn toggle_col_resize(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
let table = self.table.clone();
|
||||
table.update(cx, |table, cx| {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.delegate_mut().col_resize = *checked;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn toggle_col_order(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
let table = self.table.clone();
|
||||
table.update(cx, |table, cx| {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.delegate_mut().col_order = *checked;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn toggle_col_sort(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
let table = self.table.clone();
|
||||
table.update(cx, |table, cx| {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.delegate_mut().col_sort = *checked;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn toggle_col_selection(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
let table = self.table.clone();
|
||||
table.update(cx, |table, cx| {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.delegate_mut().col_selection = *checked;
|
||||
cx.notify();
|
||||
});
|
||||
|
|
@ -590,24 +600,24 @@ impl TableStory {
|
|||
fn toggle_stripe(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
self.stripe = *checked;
|
||||
let stripe = self.stripe;
|
||||
let table = self.table.clone();
|
||||
table.update(cx, |table, cx| {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.set_stripe(stripe, cx);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn toggle_size(&mut self, _: &ClickEvent, cx: &mut ViewContext<Self>) {
|
||||
self.size = match self.size {
|
||||
Size::XSmall => Size::Small,
|
||||
Size::Small => Size::Medium,
|
||||
Size::Medium => Size::Large,
|
||||
Size::Large => Size::XSmall,
|
||||
_ => Size::default(),
|
||||
};
|
||||
|
||||
fn toggle_fixed_cols(&mut self, checked: &bool, cx: &mut ViewContext<Self>) {
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.set_size(self.size, cx);
|
||||
table.delegate_mut().fixed_cols = *checked;
|
||||
table.refresh(cx);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn on_change_size(&mut self, a: &ChangeSize, cx: &mut ViewContext<Self>) {
|
||||
self.size = a.0;
|
||||
self.table.update(cx, |table, cx| {
|
||||
table.set_size(a.0, cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -635,14 +645,46 @@ impl TableStory {
|
|||
impl Render for TableStory {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl gpui::IntoElement {
|
||||
let delegate = self.table.read(cx).delegate();
|
||||
let size = self.size;
|
||||
|
||||
v_flex()
|
||||
.on_action(cx.listener(Self::on_change_size))
|
||||
.size_full()
|
||||
.text_sm()
|
||||
.gap_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.items_center()
|
||||
.gap_2()
|
||||
.gap_3()
|
||||
.flex_wrap()
|
||||
.child(
|
||||
Button::new("size")
|
||||
.compact()
|
||||
.outline()
|
||||
.label(format!("size: {:?}", self.size))
|
||||
.popup_menu(move |menu, cx| {
|
||||
menu.menu_with_check(
|
||||
"Large",
|
||||
size == Size::Large,
|
||||
Box::new(ChangeSize(Size::Large)),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Medium",
|
||||
size == Size::Medium,
|
||||
Box::new(ChangeSize(Size::Medium)),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Small",
|
||||
size == Size::Small,
|
||||
Box::new(ChangeSize(Size::Small)),
|
||||
)
|
||||
.menu_with_check(
|
||||
"XSmall",
|
||||
size == Size::XSmall,
|
||||
Box::new(ChangeSize(Size::XSmall)),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
Checkbox::new("loop-selection")
|
||||
.label("Loop Selection")
|
||||
|
|
@ -680,12 +722,10 @@ impl Render for TableStory {
|
|||
.on_click(cx.listener(Self::toggle_stripe)),
|
||||
)
|
||||
.child(
|
||||
Button::new("size")
|
||||
.small()
|
||||
.compact()
|
||||
.outline()
|
||||
.label(format!("size: {:?}", self.size))
|
||||
.on_click(cx.listener(Self::toggle_size)),
|
||||
Checkbox::new("fixed-cols")
|
||||
.label("Fixed Columns")
|
||||
.selected(delegate.fixed_cols)
|
||||
.on_click(cx.listener(Self::toggle_fixed_cols)),
|
||||
)
|
||||
.child(
|
||||
Checkbox::new("refresh-data")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use crate::{
|
|||
theme::ActiveTheme,
|
||||
};
|
||||
use gpui::{div, px, Axis, Div, Element, EntityId, FocusHandle, Pixels, Styled, WindowContext};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Returns a `Div` as horizontal flex layout.
|
||||
pub fn h_flex() -> Div {
|
||||
|
|
@ -133,7 +134,7 @@ pub trait StyledExt: Styled + Sized {
|
|||
impl<E: Styled> StyledExt for E {}
|
||||
|
||||
/// A size for elements.
|
||||
#[derive(Clone, Default, Copy, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Default, Copy, PartialEq, Eq, Debug, Deserialize, Serialize)]
|
||||
pub enum Size {
|
||||
Size(Pixels),
|
||||
XSmall,
|
||||
|
|
|
|||
|
|
@ -336,9 +336,9 @@ where
|
|||
self.selected_col = Some(col_ix);
|
||||
if let Some(col_ix) = self.selected_col {
|
||||
// TODO: Fix scroll to selected col, this was not working after fixed col.
|
||||
if self.col_groups[col_ix].fixed.is_none() {
|
||||
self.horizontal_scroll_handle.scroll_to_item(col_ix);
|
||||
}
|
||||
// if self.col_groups[col_ix].fixed.is_none() {
|
||||
// self.horizontal_scroll_handle.scroll_to_item(col_ix);
|
||||
// }
|
||||
}
|
||||
cx.emit(TableEvent::SelectCol(col_ix));
|
||||
cx.notify();
|
||||
|
|
@ -426,8 +426,8 @@ where
|
|||
.whitespace_nowrap()
|
||||
.map(|this| match self.size {
|
||||
Size::XSmall => this.text_sm().py_0p5().px_1(),
|
||||
Size::Small => this.text_sm().py_1().px_1p5(),
|
||||
Size::Large => this.py_1p5().px_3(),
|
||||
Size::Small => this.text_sm().py(px(3.)).px_1p5(),
|
||||
Size::Large => this.py_2().px_3(),
|
||||
_ => this.py_1().px_2(),
|
||||
})
|
||||
}
|
||||
|
|
@ -658,10 +658,10 @@ where
|
|||
|
||||
let sort = sort.unwrap();
|
||||
|
||||
let icon = match sort {
|
||||
ColSort::Ascending => IconName::SortAscending,
|
||||
ColSort::Descending => IconName::SortDescending,
|
||||
ColSort::Default => IconName::ChevronsUpDown,
|
||||
let (icon, is_on) = match sort {
|
||||
ColSort::Ascending => (IconName::SortAscending, true),
|
||||
ColSort::Descending => (IconName::SortDescending, true),
|
||||
ColSort::Default => (IconName::ChevronsUpDown, false),
|
||||
};
|
||||
|
||||
Some(
|
||||
|
|
@ -671,8 +671,12 @@ where
|
|||
.ml_2()
|
||||
.p(px(2.))
|
||||
.rounded_sm()
|
||||
.hover(|this| this.bg(cx.theme().secondary))
|
||||
.active(|this| this.bg(cx.theme().secondary_active))
|
||||
.map(|this| match is_on {
|
||||
true => this,
|
||||
false => this.opacity(0.5),
|
||||
})
|
||||
.hover(|this| this.bg(cx.theme().secondary).opacity(7.))
|
||||
.active(|this| this.bg(cx.theme().secondary_active).opacity(1.))
|
||||
.on_mouse_down(MouseButton::Left, |_, cx| cx.stop_propagation())
|
||||
.on_click(cx.listener(move |table, _, cx| table.perform_sort(col_ix, cx)))
|
||||
.child(
|
||||
|
|
@ -787,31 +791,45 @@ where
|
|||
) -> impl IntoElement {
|
||||
let view = cx.view().clone();
|
||||
let horizontal_scroll_handle = self.horizontal_scroll_handle.clone();
|
||||
let fixed_cols_count = self
|
||||
.col_groups
|
||||
.iter()
|
||||
.filter(|col| col.fixed.is_some())
|
||||
.count();
|
||||
|
||||
h_flex()
|
||||
.w_full()
|
||||
.map(|this| match self.size {
|
||||
Size::Large => this.h_10(),
|
||||
Size::Small => this.h(px(30.)),
|
||||
Size::XSmall => this.h(px(26.)),
|
||||
_ => this.h_8(),
|
||||
})
|
||||
.flex_shrink_0()
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().border)
|
||||
.child(
|
||||
.text_color(cx.theme().table_head_foreground)
|
||||
.when(fixed_cols_count > 0, |this| {
|
||||
// Render left fixed columns
|
||||
h_flex()
|
||||
.id("table-head-fixed-left")
|
||||
.h_full()
|
||||
.bg(cx.theme().table_head)
|
||||
.border_r_1()
|
||||
.border_color(cx.theme().border)
|
||||
.children(
|
||||
self.col_groups
|
||||
.iter()
|
||||
.filter(|col| col.fixed == Some(ColFixed::Left))
|
||||
.enumerate()
|
||||
.map(|(col_ix, _)| self.render_th(col_ix, cx)),
|
||||
),
|
||||
)
|
||||
this.child(
|
||||
h_flex()
|
||||
.id("table-head-fixed-left")
|
||||
.h_full()
|
||||
.bg(cx.theme().table_head)
|
||||
.border_r_1()
|
||||
.border_color(cx.theme().border)
|
||||
.children(
|
||||
self.col_groups
|
||||
.iter()
|
||||
.filter(|col| col.fixed == Some(ColFixed::Left))
|
||||
.enumerate()
|
||||
.map(|(col_ix, _)| self.render_th(col_ix, cx)),
|
||||
),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
// Render other normal columns
|
||||
uniform_list(view.clone(), "table-uniform-list-head", 1, {
|
||||
uniform_list(view.clone(), "table-head-uniform-list", 1, {
|
||||
let horizontal_scroll_handle = horizontal_scroll_handle.clone();
|
||||
let view = view.clone();
|
||||
move |table, _, cx| {
|
||||
|
|
@ -856,6 +874,12 @@ where
|
|||
.map(|this| vec![this])
|
||||
}
|
||||
})
|
||||
.map(|this| match self.size {
|
||||
Size::Large => this.h_10(),
|
||||
Size::Small => this.h(px(30.)),
|
||||
Size::XSmall => this.h(px(26.)),
|
||||
_ => this.h_8(),
|
||||
})
|
||||
.h_full()
|
||||
.flex_1(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -315,6 +315,7 @@ pub struct Theme {
|
|||
pub table: Hsla,
|
||||
pub table_even: Hsla,
|
||||
pub table_head: Hsla,
|
||||
pub table_head_foreground: Hsla,
|
||||
pub table_row_border: Hsla,
|
||||
pub table_active: Hsla,
|
||||
pub table_hover: Hsla,
|
||||
|
|
@ -398,6 +399,7 @@ impl From<Colors> for Theme {
|
|||
table_active: colors.list_active,
|
||||
table_hover: colors.list_active.opacity(0.8),
|
||||
table_row_border: colors.border.opacity(0.5),
|
||||
table_head_foreground: colors.foreground.opacity(0.7),
|
||||
link: colors.link,
|
||||
link_hover: colors.link.lighten(0.2),
|
||||
link_active: colors.link.darken(0.2),
|
||||
|
|
|
|||
Loading…
Reference in a new issue