Merge branch 'main' into user-menu
This commit is contained in:
commit
7e1d61d116
85 changed files with 3355 additions and 2696 deletions
|
@ -2,7 +2,6 @@ use gpui::{relative, DefiniteLength};
|
|||
use gpui::{rems, transparent_black, AnyElement, AnyView, ClickEvent, Div, Hsla, Rems, Stateful};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::h_stack;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub trait ButtonCommon: Clickable + Disableable {
|
||||
|
@ -250,6 +249,7 @@ impl ButtonSize {
|
|||
/// This is also used to build the prebuilt buttons.
|
||||
#[derive(IntoElement)]
|
||||
pub struct ButtonLike {
|
||||
base: Div,
|
||||
id: ElementId,
|
||||
pub(super) style: ButtonStyle,
|
||||
pub(super) disabled: bool,
|
||||
|
@ -264,6 +264,7 @@ pub struct ButtonLike {
|
|||
impl ButtonLike {
|
||||
pub fn new(id: impl Into<ElementId>) -> Self {
|
||||
Self {
|
||||
base: div(),
|
||||
id: id.into(),
|
||||
style: ButtonStyle::default(),
|
||||
disabled: false,
|
||||
|
@ -331,6 +332,13 @@ impl ButtonCommon for ButtonLike {
|
|||
}
|
||||
}
|
||||
|
||||
impl VisibleOnHover for ButtonLike {
|
||||
fn visible_on_hover(mut self, group_name: impl Into<SharedString>) -> Self {
|
||||
self.base = self.base.visible_on_hover(group_name);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ParentElement for ButtonLike {
|
||||
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
|
||||
&mut self.children
|
||||
|
@ -341,7 +349,8 @@ impl RenderOnce for ButtonLike {
|
|||
type Rendered = Stateful<Div>;
|
||||
|
||||
fn render(self, cx: &mut WindowContext) -> Self::Rendered {
|
||||
h_stack()
|
||||
self.base
|
||||
.h_flex()
|
||||
.id(self.id.clone())
|
||||
.group("")
|
||||
.flex_none()
|
||||
|
|
|
@ -98,6 +98,13 @@ impl ButtonCommon for IconButton {
|
|||
}
|
||||
}
|
||||
|
||||
impl VisibleOnHover for IconButton {
|
||||
fn visible_on_hover(mut self, group_name: impl Into<SharedString>) -> Self {
|
||||
self.base = self.base.visible_on_hover(group_name);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for IconButton {
|
||||
type Rendered = ButtonLike;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{prelude::*, Color, Icon, IconButton, IconSize};
|
||||
use gpui::ClickEvent;
|
||||
|
||||
use crate::{prelude::*, Color, Icon, IconButton, IconSize};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Disclosure {
|
||||
is_open: bool,
|
||||
|
|
|
@ -111,10 +111,9 @@ impl RenderOnce for ListHeader {
|
|||
.when_some(self.end_hover_slot, |this, end_hover_slot| {
|
||||
this.child(
|
||||
div()
|
||||
.invisible()
|
||||
.group_hover("list_header", |this| this.visible())
|
||||
.absolute()
|
||||
.right_0()
|
||||
.visible_on_hover("list_header")
|
||||
.child(end_hover_slot),
|
||||
)
|
||||
}),
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::{prelude::*, Disclosure};
|
||||
use gpui::{
|
||||
px, AnyElement, AnyView, ClickEvent, Div, MouseButton, MouseDownEvent, Pixels, Stateful,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{prelude::*, Disclosure};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct ListItem {
|
||||
id: ElementId,
|
||||
|
@ -127,7 +128,7 @@ impl RenderOnce for ListItem {
|
|||
|
||||
fn render(self, cx: &mut WindowContext) -> Self::Rendered {
|
||||
h_stack()
|
||||
.id("item_container")
|
||||
.id(self.id)
|
||||
.w_full()
|
||||
.relative()
|
||||
// When an item is inset draw the indent spacing outside of the item
|
||||
|
@ -150,7 +151,7 @@ impl RenderOnce for ListItem {
|
|||
})
|
||||
.child(
|
||||
h_stack()
|
||||
.id(self.id)
|
||||
.id("inner_list_item")
|
||||
.w_full()
|
||||
.relative()
|
||||
.gap_1()
|
||||
|
@ -170,13 +171,7 @@ impl RenderOnce for ListItem {
|
|||
})
|
||||
})
|
||||
.when_some(self.on_click, |this, on_click| {
|
||||
this.cursor_pointer().on_click(move |event, cx| {
|
||||
// HACK: GPUI currently fires `on_click` with any mouse button,
|
||||
// but we only care about the left button.
|
||||
if event.down.button == MouseButton::Left {
|
||||
(on_click)(event, cx)
|
||||
}
|
||||
})
|
||||
this.cursor_pointer().on_click(on_click)
|
||||
})
|
||||
.when_some(self.on_secondary_mouse_down, |this, on_mouse_down| {
|
||||
this.on_mouse_down(MouseButton::Right, move |event, cx| {
|
||||
|
@ -192,10 +187,14 @@ impl RenderOnce for ListItem {
|
|||
this.ml(self.indent_level as f32 * self.indent_step_size)
|
||||
}
|
||||
})
|
||||
.children(
|
||||
self.toggle
|
||||
.map(|is_open| Disclosure::new(is_open).on_toggle(self.on_toggle)),
|
||||
)
|
||||
.children(self.toggle.map(|is_open| {
|
||||
div()
|
||||
.flex()
|
||||
.absolute()
|
||||
.left(rems(-1.))
|
||||
.visible_on_hover("")
|
||||
.child(Disclosure::new(is_open).on_toggle(self.on_toggle))
|
||||
}))
|
||||
.child(
|
||||
h_stack()
|
||||
.flex_1()
|
||||
|
@ -220,8 +219,7 @@ impl RenderOnce for ListItem {
|
|||
.absolute()
|
||||
.right_2()
|
||||
.top_0()
|
||||
.invisible()
|
||||
.group_hover("list_item", |this| this.visible())
|
||||
.visible_on_hover("list_item")
|
||||
.child(end_hover_slot),
|
||||
)
|
||||
}),
|
||||
|
|
|
@ -182,12 +182,12 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
|
|||
}
|
||||
|
||||
fn paint(
|
||||
self,
|
||||
&mut self,
|
||||
_: Bounds<gpui::Pixels>,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
if let Some(child) = element_state.child_element.take() {
|
||||
if let Some(mut child) = element_state.child_element.take() {
|
||||
child.paint(cx);
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
|
|||
element_state.child_bounds = Some(cx.layout_bounds(child_layout_id));
|
||||
}
|
||||
|
||||
if let Some(menu) = element_state.menu_element.take() {
|
||||
if let Some(mut menu) = element_state.menu_element.take() {
|
||||
menu.paint(cx);
|
||||
|
||||
if let Some(child_bounds) = element_state.child_bounds {
|
||||
|
|
|
@ -112,21 +112,21 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
|
|||
}
|
||||
|
||||
fn paint(
|
||||
self,
|
||||
&mut self,
|
||||
bounds: Bounds<gpui::Pixels>,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
if let Some(child) = element_state.child_element.take() {
|
||||
if let Some(mut child) = element_state.child_element.take() {
|
||||
child.paint(cx);
|
||||
}
|
||||
|
||||
if let Some(menu) = element_state.menu_element.take() {
|
||||
if let Some(mut menu) = element_state.menu_element.take() {
|
||||
menu.paint(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(builder) = self.menu_builder else {
|
||||
let Some(builder) = self.menu_builder.take() else {
|
||||
return;
|
||||
};
|
||||
let menu = element_state.menu.clone();
|
||||
|
|
|
@ -17,7 +17,7 @@ impl Render for ListItemStory {
|
|||
.child(ListItem::new("hello_world").child("Hello, world!"))
|
||||
.child(Story::label("Inset"))
|
||||
.child(
|
||||
ListItem::new("hello_world")
|
||||
ListItem::new("inset_list_item")
|
||||
.inset(true)
|
||||
.start_slot(
|
||||
IconElement::new(Icon::Bell)
|
||||
|
@ -59,7 +59,7 @@ impl Render for ListItemStory {
|
|||
)
|
||||
.child(Story::label("With end hover slot"))
|
||||
.child(
|
||||
ListItem::new("with_left_avatar")
|
||||
ListItem::new("with_end_hover_slot")
|
||||
.child("Hello, world!")
|
||||
.end_slot(
|
||||
h_stack()
|
||||
|
|
|
@ -158,7 +158,6 @@ impl RenderOnce for Tab {
|
|||
)
|
||||
.child(
|
||||
h_stack()
|
||||
.invisible()
|
||||
.w_3()
|
||||
.h_3()
|
||||
.justify_center()
|
||||
|
@ -167,7 +166,7 @@ impl RenderOnce for Tab {
|
|||
TabCloseSide::Start => this.left_1(),
|
||||
TabCloseSide::End => this.right_1(),
|
||||
})
|
||||
.group_hover("", |style| style.visible())
|
||||
.visible_on_hover("")
|
||||
.children(self.end_slot),
|
||||
)
|
||||
.children(self.children),
|
||||
|
|
|
@ -9,6 +9,7 @@ pub use crate::clickable::*;
|
|||
pub use crate::disableable::*;
|
||||
pub use crate::fixed::*;
|
||||
pub use crate::selectable::*;
|
||||
pub use crate::visible_on_hover::*;
|
||||
pub use crate::{h_stack, v_stack};
|
||||
pub use crate::{Button, ButtonSize, ButtonStyle, IconButton};
|
||||
pub use crate::{ButtonCommon, Color, StyledExt};
|
||||
|
|
|
@ -20,14 +20,14 @@ pub enum ElevationIndex {
|
|||
}
|
||||
|
||||
impl ElevationIndex {
|
||||
pub fn z_index(self) -> u32 {
|
||||
pub fn z_index(self) -> u8 {
|
||||
match self {
|
||||
ElevationIndex::Background => 0,
|
||||
ElevationIndex::Surface => 100,
|
||||
ElevationIndex::ElevatedSurface => 200,
|
||||
ElevationIndex::Wash => 250,
|
||||
ElevationIndex::ModalSurface => 300,
|
||||
ElevationIndex::DraggedElement => 900,
|
||||
ElevationIndex::Surface => 42,
|
||||
ElevationIndex::ElevatedSurface => 84,
|
||||
ElevationIndex::Wash => 126,
|
||||
ElevationIndex::ModalSurface => 168,
|
||||
ElevationIndex::DraggedElement => 210,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ mod selectable;
|
|||
mod styled_ext;
|
||||
mod styles;
|
||||
pub mod utils;
|
||||
mod visible_on_hover;
|
||||
|
||||
pub use clickable::*;
|
||||
pub use components::*;
|
||||
|
@ -30,3 +31,4 @@ pub use prelude::*;
|
|||
pub use selectable::*;
|
||||
pub use styled_ext::*;
|
||||
pub use styles::*;
|
||||
pub use visible_on_hover::*;
|
||||
|
|
15
crates/ui2/src/visible_on_hover.rs
Normal file
15
crates/ui2/src/visible_on_hover.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use gpui::{InteractiveElement, SharedString, Styled};
|
||||
|
||||
pub trait VisibleOnHover {
|
||||
/// Sets the element to only be visible when the specified group is hovered.
|
||||
///
|
||||
/// Pass `""` as the `group_name` to use the global group.
|
||||
fn visible_on_hover(self, group_name: impl Into<SharedString>) -> Self;
|
||||
}
|
||||
|
||||
impl<E: InteractiveElement + Styled> VisibleOnHover for E {
|
||||
fn visible_on_hover(self, group_name: impl Into<SharedString>) -> Self {
|
||||
self.invisible()
|
||||
.group_hover(group_name, |style| style.visible())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue