Fix list next to select first item, cancel to deselect item. (#110)
- Add confirmed to ListItem to show check style.
This commit is contained in:
parent
e7a0d13b69
commit
f3fdfae002
5 changed files with 49 additions and 27 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
|
@ -925,7 +925,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "collections"
|
name = "collections"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
|
|
@ -1238,7 +1238,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_refineable"
|
name = "derive_refineable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2178,7 +2178,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gpui"
|
name = "gpui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"as-raw-xcb-connection",
|
"as-raw-xcb-connection",
|
||||||
|
|
@ -2278,7 +2278,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gpui_macros"
|
name = "gpui_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2482,7 +2482,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http_client"
|
name = "http_client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
|
@ -2997,7 +2997,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "media"
|
name = "media"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bindgen",
|
"bindgen",
|
||||||
|
|
@ -4107,7 +4107,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "refineable"
|
name = "refineable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derive_refineable",
|
"derive_refineable",
|
||||||
]
|
]
|
||||||
|
|
@ -4382,7 +4382,7 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semantic_version"
|
name = "semantic_version"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -4791,7 +4791,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sum_tree"
|
name = "sum_tree"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"log",
|
"log",
|
||||||
|
|
@ -5427,7 +5427,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "util"
|
name = "util"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#d18b49a95309fdc8b46b64cb57dae96d4be0e49b"
|
source = "git+https://github.com/huacnlee/zed.git?branch=export-platform-window#371a680215f5a1e91fdfd6a00afbbf362f71eade"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-fs 1.6.0",
|
"async-fs 1.6.0",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ use ui::{
|
||||||
|
|
||||||
pub struct ListItemDeletegate {
|
pub struct ListItemDeletegate {
|
||||||
story: WeakView<PickerStory>,
|
story: WeakView<PickerStory>,
|
||||||
selected_index: usize,
|
confirmed_index: Option<usize>,
|
||||||
|
selected_index: Option<usize>,
|
||||||
items: Vec<Arc<String>>,
|
items: Vec<Arc<String>>,
|
||||||
matches: Vec<Arc<String>>,
|
matches: Vec<Arc<String>>,
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +31,7 @@ impl ListDelegate for ListItemDeletegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirmed_index(&self) -> Option<usize> {
|
fn confirmed_index(&self) -> Option<usize> {
|
||||||
Some(self.selected_index)
|
self.confirmed_index
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_search(&mut self, query: &str, cx: &mut ViewContext<List<Self>>) -> Task<()> {
|
fn perform_search(&mut self, query: &str, cx: &mut ViewContext<List<Self>>) -> Task<()> {
|
||||||
|
|
@ -55,10 +56,13 @@ impl ListDelegate for ListItemDeletegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_item(&self, ix: usize, _: &mut ViewContext<List<Self>>) -> Option<Self::Item> {
|
fn render_item(&self, ix: usize, _: &mut ViewContext<List<Self>>) -> Option<Self::Item> {
|
||||||
let selected = ix == self.selected_index;
|
let confirmed = Some(ix) == self.confirmed_index;
|
||||||
|
let selected = Some(ix) == self.selected_index;
|
||||||
|
|
||||||
if let Some(item) = self.matches.get(ix) {
|
if let Some(item) = self.matches.get(ix) {
|
||||||
let list_item = ListItem::new(("item", ix))
|
let list_item = ListItem::new(("item", ix))
|
||||||
.check_icon(ui::IconName::Check)
|
.check_icon(ui::IconName::Check)
|
||||||
|
.confirmed(confirmed)
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.py_1()
|
.py_1()
|
||||||
.px_3()
|
.px_3()
|
||||||
|
|
@ -115,7 +119,7 @@ impl ListDelegate for ListItemDeletegate {
|
||||||
if let Some(story) = self.story.upgrade() {
|
if let Some(story) = self.story.upgrade() {
|
||||||
cx.update_view(&story, |story, cx| {
|
cx.update_view(&story, |story, cx| {
|
||||||
if let Some(ix) = ix {
|
if let Some(ix) = ix {
|
||||||
self.selected_index = ix;
|
self.confirmed_index = Some(ix);
|
||||||
if let Some(item) = self.matches.get(ix) {
|
if let Some(item) = self.matches.get(ix) {
|
||||||
story.selected_value = Some(item.clone());
|
story.selected_value = Some(item.clone());
|
||||||
}
|
}
|
||||||
|
|
@ -127,8 +131,9 @@ impl ListDelegate for ListItemDeletegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_selected_index(&mut self, ix: Option<usize>, cx: &mut ViewContext<List<Self>>) {
|
fn set_selected_index(&mut self, ix: Option<usize>, cx: &mut ViewContext<List<Self>>) {
|
||||||
if let Some(ix) = ix {
|
self.selected_index = ix;
|
||||||
self.selected_index = ix;
|
|
||||||
|
if let Some(_) = ix {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +209,8 @@ impl PickerStory {
|
||||||
let story = cx.view().downgrade();
|
let story = cx.view().downgrade();
|
||||||
let delegate = ListItemDeletegate {
|
let delegate = ListItemDeletegate {
|
||||||
story,
|
story,
|
||||||
selected_index: 0,
|
selected_index: None,
|
||||||
|
confirmed_index: None,
|
||||||
items: items.clone(),
|
items: items.clone(),
|
||||||
matches: items.clone(),
|
matches: items.clone(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
fn action_cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
||||||
|
self.set_selected_index(None, cx);
|
||||||
self.delegate.cancel(cx);
|
self.delegate.cancel(cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
@ -259,9 +260,12 @@ where
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let selected_index = self.selected_index.unwrap_or(0);
|
if let Some(selected_index) = self.selected_index {
|
||||||
if selected_index < self.delegate.items_count() - 1 {
|
if selected_index < self.delegate.items_count() - 1 {
|
||||||
self.selected_index = Some(selected_index + 1);
|
self.selected_index = Some(selected_index + 1);
|
||||||
|
} else {
|
||||||
|
self.selected_index = Some(0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.selected_index = Some(0);
|
self.selected_index = Some(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ pub struct ListItem {
|
||||||
base: Stateful<Div>,
|
base: Stateful<Div>,
|
||||||
disabled: bool,
|
disabled: bool,
|
||||||
selected: bool,
|
selected: bool,
|
||||||
|
confirmed: bool,
|
||||||
check_icon: Option<Icon>,
|
check_icon: Option<Icon>,
|
||||||
on_click: Option<Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
|
on_click: Option<Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
|
||||||
on_secondary_mouse_down: Option<Box<dyn Fn(&MouseDownEvent, &mut WindowContext) + 'static>>,
|
on_secondary_mouse_down: Option<Box<dyn Fn(&MouseDownEvent, &mut WindowContext) + 'static>>,
|
||||||
|
|
@ -25,6 +26,7 @@ impl ListItem {
|
||||||
base: h_flex().id(id.into()).gap_x_1().py_1().px_2().text_base(),
|
base: h_flex().id(id.into()).gap_x_1().py_1().px_2().text_base(),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
selected: false,
|
selected: false,
|
||||||
|
confirmed: false,
|
||||||
on_click: None,
|
on_click: None,
|
||||||
on_secondary_mouse_down: None,
|
on_secondary_mouse_down: None,
|
||||||
check_icon: None,
|
check_icon: None,
|
||||||
|
|
@ -33,16 +35,24 @@ impl ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set to show check icon, default is None.
|
||||||
pub fn check_icon(mut self, icon: IconName) -> Self {
|
pub fn check_icon(mut self, icon: IconName) -> Self {
|
||||||
self.check_icon = Some(Icon::new(icon));
|
self.check_icon = Some(Icon::new(icon));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set ListItem as the selected item style.
|
||||||
pub fn selected(mut self, selected: bool) -> Self {
|
pub fn selected(mut self, selected: bool) -> Self {
|
||||||
self.selected = selected;
|
self.selected = selected;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set ListItem as the confirmed item style, it will show a check icon.
|
||||||
|
pub fn confirmed(mut self, confirmed: bool) -> Self {
|
||||||
|
self.confirmed = confirmed;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn disabled(mut self, disabled: bool) -> Self {
|
pub fn disabled(mut self, disabled: bool) -> Self {
|
||||||
self.disabled = disabled;
|
self.disabled = disabled;
|
||||||
self
|
self
|
||||||
|
|
@ -100,6 +110,8 @@ 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;
|
||||||
|
|
||||||
self.base
|
self.base
|
||||||
.text_color(cx.theme().foreground)
|
.text_color(cx.theme().foreground)
|
||||||
.relative()
|
.relative()
|
||||||
|
|
@ -112,8 +124,8 @@ impl RenderOnce for ListItem {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.when(self.selected, |this| this.bg(cx.theme().list_active))
|
.when(is_active, |this| this.bg(cx.theme().list_active))
|
||||||
.when(!self.selected && !self.disabled, |this| {
|
.when(!is_active && !self.disabled, |this| {
|
||||||
this.hover(|this| this.bg(cx.theme().list_hover))
|
this.hover(|this| this.bg(cx.theme().list_hover))
|
||||||
})
|
})
|
||||||
// Right click
|
// Right click
|
||||||
|
|
@ -133,7 +145,7 @@ impl RenderOnce for ListItem {
|
||||||
.child(div().w_full().overflow_hidden().children(self.children))
|
.child(div().w_full().overflow_hidden().children(self.children))
|
||||||
.when_some(self.check_icon, |this, icon| {
|
.when_some(self.check_icon, |this, icon| {
|
||||||
this.child(div().w_5().items_center().justify_center().when(
|
this.child(div().w_5().items_center().justify_center().when(
|
||||||
self.selected,
|
self.confirmed,
|
||||||
|this| {
|
|this| {
|
||||||
this.child(
|
this.child(
|
||||||
icon.size(Size::Small)
|
icon.size(Size::Small)
|
||||||
|
|
|
||||||
|
|
@ -84,8 +84,8 @@ impl Asset for Image {
|
||||||
return Err(usvg::Error::InvalidSize.into());
|
return Err(usvg::Error::InvalidSize.into());
|
||||||
}
|
}
|
||||||
let size = Size {
|
let size = Size {
|
||||||
width: size.width * scale,
|
width: (size.width * scale).ceil(),
|
||||||
height: size.height * scale,
|
height: (size.height * scale).ceil(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let bytes = match source.source {
|
let bytes = match source.source {
|
||||||
|
|
@ -258,8 +258,8 @@ impl Element for SvgImg {
|
||||||
};
|
};
|
||||||
|
|
||||||
let img_bounds = Bounds {
|
let img_bounds = Bounds {
|
||||||
size: new_size,
|
origin: new_origin.map(|origin| origin.floor()),
|
||||||
origin: new_origin,
|
size: new_size.map(|size| size.ceil()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match cx.paint_image(img_bounds, px(0.).into(), data, 0, false) {
|
match cx.paint_image(img_bounds, px(0.).into(), data, 0, false) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue