WIP update popover_menu

This commit is contained in:
Nate Butler 2023-11-30 14:54:44 -05:00
parent 5fdfdb046c
commit 180ba42456
2 changed files with 81 additions and 31 deletions

View File

@ -39,7 +39,7 @@ use project::{Project, RepositoryEntry};
use theme::ActiveTheme;
use ui::{
h_stack, prelude::*, Avatar, Button, ButtonLike, ButtonStyle2, Icon, IconButton, IconElement,
KeyBinding, Tooltip,
KeyBinding, PopoverMenu, Tooltip,
};
use util::ResultExt;
use workspace::{notifications::NotifyResultExt, Workspace};
@ -289,28 +289,29 @@ impl Render for CollabTitlebarItem {
this.when_some(user.avatar.clone(), |this, avatar| {
// TODO: Finish implementing user menu popover
//
// this.child(
// PopoverMenu::new(
// ButtonLike::new("user-menu")
// .child(h_stack().gap_0p5().child(Avatar::data(avatar)).child(
// IconElement::new(Icon::ChevronDown).color(Color::Muted),
// ))
// .style(ButtonStyle2::Subtle)
// .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx))
// .into_any_element(),
// )
// .children(vec![div().w_96().h_96().bg(gpui::red())]),
// )
this.child(
ButtonLike::new("user-menu")
.child(
h_stack().gap_0p5().child(Avatar::data(avatar)).child(
PopoverMenu::new(
ButtonLike::new("user-menu")
.child(h_stack().gap_0p5().child(Avatar::data(avatar)).child(
IconElement::new(Icon::ChevronDown).color(Color::Muted),
),
)
.style(ButtonStyle2::Subtle)
.tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
))
.style(ButtonStyle2::Subtle)
.tooltip(move |cx| Tooltip::text("Toggle User Menu", cx))
.into_any_element(),
)
.anchor(gpui::AnchorCorner::TopRight)
.children(vec![div().w_96().h_96().bg(gpui::red())]),
)
// this.child(
// ButtonLike::new("user-menu")
// .child(
// h_stack().gap_0p5().child(Avatar::data(avatar)).child(
// IconElement::new(Icon::ChevronDown).color(Color::Muted),
// ),
// )
// .style(ButtonStyle2::Subtle)
// .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
// )
})
} else {
this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| {

View File

@ -1,33 +1,70 @@
use gpui::{div, overlay, px, AnyElement, Div, ParentElement, RenderOnce, Styled, WindowContext};
use gpui::{
div, overlay, rems, AnchorCorner, AnyElement, Div, ParentElement, RenderOnce, Styled,
WindowContext,
};
use smallvec::SmallVec;
use crate::{prelude::*, Popover};
// 🚧 Under Construction
#[derive(IntoElement)]
pub struct PopoverMenu {
/// The element that triggers the popover menu when clicked
/// Usually a button
trigger: AnyElement,
/// The content of the popover menu
/// This will automatically be wrapped in a [Popover] element
children: SmallVec<[AnyElement; 2]>,
/// The direction the popover menu will open by default
///
/// When not enough space is available in the default direction,
/// the popover menu will follow the rules of [gpui2::elements::overlay]
anchor: AnchorCorner,
/// Whether the popover menu is currently open
show_menu: bool,
}
impl RenderOnce for PopoverMenu {
type Rendered = Div;
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
// Default offset = 4px padding + 1px border
let offset = 5. / 16.;
let (top, right, bottom, left) = match self.anchor {
AnchorCorner::TopRight => (None, Some(-offset), Some(-offset), None),
AnchorCorner::TopLeft => (None, None, Some(-offset), Some(-offset)),
AnchorCorner::BottomRight => (Some(-offset), Some(-offset), None, None),
AnchorCorner::BottomLeft => (Some(-offset), None, None, Some(-offset)),
};
div()
.flex()
.flex_none()
.bg(gpui::green())
.relative()
.child(div().bg(gpui::blue()).child(self.trigger))
.child(
overlay()
.position(gpui::Point {
x: px(100.),
y: px(100.),
})
.anchor(gpui::AnchorCorner::TopRight)
.child(Popover::new().children(self.children)),
div()
.flex_none()
.relative()
.bg(gpui::blue())
.child(self.trigger),
)
.when(self.show_menu, |this| {
this.child(
div()
.absolute()
.size_0()
.when_some(top, |this, t| this.top(rems(t)))
.when_some(right, |this, r| this.right(rems(r)))
.when_some(bottom, |this, b| this.bottom(rems(b)))
.when_some(left, |this, l| this.left(rems(l)))
.child(
overlay()
.anchor(AnchorCorner::TopRight)
.child(Popover::new().children(self.children)),
),
)
})
}
}
@ -36,8 +73,20 @@ impl PopoverMenu {
Self {
trigger,
children: SmallVec::new(),
anchor: AnchorCorner::TopLeft,
show_menu: false,
}
}
pub fn anchor(mut self, anchor: AnchorCorner) -> Self {
self.anchor = anchor;
self
}
pub fn show_menu(mut self, show_menu: bool) -> Self {
self.show_menu = show_menu;
self
}
}
impl ParentElement for PopoverMenu {