example: Add input example. (#1380)
This commit is contained in:
parent
4ccd7d99d0
commit
429a4b2858
5 changed files with 107 additions and 38 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
|
@ -3564,6 +3564,15 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "input"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"gpui",
|
||||||
|
"gpui-component",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["examples/hello_world", "examples/window_title", "crates/macros", "crates/story", "crates/ui", "examples/window_title", "examples/app_assets", "examples/app_assets"]
|
members = ["examples/hello_world", "examples/window_title", "crates/macros", "crates/story", "crates/ui", "examples/window_title", "examples/app_assets", "examples/app_assets", "examples/input"]
|
||||||
|
|
||||||
default-members = ["crates/story"]
|
default-members = ["crates/story"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
use gpui_component::{
|
use gpui_component::{button::*, *};
|
||||||
button::{Button, ButtonVariants},
|
|
||||||
Root, StyledExt,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct HelloWorld;
|
pub struct Example;
|
||||||
|
impl Render for Example {
|
||||||
impl Render for HelloWorld {
|
|
||||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||||
div()
|
div()
|
||||||
.v_flex()
|
.v_flex()
|
||||||
|
|
@ -14,7 +10,6 @@ impl Render for HelloWorld {
|
||||||
.size_full()
|
.size_full()
|
||||||
.items_center()
|
.items_center()
|
||||||
.justify_center()
|
.justify_center()
|
||||||
.text_center()
|
|
||||||
.child("Hello, World!")
|
.child("Hello, World!")
|
||||||
.child(
|
.child(
|
||||||
Button::new("ok")
|
Button::new("ok")
|
||||||
|
|
@ -29,38 +24,13 @@ fn main() {
|
||||||
let app = Application::new();
|
let app = Application::new();
|
||||||
|
|
||||||
app.run(move |cx| {
|
app.run(move |cx| {
|
||||||
// We must initialize gpui_component before using it.
|
// This must be called before using any GPUI Component features.
|
||||||
gpui_component::init(cx);
|
gpui_component::init(cx);
|
||||||
|
|
||||||
cx.activate(true);
|
|
||||||
|
|
||||||
let mut window_size = size(px(640.), px(480.));
|
|
||||||
if let Some(display) = cx.primary_display() {
|
|
||||||
let display_size = display.bounds().size;
|
|
||||||
window_size.width = window_size.width.min(display_size.width * 0.85);
|
|
||||||
window_size.height = window_size.height.min(display_size.height * 0.85);
|
|
||||||
}
|
|
||||||
let window_bounds = Bounds::centered(None, window_size, cx);
|
|
||||||
|
|
||||||
cx.spawn(async move |cx| {
|
cx.spawn(async move |cx| {
|
||||||
let options = WindowOptions {
|
cx.open_window(WindowOptions::default(), |window, cx| {
|
||||||
window_bounds: Some(WindowBounds::Windowed(window_bounds)),
|
let view = cx.new(|_| Example);
|
||||||
titlebar: None,
|
// This first level on the window, should be a Root.
|
||||||
window_min_size: Some(gpui::Size {
|
|
||||||
width: px(640.),
|
|
||||||
height: px(480.),
|
|
||||||
}),
|
|
||||||
kind: WindowKind::Normal,
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
window_background: gpui::WindowBackgroundAppearance::Transparent,
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
window_decorations: Some(gpui::WindowDecorations::Client),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
cx.open_window(options, |window, cx| {
|
|
||||||
let view = cx.new(|_| HelloWorld);
|
|
||||||
// The first level on the window must be Root.
|
|
||||||
cx.new(|cx| Root::new(view.into(), window, cx))
|
cx.new(|cx| Root::new(view.into(), window, cx))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
||||||
12
examples/input/Cargo.toml
Normal file
12
examples/input/Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "input"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow.workspace = true
|
||||||
|
gpui.workspace = true
|
||||||
|
gpui-component = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
78
examples/input/src/main.rs
Normal file
78
examples/input/src/main.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
use gpui::*;
|
||||||
|
use gpui_component::{
|
||||||
|
input::{InputEvent, InputState, TextInput},
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Example {
|
||||||
|
input_state: Entity<InputState>,
|
||||||
|
display_text: SharedString,
|
||||||
|
|
||||||
|
/// We need to keep the subscriptions alive with the Example entity.
|
||||||
|
///
|
||||||
|
/// So if the Example entity is dropped, the subscriptions are also dropped.
|
||||||
|
/// This is important to avoid memory leaks.
|
||||||
|
_subscriptions: Vec<Subscription>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example {
|
||||||
|
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
|
let input_state = cx.new(|cx| InputState::new(window, cx).placeholder("Enter your name"));
|
||||||
|
|
||||||
|
let _subscriptions = vec![cx.subscribe_in(&input_state, window, {
|
||||||
|
let input_state = input_state.clone();
|
||||||
|
move |this, _, ev: &InputEvent, _window, cx| match ev {
|
||||||
|
InputEvent::Change => {
|
||||||
|
let value = input_state.read(cx).value();
|
||||||
|
this.display_text = format!("Hello, {}!", value).into();
|
||||||
|
cx.notify()
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
|
||||||
|
Self {
|
||||||
|
input_state,
|
||||||
|
display_text: SharedString::default(),
|
||||||
|
_subscriptions,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for Example {
|
||||||
|
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
v_flex()
|
||||||
|
.p_5()
|
||||||
|
.gap_2()
|
||||||
|
.size_full()
|
||||||
|
.items_center()
|
||||||
|
.justify_center()
|
||||||
|
.child(TextInput::new(&self.input_state))
|
||||||
|
.child(self.display_text.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let app = Application::new();
|
||||||
|
|
||||||
|
app.run(move |cx| {
|
||||||
|
// This must be called before using any GPUI Component features.
|
||||||
|
gpui_component::init(cx);
|
||||||
|
|
||||||
|
let window_options = WindowOptions {
|
||||||
|
window_bounds: Some(WindowBounds::centered(size(px(800.), px(600.)), cx)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.spawn(async move |cx| {
|
||||||
|
cx.open_window(window_options, |window, cx| {
|
||||||
|
let view = cx.new(|cx| Example::new(window, cx));
|
||||||
|
// This first level on the window, should be a Root.
|
||||||
|
cx.new(|cx| Root::new(view.into(), window, cx))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok::<_, anyhow::Error>(())
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue