Add button port example
This commit is contained in:
parent
88024ca7c9
commit
f3eb1d4abf
1 changed files with 26 additions and 40 deletions
|
@ -1,25 +1,27 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use gpui::{DefiniteLength, Hsla, MouseButton, StatefulInteractiveComponent, WindowContext};
|
use gpui::{
|
||||||
|
CallbackHandle, DefiniteLength, Hsla, MouseButton, StatefulInteractiveComponent, WindowContext,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{h_stack, Icon, IconButton, IconElement, Label, LineHeightStyle, TextColor};
|
use crate::{h_stack, Icon, IconButton, IconElement, Label, LineHeightStyle, TextColor};
|
||||||
|
|
||||||
/// Provides the flexibility to use either a standard
|
/// Provides the flexibility to use either a standard
|
||||||
/// button or an icon button in a given context.
|
/// button or an icon button in a given context.
|
||||||
pub enum ButtonOrIconButton<V: 'static> {
|
pub enum ButtonOrIconButton {
|
||||||
Button(Button<V>),
|
Button(Button),
|
||||||
IconButton(IconButton<V>),
|
IconButton(IconButton),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> From<Button<V>> for ButtonOrIconButton<V> {
|
impl From<Button> for ButtonOrIconButton {
|
||||||
fn from(value: Button<V>) -> Self {
|
fn from(value: Button) -> Self {
|
||||||
Self::Button(value)
|
Self::Button(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> From<IconButton<V>> for ButtonOrIconButton<V> {
|
impl From<IconButton> for ButtonOrIconButton {
|
||||||
fn from(value: IconButton<V>) -> Self {
|
fn from(value: IconButton) -> Self {
|
||||||
Self::IconButton(value)
|
Self::IconButton(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,25 +63,10 @@ impl ButtonVariant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ClickHandler<V> = Arc<dyn Fn(&mut V, &mut ViewContext<V>)>;
|
// #[derive(Component)] <- todo
|
||||||
|
pub struct Button {
|
||||||
struct ButtonHandlers<V: 'static> {
|
|
||||||
click: Option<ClickHandler<V>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<S> Send for ButtonHandlers<S> {}
|
|
||||||
unsafe impl<S> Sync for ButtonHandlers<S> {}
|
|
||||||
|
|
||||||
impl<V: 'static> Default for ButtonHandlers<V> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { click: None }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Button<V: 'static> {
|
|
||||||
disabled: bool,
|
disabled: bool,
|
||||||
handlers: ButtonHandlers<V>,
|
click_handler: Option<CallbackHandle<()>>,
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
icon_position: Option<IconPosition>,
|
icon_position: Option<IconPosition>,
|
||||||
label: SharedString,
|
label: SharedString,
|
||||||
|
@ -88,11 +75,11 @@ pub struct Button<V: 'static> {
|
||||||
color: Option<TextColor>,
|
color: Option<TextColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> Button<V> {
|
impl Button {
|
||||||
pub fn new(label: impl Into<SharedString>) -> Self {
|
pub fn new(label: impl Into<SharedString>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
handlers: ButtonHandlers::default(),
|
click_handler: None,
|
||||||
icon: None,
|
icon: None,
|
||||||
icon_position: None,
|
icon_position: None,
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
|
@ -129,7 +116,7 @@ impl<V: 'static> Button<V> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_click(mut self, handler: ClickHandler<V>) -> Self {
|
pub fn on_click(mut self, handler: CallbackHandle<()>) -> Self {
|
||||||
self.handlers.click = Some(handler);
|
self.handlers.click = Some(handler);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -164,7 +151,7 @@ impl<V: 'static> Button<V> {
|
||||||
self.icon.map(|i| IconElement::new(i).color(icon_color))
|
self.icon.map(|i| IconElement::new(i).color(icon_color))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
pub fn render(self, cx: &mut WindowContext) -> impl Component {
|
||||||
let (icon_color, label_color) = match (self.disabled, self.color) {
|
let (icon_color, label_color) = match (self.disabled, self.color) {
|
||||||
(true, _) => (TextColor::Disabled, TextColor::Disabled),
|
(true, _) => (TextColor::Disabled, TextColor::Disabled),
|
||||||
(_, None) => (TextColor::Default, TextColor::Default),
|
(_, None) => (TextColor::Default, TextColor::Default),
|
||||||
|
@ -212,21 +199,20 @@ impl<V: 'static> Button<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
pub struct ButtonGroup {
|
||||||
pub struct ButtonGroup<V: 'static> {
|
buttons: Vec<Button>,
|
||||||
buttons: Vec<Button<V>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> ButtonGroup<V> {
|
impl ButtonGroup {
|
||||||
pub fn new(buttons: Vec<Button<V>>) -> Self {
|
pub fn new(buttons: Vec<Button>) -> Self {
|
||||||
Self { buttons }
|
Self { buttons }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
fn render(self, cx: &mut WindowContext) -> impl Component {
|
||||||
let mut el = h_stack().text_ui();
|
let mut el = h_stack().text_ui();
|
||||||
|
|
||||||
for button in self.buttons {
|
for button in self.buttons {
|
||||||
el = el.child(button.render(_view, cx));
|
el = el.child(button.render(cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
el
|
el
|
||||||
|
@ -246,13 +232,13 @@ mod stories {
|
||||||
pub struct ButtonStory;
|
pub struct ButtonStory;
|
||||||
|
|
||||||
impl Render for ButtonStory {
|
impl Render for ButtonStory {
|
||||||
type Element = Div<Self>;
|
type Element = Div;
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
let states = InteractionState::iter();
|
let states = InteractionState::iter();
|
||||||
|
|
||||||
Story::container(cx)
|
Story::container(cx)
|
||||||
.child(Story::title_for::<_, Button<Self>>(cx))
|
.child(Story::title_for::<_, Button>(cx))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
|
@ -395,7 +381,7 @@ mod stories {
|
||||||
.child(
|
.child(
|
||||||
Button::new("Label")
|
Button::new("Label")
|
||||||
.variant(ButtonVariant::Ghost)
|
.variant(ButtonVariant::Ghost)
|
||||||
.on_click(Arc::new(|_view, _cx| println!("Button clicked."))),
|
.on_click(cx.callback(|_view, _, cx| println!("Button clicked."))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue