Chnage TextField to impl Render

This commit is contained in:
Jason Lee 2024-06-26 13:43:28 +08:00
parent e4fcd24382
commit 4945be5a36
2 changed files with 39 additions and 25 deletions

View file

@ -8,27 +8,31 @@ use crate::text_field::TextField;
use super::story_case; use super::story_case;
pub struct InputStory { pub struct InputStory {
input1: TextField, input1: View<TextField>,
input2: TextField, input2: View<TextField>,
mash_input: TextField, mash_input: View<TextField>,
disabled_input: TextField, disabled_input: View<TextField>,
} }
impl InputStory { impl InputStory {
pub(crate) fn new(cx: &mut WindowContext) -> Self { pub(crate) fn new(cx: &mut WindowContext) -> Self {
let input1 = TextField::new(cx).set_text("Hello 世界", cx); let input1 = cx.new_view(|cx| TextField::new(cx).set_text("Hello 世界", cx));
let mask_input = TextField::new(cx) let mask_input = cx.new_view(|cx| {
.set_masked(true, cx) TextField::new(cx)
.set_text("this-is-password", cx); .set_masked(true, cx)
.set_text("this-is-password", cx)
});
Self { Self {
input1, input1,
input2: TextField::new(cx).set_placeholder("Enter text here...", cx), input2: cx.new_view(|cx| TextField::new(cx).set_placeholder("Enter text here...", cx)),
mash_input: mask_input, mash_input: mask_input,
disabled_input: TextField::new(cx) disabled_input: cx.new_view(|cx| {
.set_text("This is disabled input", cx) TextField::new(cx)
.set_disabled(true, cx), .set_text("This is disabled input", cx)
.set_disabled(true, cx)
}),
} }
} }
@ -39,7 +43,7 @@ impl InputStory {
} }
impl Render for InputStory { impl Render for InputStory {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
story_case("Input", "A text input field.").child( story_case("Input", "A text input field.").child(
div() div()
.flex() .flex()

View file

@ -4,15 +4,16 @@ mod text_view;
use crate::theme::ActiveTheme; use crate::theme::ActiveTheme;
use gpui::{ use gpui::{
div, prelude::FluentBuilder as _, ClipboardItem, EventEmitter, FocusHandle, InteractiveElement, div, prelude::FluentBuilder as _, ClipboardItem, EventEmitter, FocusHandle, FocusableView,
IntoElement, KeyDownEvent, MouseButton, ParentElement, RenderOnce, Styled, View, WindowContext, InteractiveElement, IntoElement, KeyDownEvent, MouseButton, ParentElement, Render, RenderOnce,
Styled, View, WindowContext,
}; };
use std::time::Duration; use std::time::Duration;
use text_view::TextView; use text_view::TextView;
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
#[derive(Clone, IntoElement)] #[derive(Clone)]
pub struct TextField { pub struct TextField {
focus_handle: FocusHandle, focus_handle: FocusHandle,
pub view: View<TextView>, pub view: View<TextView>,
@ -56,8 +57,14 @@ impl TextField {
} }
} }
impl RenderOnce for TextField { impl FocusableView for TextField {
fn render(self, cx: &mut WindowContext) -> impl IntoElement { fn focus_handle(&self, _cx: &gpui::AppContext) -> FocusHandle {
self.focus_handle.clone()
}
}
impl Render for TextField {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl IntoElement {
let focus_handle = self.focus_handle.clone(); let focus_handle = self.focus_handle.clone();
let theme = cx.theme(); let theme = cx.theme();
@ -70,14 +77,17 @@ impl RenderOnce for TextField {
div() div()
.track_focus(&focus_handle) .track_focus(&focus_handle)
.when(!text_view.disabled, |this| { .when(!text_view.disabled, |this| {
this.on_mouse_down(MouseButton::Left, move |_, cx| { this.on_mouse_down(
cx.prevent_default(); MouseButton::Left,
self.focus_handle.focus(cx) cx.listener(move |view, _, cx| {
}) cx.prevent_default();
view.focus_handle.focus(cx)
}),
)
}) })
.when(!disabled, |this| { .when(!disabled, |this| {
this.on_key_down(move |ev, cx| { this.on_key_down(cx.listener(move |this, ev: &KeyDownEvent, cx| {
self.view.update(cx, |text_view, cx| { this.view.update(cx, |text_view, cx| {
let prev = text_view.text.clone(); let prev = text_view.text.clone();
cx.emit(TextEvent::KeyDown(ev.clone())); cx.emit(TextEvent::KeyDown(ev.clone()));
let keystroke = ev.keystroke.key.as_str(); let keystroke = ev.keystroke.key.as_str();
@ -219,7 +229,7 @@ impl RenderOnce for TextField {
} }
cx.notify(); cx.notify();
}); });
}) }))
}) })
.border_color(if focused { theme.ring } else { theme.input }) .border_color(if focused { theme.ring } else { theme.input })
.border_1() .border_1()