mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-30 06:05:19 +00:00
Rework Toggle
into Toggleable
and ToggleState
This commit is contained in:
parent
6f5cc0af94
commit
e77846d2dc
10 changed files with 95 additions and 93 deletions
|
@ -178,7 +178,7 @@ use serde_derive::{Deserialize, Serialize};
|
|||
use settings::{Settings, SettingsStore};
|
||||
use ui::{
|
||||
h_stack, v_stack, Avatar, Button, Color, Icon, IconButton, IconElement, Label, List,
|
||||
ListHeader, ListItem, Toggle, Tooltip,
|
||||
ListHeader, ListItem, Toggleable, Tooltip,
|
||||
};
|
||||
use util::{maybe, ResultExt, TryFutureExt};
|
||||
use workspace::{
|
||||
|
@ -2534,9 +2534,10 @@ impl CollabPanel {
|
|||
.when_some(button, |el, button| el.right_button(button))
|
||||
.selected(is_selected)
|
||||
.when(can_collapse, |el| {
|
||||
el.toggle(ui::Toggle::Toggled(is_collapsed)).on_toggle(
|
||||
cx.listener(move |this, _, cx| this.toggle_section_expanded(section, cx)),
|
||||
)
|
||||
el.toggle(Toggleable::Toggleable(is_collapsed.into()))
|
||||
.on_toggle(
|
||||
cx.listener(move |this, _, cx| this.toggle_section_expanded(section, cx)),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2853,9 +2854,9 @@ impl CollabPanel {
|
|||
),
|
||||
)
|
||||
.toggle(if has_children {
|
||||
Toggle::Toggled(disclosed)
|
||||
Toggleable::Toggleable(disclosed.into())
|
||||
} else {
|
||||
Toggle::NotToggleable
|
||||
Toggleable::NotToggleable
|
||||
})
|
||||
.on_toggle(
|
||||
cx.listener(move |this, _, cx| this.toggle_channel_collapsed(channel_id, cx)),
|
||||
|
|
|
@ -13,7 +13,6 @@ mod list;
|
|||
mod popover;
|
||||
mod slot;
|
||||
mod stack;
|
||||
mod toggle;
|
||||
mod tooltip;
|
||||
|
||||
#[cfg(feature = "stories")]
|
||||
|
@ -34,7 +33,6 @@ pub use list::*;
|
|||
pub use popover::*;
|
||||
pub use slot::*;
|
||||
pub use stack::*;
|
||||
pub use toggle::*;
|
||||
pub use tooltip::*;
|
||||
|
||||
#[cfg(feature = "stories")]
|
||||
|
|
|
@ -1,24 +1,31 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use gpui::{ClickEvent, Div};
|
||||
use gpui::ClickEvent;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{Color, Icon, IconButton, IconSize, Toggle};
|
||||
use crate::{Color, Icon, IconButton, IconSize, ToggleState, Toggleable};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Disclosure {
|
||||
toggle: Toggle,
|
||||
state: ToggleState,
|
||||
on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
|
||||
}
|
||||
|
||||
impl Disclosure {
|
||||
pub fn new(toggle: Toggle) -> Self {
|
||||
pub fn new(state: ToggleState) -> Self {
|
||||
Self {
|
||||
toggle,
|
||||
state,
|
||||
on_toggle: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_toggleable(toggleable: Toggleable) -> Option<Self> {
|
||||
match toggleable {
|
||||
Toggleable::Toggleable(state) => Some(Self::new(state)),
|
||||
Toggleable::NotToggleable => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_toggle(
|
||||
mut self,
|
||||
handler: impl Into<Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>>,
|
||||
|
@ -29,27 +36,20 @@ impl Disclosure {
|
|||
}
|
||||
|
||||
impl RenderOnce for Disclosure {
|
||||
type Rendered = Div;
|
||||
type Rendered = IconButton;
|
||||
|
||||
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
|
||||
if !self.toggle.is_toggleable() {
|
||||
return div();
|
||||
}
|
||||
|
||||
div().child(
|
||||
IconButton::new(
|
||||
"toggle",
|
||||
if self.toggle.is_toggled() {
|
||||
Icon::ChevronDown
|
||||
} else {
|
||||
Icon::ChevronRight
|
||||
},
|
||||
)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::Small)
|
||||
.when_some(self.on_toggle, move |this, on_toggle| {
|
||||
this.on_click(move |event, cx| on_toggle(event, cx))
|
||||
}),
|
||||
IconButton::new(
|
||||
"toggle",
|
||||
match self.state {
|
||||
ToggleState::Toggled => Icon::ChevronDown,
|
||||
ToggleState::NotToggled => Icon::ChevronRight,
|
||||
},
|
||||
)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::Small)
|
||||
.when_some(self.on_toggle, move |this, on_toggle| {
|
||||
this.on_click(move |event, cx| on_toggle(event, cx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use gpui::{AnyElement, Div};
|
|||
use smallvec::SmallVec;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{v_stack, Label, Toggle};
|
||||
use crate::{v_stack, Label, ToggleState, Toggleable};
|
||||
|
||||
pub use list_header::*;
|
||||
pub use list_item::*;
|
||||
|
@ -20,7 +20,7 @@ pub struct List {
|
|||
/// Defaults to "No items"
|
||||
empty_message: SharedString,
|
||||
header: Option<ListHeader>,
|
||||
toggle: Toggle,
|
||||
toggle: Toggleable,
|
||||
children: SmallVec<[AnyElement; 2]>,
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ impl List {
|
|||
Self {
|
||||
empty_message: "No items".into(),
|
||||
header: None,
|
||||
toggle: Toggle::NotToggleable,
|
||||
toggle: Toggleable::NotToggleable,
|
||||
children: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ impl List {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn toggle(mut self, toggle: Toggle) -> Self {
|
||||
pub fn toggle(mut self, toggle: Toggleable) -> Self {
|
||||
self.toggle = toggle;
|
||||
self
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ impl RenderOnce for List {
|
|||
.children(self.header.map(|header| header))
|
||||
.map(|this| match (self.children.is_empty(), self.toggle) {
|
||||
(false, _) => this.children(self.children),
|
||||
(true, Toggle::Toggled(false)) => this,
|
||||
(true, Toggleable::Toggleable(ToggleState::NotToggled)) => this,
|
||||
(true, _) => this.child(Label::new(self.empty_message.clone()).color(Color::Muted)),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::rc::Rc;
|
|||
use gpui::{ClickEvent, Div};
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{h_stack, Disclosure, Icon, IconButton, IconElement, IconSize, Label, Toggle};
|
||||
use crate::{h_stack, Disclosure, Icon, IconButton, IconElement, IconSize, Label, Toggleable};
|
||||
|
||||
pub enum ListHeaderMeta {
|
||||
Tools(Vec<IconButton>),
|
||||
|
@ -17,7 +17,7 @@ pub struct ListHeader {
|
|||
label: SharedString,
|
||||
left_icon: Option<Icon>,
|
||||
meta: Option<ListHeaderMeta>,
|
||||
toggle: Toggle,
|
||||
toggle: Toggleable,
|
||||
on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
|
||||
inset: bool,
|
||||
selected: bool,
|
||||
|
@ -30,13 +30,13 @@ impl ListHeader {
|
|||
left_icon: None,
|
||||
meta: None,
|
||||
inset: false,
|
||||
toggle: Toggle::NotToggleable,
|
||||
toggle: Toggleable::NotToggleable,
|
||||
on_toggle: None,
|
||||
selected: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle(mut self, toggle: Toggle) -> Self {
|
||||
pub fn toggle(mut self, toggle: Toggleable) -> Self {
|
||||
self.toggle = toggle;
|
||||
self
|
||||
}
|
||||
|
@ -113,7 +113,10 @@ impl RenderOnce for ListHeader {
|
|||
}))
|
||||
.child(Label::new(self.label.clone()).color(Color::Muted)),
|
||||
)
|
||||
.child(Disclosure::new(self.toggle).on_toggle(self.on_toggle)),
|
||||
.children(
|
||||
Disclosure::from_toggleable(self.toggle)
|
||||
.map(|disclosure| disclosure.on_toggle(self.on_toggle)),
|
||||
),
|
||||
)
|
||||
.child(meta),
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ use gpui::{
|
|||
use smallvec::SmallVec;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{Avatar, Disclosure, GraphicSlot, Icon, IconElement, IconSize, Toggle};
|
||||
use crate::{Avatar, Disclosure, GraphicSlot, Icon, IconElement, IconSize, Toggleable};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct ListItem {
|
||||
|
@ -17,7 +17,7 @@ pub struct ListItem {
|
|||
indent_level: usize,
|
||||
indent_step_size: Pixels,
|
||||
left_slot: Option<GraphicSlot>,
|
||||
toggle: Toggle,
|
||||
toggle: Toggleable,
|
||||
inset: bool,
|
||||
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
|
||||
on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
|
||||
|
@ -33,7 +33,7 @@ impl ListItem {
|
|||
indent_level: 0,
|
||||
indent_step_size: px(12.),
|
||||
left_slot: None,
|
||||
toggle: Toggle::NotToggleable,
|
||||
toggle: Toggleable::NotToggleable,
|
||||
inset: false,
|
||||
on_click: None,
|
||||
on_secondary_mouse_down: None,
|
||||
|
@ -70,7 +70,7 @@ impl ListItem {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn toggle(mut self, toggle: Toggle) -> Self {
|
||||
pub fn toggle(mut self, toggle: Toggleable) -> Self {
|
||||
self.toggle = toggle;
|
||||
self
|
||||
}
|
||||
|
@ -150,7 +150,10 @@ impl RenderOnce for ListItem {
|
|||
.gap_1()
|
||||
.items_center()
|
||||
.relative()
|
||||
.child(Disclosure::new(self.toggle).on_toggle(self.on_toggle))
|
||||
.children(
|
||||
Disclosure::from_toggleable(self.toggle)
|
||||
.map(|disclosure| disclosure.on_toggle(self.on_toggle)),
|
||||
)
|
||||
.map(|this| match self.left_slot {
|
||||
Some(GraphicSlot::Icon(i)) => this.child(
|
||||
IconElement::new(i)
|
||||
|
|
|
@ -2,7 +2,7 @@ use gpui::{Div, Render};
|
|||
use story::Story;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{Disclosure, Toggle};
|
||||
use crate::{Disclosure, ToggleState};
|
||||
|
||||
pub struct DisclosureStory;
|
||||
|
||||
|
@ -13,10 +13,8 @@ impl Render for DisclosureStory {
|
|||
Story::container()
|
||||
.child(Story::title_for::<Disclosure>())
|
||||
.child(Story::label("Toggled"))
|
||||
.child(Disclosure::new(Toggle::Toggled(true)))
|
||||
.child(Disclosure::new(ToggleState::Toggled))
|
||||
.child(Story::label("Not Toggled"))
|
||||
.child(Disclosure::new(Toggle::Toggled(false)))
|
||||
.child(Story::label("Not Toggleable"))
|
||||
.child(Disclosure::new(Toggle::NotToggleable))
|
||||
.child(Disclosure::new(ToggleState::NotToggled))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/// Whether the entry is toggleable, and if so, whether it is currently toggled.
|
||||
///
|
||||
/// To make an element toggleable, simply add a `Toggle::Toggled(_)` and handle it's cases.
|
||||
///
|
||||
/// You can check if an element is toggleable with `.is_toggleable()`
|
||||
///
|
||||
/// Possible values:
|
||||
/// - `Toggle::NotToggleable` - The entry is not toggleable
|
||||
/// - `Toggle::Toggled(true)` - The entry is toggleable and toggled
|
||||
/// - `Toggle::Toggled(false)` - The entry is toggleable and not toggled
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Toggle {
|
||||
NotToggleable,
|
||||
Toggled(bool),
|
||||
}
|
||||
|
||||
impl Toggle {
|
||||
/// Returns true if the entry is toggled (or is not toggleable.)
|
||||
///
|
||||
/// As element that isn't toggleable is always "expanded" or "enabled"
|
||||
/// returning true in that case makes sense.
|
||||
pub fn is_toggled(&self) -> bool {
|
||||
match self {
|
||||
Self::Toggled(false) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_toggleable(&self) -> bool {
|
||||
match self {
|
||||
Self::Toggled(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Toggle {
|
||||
fn from(toggled: bool) -> Self {
|
||||
Toggle::Toggled(toggled)
|
||||
}
|
||||
}
|
38
crates/ui2/src/toggleable.rs
Normal file
38
crates/ui2/src/toggleable.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
/// Whether an element is able to be toggled.
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub enum Toggleable {
|
||||
Toggleable(ToggleState),
|
||||
NotToggleable,
|
||||
}
|
||||
|
||||
/// The current state of a [`Toggleable`] element.
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub enum ToggleState {
|
||||
Toggled,
|
||||
NotToggled,
|
||||
}
|
||||
|
||||
impl ToggleState {
|
||||
/// Returns whether an entry is toggled.
|
||||
pub fn is_toggled(&self) -> bool {
|
||||
match self {
|
||||
ToggleState::Toggled => true,
|
||||
ToggleState::NotToggled => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for ToggleState {
|
||||
fn from(toggled: bool) -> Self {
|
||||
match toggled {
|
||||
true => Self::Toggled,
|
||||
false => Self::NotToggled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ToggleState> for bool {
|
||||
fn from(value: ToggleState) -> Self {
|
||||
value.is_toggled()
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ pub mod prelude;
|
|||
mod selectable;
|
||||
mod styled_ext;
|
||||
mod styles;
|
||||
mod toggleable;
|
||||
pub mod utils;
|
||||
|
||||
pub use clickable::*;
|
||||
|
@ -30,3 +31,4 @@ pub use prelude::*;
|
|||
pub use selectable::*;
|
||||
pub use styled_ext::*;
|
||||
pub use styles::*;
|
||||
pub use toggleable::*;
|
||||
|
|
Loading…
Reference in a new issue