input: Add Esc to clean. (#803)
This commit is contained in:
parent
7719d8b6fc
commit
f7be6a245a
3 changed files with 48 additions and 17 deletions
|
|
@ -1,9 +1,5 @@
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
use gpui_component::{
|
|
||||||
alert::Alert,
|
|
||||||
button::{Button, ButtonGroup},
|
|
||||||
v_flex, IconName, Selectable as _, Sizable as _, Size,
|
|
||||||
};
|
|
||||||
use story::{AlertStory, Assets};
|
use story::{AlertStory, Assets};
|
||||||
|
|
||||||
pub struct Example {
|
pub struct Example {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use gpui_component::{
|
||||||
button::{Button, ButtonVariant, ButtonVariants as _},
|
button::{Button, ButtonVariant, ButtonVariants as _},
|
||||||
h_flex,
|
h_flex,
|
||||||
input::{InputEvent, TextInput},
|
input::{InputEvent, TextInput},
|
||||||
v_flex, FocusableCycle, Icon, IconName, Sizable, StyledExt,
|
v_flex, FocusableCycle, Icon, IconName, Sizable,
|
||||||
};
|
};
|
||||||
|
|
||||||
actions!(input_story, [Tab, TabPrev]);
|
actions!(input_story, [Tab, TabPrev]);
|
||||||
|
|
@ -26,6 +26,7 @@ pub fn init(cx: &mut App) {
|
||||||
pub struct InputStory {
|
pub struct InputStory {
|
||||||
input1: Entity<TextInput>,
|
input1: Entity<TextInput>,
|
||||||
input2: Entity<TextInput>,
|
input2: Entity<TextInput>,
|
||||||
|
input_esc: Entity<TextInput>,
|
||||||
mask_input: Entity<TextInput>,
|
mask_input: Entity<TextInput>,
|
||||||
disabled_input: Entity<TextInput>,
|
disabled_input: Entity<TextInput>,
|
||||||
prefix_input1: Entity<TextInput>,
|
prefix_input1: Entity<TextInput>,
|
||||||
|
|
@ -68,6 +69,12 @@ impl InputStory {
|
||||||
});
|
});
|
||||||
|
|
||||||
let input2 = cx.new(|cx| TextInput::new(window, cx).placeholder("Enter text here..."));
|
let input2 = cx.new(|cx| TextInput::new(window, cx).placeholder("Enter text here..."));
|
||||||
|
let input_esc = cx.new(|cx| {
|
||||||
|
TextInput::new(window, cx)
|
||||||
|
.placeholder("Enter text and clear it by pressing ESC")
|
||||||
|
.cleanable()
|
||||||
|
.clean_on_escape()
|
||||||
|
});
|
||||||
|
|
||||||
let mask_input = cx.new(|cx| {
|
let mask_input = cx.new(|cx| {
|
||||||
let mut input = TextInput::new(window, cx)
|
let mut input = TextInput::new(window, cx)
|
||||||
|
|
@ -119,6 +126,7 @@ impl InputStory {
|
||||||
Self {
|
Self {
|
||||||
input1,
|
input1,
|
||||||
input2,
|
input2,
|
||||||
|
input_esc,
|
||||||
mask_input,
|
mask_input,
|
||||||
disabled_input: cx.new(|cx| {
|
disabled_input: cx.new(|cx| {
|
||||||
let mut input = TextInput::new(window, cx);
|
let mut input = TextInput::new(window, cx);
|
||||||
|
|
@ -173,6 +181,7 @@ impl FocusableCycle for InputStory {
|
||||||
[
|
[
|
||||||
self.input1.focus_handle(cx),
|
self.input1.focus_handle(cx),
|
||||||
self.input2.focus_handle(cx),
|
self.input2.focus_handle(cx),
|
||||||
|
self.input_esc.focus_handle(cx),
|
||||||
self.disabled_input.focus_handle(cx),
|
self.disabled_input.focus_handle(cx),
|
||||||
self.mask_input.focus_handle(cx),
|
self.mask_input.focus_handle(cx),
|
||||||
self.prefix_input1.focus_handle(cx),
|
self.prefix_input1.focus_handle(cx),
|
||||||
|
|
@ -202,21 +211,18 @@ impl Render for InputStory {
|
||||||
.gap_3()
|
.gap_3()
|
||||||
.child(
|
.child(
|
||||||
section("Normal Input")
|
section("Normal Input")
|
||||||
.v_flex()
|
|
||||||
.max_w_md()
|
.max_w_md()
|
||||||
.child(self.input1.clone())
|
.child(self.input1.clone())
|
||||||
.child(self.input2.clone()),
|
.child(self.input2.clone()),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
section("Input State")
|
section("Input State")
|
||||||
.v_flex()
|
|
||||||
.max_w_md()
|
.max_w_md()
|
||||||
.child(self.disabled_input.clone())
|
.child(self.disabled_input.clone())
|
||||||
.child(self.mask_input.clone()),
|
.child(self.mask_input.clone()),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
section("Prefix and Suffix")
|
section("Prefix and Suffix")
|
||||||
.v_flex()
|
|
||||||
.max_w_md()
|
.max_w_md()
|
||||||
.child(self.prefix_input1.clone())
|
.child(self.prefix_input1.clone())
|
||||||
.child(self.both_input1.clone())
|
.child(self.both_input1.clone())
|
||||||
|
|
@ -224,11 +230,15 @@ impl Render for InputStory {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
section("Input Size")
|
section("Input Size")
|
||||||
.v_flex()
|
|
||||||
.max_w_md()
|
.max_w_md()
|
||||||
.child(self.large_input.clone())
|
.child(self.large_input.clone())
|
||||||
.child(self.small_input.clone()),
|
.child(self.small_input.clone()),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
section("Cleanable and ESC to clean")
|
||||||
|
.max_w_md()
|
||||||
|
.child(self.input_esc.clone()),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ use unicode_segmentation::*;
|
||||||
use gpui::prelude::FluentBuilder as _;
|
use gpui::prelude::FluentBuilder as _;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, impl_internal_actions, point, px, relative, AnyElement, App, AppContext, Bounds,
|
actions, div, impl_internal_actions, point, px, relative, AnyElement, App, AppContext, Bounds,
|
||||||
ClickEvent, ClipboardItem, Context, DefiniteLength, Entity, EntityInputHandler, EventEmitter,
|
ClipboardItem, Context, DefiniteLength, Entity, EntityInputHandler, EventEmitter, FocusHandle,
|
||||||
FocusHandle, Focusable, InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent,
|
Focusable, InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent, MouseButton,
|
||||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point,
|
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Rems, Render,
|
||||||
Rems, Render, ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, Subscription,
|
ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, Subscription, UTF16Selection,
|
||||||
UTF16Selection, Window, WrappedLine,
|
Window, WrappedLine,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
@ -85,6 +85,7 @@ actions!(
|
||||||
MoveToPreviousWord,
|
MoveToPreviousWord,
|
||||||
MoveToNextWord,
|
MoveToNextWord,
|
||||||
TextChanged,
|
TextChanged,
|
||||||
|
Escape
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -116,6 +117,7 @@ pub fn init(cx: &mut App) {
|
||||||
KeyBinding::new("ctrl-delete", DeleteToNextWordEnd, Some(CONTEXT)),
|
KeyBinding::new("ctrl-delete", DeleteToNextWordEnd, Some(CONTEXT)),
|
||||||
KeyBinding::new("enter", Enter { secondary: false }, Some(CONTEXT)),
|
KeyBinding::new("enter", Enter { secondary: false }, Some(CONTEXT)),
|
||||||
KeyBinding::new("secondary-enter", Enter { secondary: true }, Some(CONTEXT)),
|
KeyBinding::new("secondary-enter", Enter { secondary: true }, Some(CONTEXT)),
|
||||||
|
KeyBinding::new("escape", Escape, Some(CONTEXT)),
|
||||||
KeyBinding::new("up", Up, Some(CONTEXT)),
|
KeyBinding::new("up", Up, Some(CONTEXT)),
|
||||||
KeyBinding::new("down", Down, Some(CONTEXT)),
|
KeyBinding::new("down", Down, Some(CONTEXT)),
|
||||||
KeyBinding::new("left", Left, Some(CONTEXT)),
|
KeyBinding::new("left", Left, Some(CONTEXT)),
|
||||||
|
|
@ -233,6 +235,7 @@ pub struct TextInput {
|
||||||
pub(super) mask_toggle: bool,
|
pub(super) mask_toggle: bool,
|
||||||
pub(super) appearance: bool,
|
pub(super) appearance: bool,
|
||||||
pub(super) cleanable: bool,
|
pub(super) cleanable: bool,
|
||||||
|
pub(super) clean_on_escape: bool,
|
||||||
pub(super) size: Size,
|
pub(super) size: Size,
|
||||||
pub(super) rows: usize,
|
pub(super) rows: usize,
|
||||||
pub(super) min_rows: usize,
|
pub(super) min_rows: usize,
|
||||||
|
|
@ -295,6 +298,7 @@ impl TextInput {
|
||||||
mask_toggle: false,
|
mask_toggle: false,
|
||||||
appearance: true,
|
appearance: true,
|
||||||
cleanable: false,
|
cleanable: false,
|
||||||
|
clean_on_escape: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
prefix: None,
|
prefix: None,
|
||||||
suffix: None,
|
suffix: None,
|
||||||
|
|
@ -662,6 +666,12 @@ impl TextInput {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set true to clear the input by pressing Escape key.
|
||||||
|
pub fn clean_on_escape(mut self) -> Self {
|
||||||
|
self.clean_on_escape = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set true to not use gap between input and prefix, suffix, and clear button.
|
/// Set true to not use gap between input and prefix, suffix, and clear button.
|
||||||
///
|
///
|
||||||
/// Default: false
|
/// Default: false
|
||||||
|
|
@ -1059,10 +1069,20 @@ impl TextInput {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
|
fn clean(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.replace_text("", window, cx);
|
self.replace_text("", window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn escape(&mut self, _: &Escape, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
if self.selected_range.len() > 0 {
|
||||||
|
return self.unselect(window, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.clean_on_escape {
|
||||||
|
self.clean(window, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn on_mouse_down(
|
fn on_mouse_down(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: &MouseDownEvent,
|
event: &MouseDownEvent,
|
||||||
|
|
@ -1788,6 +1808,7 @@ impl Render for TextInput {
|
||||||
.on_action(cx.listener(Self::delete_previous_word))
|
.on_action(cx.listener(Self::delete_previous_word))
|
||||||
.on_action(cx.listener(Self::delete_next_word))
|
.on_action(cx.listener(Self::delete_next_word))
|
||||||
.on_action(cx.listener(Self::enter))
|
.on_action(cx.listener(Self::enter))
|
||||||
|
.on_action(cx.listener(Self::escape))
|
||||||
})
|
})
|
||||||
.on_action(cx.listener(Self::left))
|
.on_action(cx.listener(Self::left))
|
||||||
.on_action(cx.listener(Self::right))
|
.on_action(cx.listener(Self::right))
|
||||||
|
|
@ -1868,7 +1889,11 @@ impl Render for TextInput {
|
||||||
})
|
})
|
||||||
.children(self.render_toggle_mask_button(window, cx))
|
.children(self.render_toggle_mask_button(window, cx))
|
||||||
.when(show_clear_button, |this| {
|
.when(show_clear_button, |this| {
|
||||||
this.child(clear_button(cx).on_click(cx.listener(Self::clean)))
|
this.child(
|
||||||
|
clear_button(cx).on_click(cx.listener(|view, _, window, cx| {
|
||||||
|
view.clean(window, cx);
|
||||||
|
})),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.children(suffix),
|
.children(suffix),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue