list, table: Add scroll_to_item to List, scroll_to_row to Table. (#535)
This commit is contained in:
parent
8aac2f75e4
commit
bf82e3db13
4 changed files with 142 additions and 73 deletions
|
|
@ -3,17 +3,18 @@ use std::time::Duration;
|
|||
|
||||
use fake::Fake;
|
||||
use gpui::{
|
||||
actions, div, px, relative, AnyElement, AppContext, ElementId, FocusHandle, FocusableView,
|
||||
InteractiveElement, IntoElement, ParentElement, Render, RenderOnce, Styled, Task, Timer, View,
|
||||
ViewContext, VisualContext, WindowContext,
|
||||
actions, div, px, AppContext, ElementId, FocusHandle, FocusableView, InteractiveElement,
|
||||
IntoElement, ParentElement, Render, RenderOnce, Styled, Task, Timer, View, ViewContext,
|
||||
VisualContext, WindowContext,
|
||||
};
|
||||
|
||||
use ui::{
|
||||
button::Button,
|
||||
h_flex,
|
||||
label::Label,
|
||||
list::{List, ListDelegate, ListItem},
|
||||
theme::{hsl, ActiveTheme},
|
||||
v_flex,
|
||||
v_flex, Sizable,
|
||||
};
|
||||
|
||||
actions!(list_story, [SelectedCompany]);
|
||||
|
|
@ -171,39 +172,6 @@ impl ListDelegate for CompanyListDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_initial(&self, cx: &mut ViewContext<List<Self>>) -> Option<AnyElement> {
|
||||
let histories = ["BABA", "BIDU", "GOOGL", "LB", "LP", "LBW"];
|
||||
|
||||
let input_history = histories
|
||||
.into_iter()
|
||||
.map(|name| {
|
||||
div()
|
||||
.rounded_xl()
|
||||
.min_w(px(30.))
|
||||
.border_1()
|
||||
.rounded_md()
|
||||
.border_color(cx.theme().muted_foreground.opacity(0.3))
|
||||
.line_height(relative(1.))
|
||||
.p_1()
|
||||
.child(div().whitespace_nowrap().child(name).text_xs())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let element = v_flex()
|
||||
.p_4()
|
||||
.child(
|
||||
v_flex().gap_y_2().child("History").child(
|
||||
h_flex()
|
||||
.gap_x_4()
|
||||
.gap_y_2()
|
||||
.flex_wrap()
|
||||
.children(input_history),
|
||||
),
|
||||
)
|
||||
.into_any_element();
|
||||
Some(element)
|
||||
}
|
||||
|
||||
fn set_selected_index(&mut self, ix: Option<usize>, cx: &mut ViewContext<List<Self>>) {
|
||||
if let Some(ix) = ix {
|
||||
self.selected_index = ix;
|
||||
|
|
@ -357,14 +325,43 @@ impl FocusableView for ListStory {
|
|||
|
||||
impl Render for ListStory {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
div()
|
||||
v_flex()
|
||||
.track_focus(&self.focus_handle)
|
||||
.on_action(cx.listener(Self::selected_company))
|
||||
.size_full()
|
||||
.gap_4()
|
||||
.border_1()
|
||||
.border_color(cx.theme().border)
|
||||
.rounded_md()
|
||||
.child(self.company_list.clone())
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
Button::new("scroll-top")
|
||||
.child("Scroll to Top")
|
||||
.small()
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.company_list.update(cx, |list, cx| {
|
||||
list.scroll_to_item(0, cx);
|
||||
})
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
Button::new("scroll-bottom")
|
||||
.child("Scroll to Bottom")
|
||||
.small()
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.company_list.update(cx, |list, cx| {
|
||||
list.scroll_to_item(list.delegate().items_count(cx) - 1, cx);
|
||||
})
|
||||
})),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.w_full()
|
||||
.border_1()
|
||||
.border_color(cx.theme().border)
|
||||
.rounded_md()
|
||||
.child(self.company_list.clone()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use gpui::{
|
|||
};
|
||||
use serde::Deserialize;
|
||||
use ui::{
|
||||
button::{Button, ButtonVariants},
|
||||
button::Button,
|
||||
checkbox::Checkbox,
|
||||
h_flex,
|
||||
indicator::Indicator,
|
||||
|
|
@ -18,7 +18,7 @@ use ui::{
|
|||
prelude::FluentBuilder as _,
|
||||
table::{ColFixed, ColSort, Table, TableDelegate, TableEvent},
|
||||
theme::ActiveTheme as _,
|
||||
v_flex, Selectable, Size, StyleSized as _,
|
||||
v_flex, Selectable, Sizable as _, Size, StyleSized as _,
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Deserialize)]
|
||||
|
|
@ -707,34 +707,6 @@ impl Render for TableStory {
|
|||
.items_center()
|
||||
.gap_3()
|
||||
.flex_wrap()
|
||||
.child(
|
||||
Button::new("size")
|
||||
.compact()
|
||||
.outline()
|
||||
.label(format!("size: {:?}", self.size))
|
||||
.popup_menu(move |menu, _| {
|
||||
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")
|
||||
|
|
@ -784,6 +756,76 @@ impl Render for TableStory {
|
|||
.on_click(cx.listener(Self::toggle_refresh_data)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
Button::new("size")
|
||||
.small()
|
||||
.label(format!("size: {:?}", self.size))
|
||||
.popup_menu(move |menu, _| {
|
||||
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(
|
||||
Button::new("scroll-top")
|
||||
.child("Scroll to Top")
|
||||
.small()
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.table.update(cx, |table, cx| {
|
||||
table.scroll_to_row(0, cx);
|
||||
})
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
Button::new("scroll-bottom")
|
||||
.child("Scroll to Bottom")
|
||||
.small()
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.table.update(cx, |table, cx| {
|
||||
table.scroll_to_row(table.delegate().rows_count(cx) - 1, cx);
|
||||
})
|
||||
})),
|
||||
), // .child(
|
||||
// Button::new("scroll-first-col")
|
||||
// .child("Scroll to First Column")
|
||||
// .small()
|
||||
// .on_click(cx.listener(|this, _, cx| {
|
||||
// this.table.update(cx, |table, cx| {
|
||||
// table.scroll_to_col(0, cx);
|
||||
// })
|
||||
// })),
|
||||
// )
|
||||
// .child(
|
||||
// Button::new("scroll-last-col")
|
||||
// .child("Scroll to Last Column")
|
||||
// .small()
|
||||
// .on_click(cx.listener(|this, _, cx| {
|
||||
// this.table.update(cx, |table, cx| {
|
||||
// table.scroll_to_col(table.delegate().cols_count(cx), cx);
|
||||
// })
|
||||
// })),
|
||||
// ),
|
||||
)
|
||||
.child(
|
||||
h_flex().items_center().gap_2().child(
|
||||
h_flex()
|
||||
|
|
|
|||
|
|
@ -231,6 +231,18 @@ where
|
|||
))
|
||||
}
|
||||
|
||||
/// Scroll to the item at the given index.
|
||||
pub fn scroll_to_item(&mut self, ix: usize, cx: &mut ViewContext<Self>) {
|
||||
self.vertical_scroll_handle
|
||||
.scroll_to_item(ix, ScrollStrategy::Top);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
/// Get scroll handle
|
||||
pub fn scroll_handle(&self) -> &UniformListScrollHandle {
|
||||
&self.vertical_scroll_handle
|
||||
}
|
||||
|
||||
fn scroll_to_selected_item(&mut self, _cx: &mut ViewContext<Self>) {
|
||||
if let Some(ix) = self.selected_index {
|
||||
self.vertical_scroll_handle
|
||||
|
|
|
|||
|
|
@ -367,12 +367,30 @@ where
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
fn scroll_to_row(&mut self, row_ix: usize, cx: &mut ViewContext<Self>) {
|
||||
/// Scroll to the row at the given index.
|
||||
pub fn scroll_to_row(&mut self, row_ix: usize, cx: &mut ViewContext<Self>) {
|
||||
self.vertical_scroll_handle
|
||||
.scroll_to_item(row_ix, ScrollStrategy::Top);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
// Scroll to the column at the given index.
|
||||
// TODO: Fix scroll to selected col, this was not working after fixed col.
|
||||
// pub fn scroll_to_col(&mut self, col_ix: usize, cx: &mut ViewContext<Self>) {
|
||||
// self.horizontal_scroll_handle.scroll_to_item(col_ix);
|
||||
// cx.notify();
|
||||
// }
|
||||
|
||||
/// Get scroll handle
|
||||
pub fn scroll_handle(&self) -> &UniformListScrollHandle {
|
||||
&self.vertical_scroll_handle
|
||||
}
|
||||
|
||||
/// Get horizontal scroll handle
|
||||
pub fn horizontal_scroll_handle(&self) -> &ScrollHandle {
|
||||
&self.horizontal_scroll_handle
|
||||
}
|
||||
|
||||
/// Returns the selected row index.
|
||||
pub fn selected_row(&self) -> Option<usize> {
|
||||
self.selected_row
|
||||
|
|
|
|||
Loading…
Reference in a new issue