button: Add Support for on_hover event (#1341)
This commit is contained in:
parent
ca9d5b77e2
commit
7a8be9a628
3 changed files with 43 additions and 15 deletions
|
|
@ -1,13 +1,13 @@
|
||||||
use gpui::{
|
use gpui::{
|
||||||
prelude::FluentBuilder, px, Action, App, AppContext as _, ClickEvent, Context, Entity,
|
Action, App, AppContext as _, ClickEvent, Context, Entity, Focusable, InteractiveElement,
|
||||||
Focusable, InteractiveElement, IntoElement, ParentElement as _, Render, Styled as _, Window,
|
IntoElement, ParentElement as _, Render, Styled as _, Window, prelude::FluentBuilder, px,
|
||||||
};
|
};
|
||||||
|
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
|
ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, Theme,
|
||||||
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
|
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
|
||||||
checkbox::Checkbox,
|
checkbox::Checkbox,
|
||||||
h_flex, v_flex, ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _,
|
h_flex, v_flex,
|
||||||
Theme,
|
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
|
@ -43,8 +43,12 @@ impl ButtonStory {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_click(ev: &ClickEvent, _window: &mut Window, _cx: &mut App) {
|
fn on_click(ev: &ClickEvent, _: &mut Window, _: &mut App) {
|
||||||
println!("Button clicked! {:?}", ev);
|
println!("Button clicked {:?}", ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_hover(hovered: &bool, _: &mut Window, _: &mut App) {
|
||||||
|
println!("Button hovered {:?}", hovered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +163,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-2")
|
Button::new("button-2")
|
||||||
|
|
@ -168,7 +173,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-4")
|
Button::new("button-4")
|
||||||
|
|
@ -178,7 +184,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-4-warning")
|
Button::new("button-4-warning")
|
||||||
|
|
@ -188,7 +195,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-4-success")
|
Button::new("button-4-success")
|
||||||
|
|
@ -198,7 +206,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-5-info")
|
Button::new("button-5-info")
|
||||||
|
|
@ -208,7 +217,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-5-ghost")
|
Button::new("button-5-ghost")
|
||||||
|
|
@ -218,7 +228,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-5-link")
|
Button::new("button-5-link")
|
||||||
|
|
@ -228,7 +239,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-5-text")
|
Button::new("button-5-text")
|
||||||
|
|
@ -238,7 +250,8 @@ impl Render for ButtonStory {
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.loading(loading)
|
.loading(loading)
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click)
|
||||||
|
.on_hover(Self::on_hover),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ pub struct Button {
|
||||||
Option<(Rc<Box<dyn Action>>, Option<SharedString>)>,
|
Option<(Rc<Box<dyn Action>>, Option<SharedString>)>,
|
||||||
)>,
|
)>,
|
||||||
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
|
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
|
||||||
|
on_hover: Option<Rc<dyn Fn(&bool, &mut Window, &mut App)>>,
|
||||||
pub(crate) stop_propagation: bool,
|
pub(crate) stop_propagation: bool,
|
||||||
loading: bool,
|
loading: bool,
|
||||||
loading_icon: Option<Icon>,
|
loading_icon: Option<Icon>,
|
||||||
|
|
@ -236,6 +237,7 @@ impl Button {
|
||||||
size: Size::Medium,
|
size: Size::Medium,
|
||||||
tooltip: None,
|
tooltip: None,
|
||||||
on_click: None,
|
on_click: None,
|
||||||
|
on_hover: None,
|
||||||
stop_propagation: true,
|
stop_propagation: true,
|
||||||
loading: false,
|
loading: false,
|
||||||
compact: false,
|
compact: false,
|
||||||
|
|
@ -325,6 +327,12 @@ impl Button {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add hover handler, the bool parameter indicates whether the mouse is hovering.
|
||||||
|
pub fn on_hover(mut self, handler: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self {
|
||||||
|
self.on_hover = Some(Rc::new(handler));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stop_propagation(mut self, val: bool) -> Self {
|
pub fn stop_propagation(mut self, val: bool) -> Self {
|
||||||
self.stop_propagation = val;
|
self.stop_propagation = val;
|
||||||
self
|
self
|
||||||
|
|
@ -526,6 +534,11 @@ impl RenderOnce for Button {
|
||||||
(on_click)(event, window, cx);
|
(on_click)(event, window, cx);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.when_some(self.on_hover.filter(|_| clickable), |this, on_hover| {
|
||||||
|
this.on_hover(move |hovered, window, cx| {
|
||||||
|
(on_hover)(hovered, window, cx);
|
||||||
|
})
|
||||||
|
})
|
||||||
.when(self.disabled, |this| {
|
.when(self.disabled, |this| {
|
||||||
let disabled_style = style.disabled(self.outline, cx);
|
let disabled_style = style.disabled(self.outline, cx);
|
||||||
this.bg(disabled_style.bg)
|
this.bg(disabled_style.bg)
|
||||||
|
|
|
||||||
|
|
@ -601,6 +601,7 @@ mod tests {
|
||||||
// Test for not on a char boundary
|
// Test for not on a char boundary
|
||||||
let mut rope = Rope::from("中文");
|
let mut rope = Rope::from("中文");
|
||||||
rope.replace(0..1, "New");
|
rope.replace(0..1, "New");
|
||||||
|
// autocorrect-disable
|
||||||
assert_eq!(rope.to_string(), "New文");
|
assert_eq!(rope.to_string(), "New文");
|
||||||
let mut rope = Rope::from("中文");
|
let mut rope = Rope::from("中文");
|
||||||
rope.replace(0..2, "New");
|
rope.replace(0..2, "New");
|
||||||
|
|
@ -608,6 +609,7 @@ mod tests {
|
||||||
let mut rope = Rope::from("中文");
|
let mut rope = Rope::from("中文");
|
||||||
rope.replace(0..3, "New");
|
rope.replace(0..3, "New");
|
||||||
assert_eq!(rope.to_string(), "New文");
|
assert_eq!(rope.to_string(), "New文");
|
||||||
|
// autocorrect-enable
|
||||||
let mut rope = Rope::from("中文");
|
let mut rope = Rope::from("中文");
|
||||||
rope.replace(1..4, "New");
|
rope.replace(1..4, "New");
|
||||||
assert_eq!(rope.to_string(), "New");
|
assert_eq!(rope.to_string(), "New");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue