list: Fix selected and confirmed list item detail. (#520)

Closes #519 to fix popup_menu attempt to subtract with overflow bug.
This commit is contained in:
Jason Lee 2024-12-27 18:41:27 +08:00 committed by GitHub
parent 0327df323d
commit d7cd0e54c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 40 deletions

View file

@ -275,7 +275,8 @@ where
} }
fn on_action_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) { fn on_action_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
if self.delegate.items_count(cx) == 0 { let items_count = self.delegate.items_count(cx);
if items_count == 0 {
return; return;
} }
@ -283,7 +284,7 @@ where
if selected_index > 0 { if selected_index > 0 {
self.selected_index = Some(selected_index - 1); self.selected_index = Some(selected_index - 1);
} else { } else {
self.selected_index = Some(self.delegate.items_count(cx) - 1); self.selected_index = Some(items_count - 1);
} }
self.delegate.set_selected_index(self.selected_index, cx); self.delegate.set_selected_index(self.selected_index, cx);
@ -292,12 +293,13 @@ where
} }
fn on_action_select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) { fn on_action_select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
if self.delegate.items_count(cx) == 0 { let items_count = self.delegate.items_count(cx);
if items_count == 0 {
return; return;
} }
if let Some(selected_index) = self.selected_index { if let Some(selected_index) = self.selected_index {
if selected_index < self.delegate.items_count(cx) - 1 { if selected_index < items_count - 1 {
self.selected_index = Some(selected_index + 1); self.selected_index = Some(selected_index + 1);
} else { } else {
self.selected_index = Some(0); self.selected_index = Some(0);
@ -312,27 +314,15 @@ where
} }
fn render_list_item(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render_list_item(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> impl IntoElement {
let selected = self.selected_index == Some(ix);
let right_clicked = self.right_clicked_index == Some(ix);
div() div()
.id("list-item") .id("list-item")
.w_full() .w_full()
.relative() .relative()
.children(self.delegate.render_item(ix, cx)) .children(self.delegate.render_item(ix, cx))
.when_some(self.selected_index, |this, selected_index| { .when(selected || right_clicked, |this| {
this.when(ix == selected_index, |this| {
this.child(
div()
.absolute()
.top(px(0.))
.left(px(0.))
.right(px(0.))
.bottom(px(0.))
.bg(cx.theme().list_active)
.border_1()
.border_color(cx.theme().list_active_border),
)
})
})
.when(self.right_clicked_index == Some(ix), |this| {
this.child( this.child(
div() div()
.absolute() .absolute()
@ -340,6 +330,7 @@ where
.left(px(0.)) .left(px(0.))
.right(px(0.)) .right(px(0.))
.bottom(px(0.)) .bottom(px(0.))
.when(selected, |this| this.bg(cx.theme().list_active))
.border_1() .border_1()
.border_color(cx.theme().list_active_border), .border_color(cx.theme().list_active_border),
) )

View file

@ -116,35 +116,28 @@ impl ParentElement for ListItem {
impl RenderOnce for ListItem { impl RenderOnce for ListItem {
fn render(self, cx: &mut WindowContext) -> impl IntoElement { fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let is_active = self.selected || self.confirmed; let is_active = self.confirmed || self.selected;
self.base self.base
.text_color(cx.theme().foreground) .text_color(cx.theme().foreground)
.relative() .relative()
.items_center() .items_center()
.justify_between() .justify_between()
.when_some(self.on_click, |this, on_click| { .when(is_active, |this| this.bg(cx.theme().list_active))
if !self.disabled { .when(!self.disabled, |this| {
this.when_some(self.on_click, |this, on_click| {
this.cursor_pointer() this.cursor_pointer()
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(MouseButton::Left, move |_, cx| {
cx.stop_propagation(); cx.stop_propagation();
}) })
.on_click(on_click) .on_click(on_click)
} else { })
this .when_some(self.on_mouse_enter, |this, on_mouse_enter| {
}
})
.when(is_active, |this| this.bg(cx.theme().list_active))
.when(!is_active && !self.disabled, |this| {
this.hover(|this| this.bg(cx.theme().list_hover))
})
// Mouse enter
.when_some(self.on_mouse_enter, |this, on_mouse_enter| {
if !self.disabled {
this.on_mouse_move(move |ev, cx| (on_mouse_enter)(ev, cx)) this.on_mouse_move(move |ev, cx| (on_mouse_enter)(ev, cx))
} else { })
this .when(!is_active, |this| {
} this.hover(|this| this.bg(cx.theme().list_hover))
})
}) })
.child( .child(
h_flex() h_flex()

View file

@ -389,9 +389,10 @@ impl PopupMenu {
fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) { fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
let count = self.clickable_menu_items().count(); let count = self.clickable_menu_items().count();
if count > 0 { if count > 0 {
let last_ix = count.saturating_sub(1);
let ix = self let ix = self
.selected_index .selected_index
.map(|index| if index == count - 1 { 0 } else { index + 1 }) .map(|index| if index == last_ix { 0 } else { index + 1 })
.unwrap_or(0); .unwrap_or(0);
self.selected_index = Some(ix); self.selected_index = Some(ix);
@ -402,10 +403,18 @@ impl PopupMenu {
fn select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) { fn select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
let count = self.clickable_menu_items().count(); let count = self.clickable_menu_items().count();
if count > 0 { if count > 0 {
let last_ix = count.saturating_sub(1);
let ix = self let ix = self
.selected_index .selected_index
.map(|index| if index == count - 1 { 0 } else { index - 1 }) .map(|index| {
.unwrap_or(count - 1); if index == last_ix {
0
} else {
index.saturating_sub(1)
}
})
.unwrap_or(last_ix);
self.selected_index = Some(ix); self.selected_index = Some(ix);
cx.notify(); cx.notify();
} }