Progress on ContextMenu
This commit is contained in:
parent
9456f716c2
commit
074a221e0f
5 changed files with 247 additions and 158 deletions
|
@ -10,7 +10,10 @@ use schemars::JsonSchema;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use smallvec::SmallVec;
|
||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||
use ui::{h_stack, IconButton, InteractionState, Label, Tooltip};
|
||||
use ui::{
|
||||
h_stack, ContextMenu, ContextMenuItem, IconButton, InteractionState, Label, MenuEvent,
|
||||
MenuHandle, Tooltip,
|
||||
};
|
||||
|
||||
pub enum PanelEvent {
|
||||
ChangePosition,
|
||||
|
@ -659,117 +662,6 @@ impl PanelButtons {
|
|||
// }
|
||||
// }
|
||||
|
||||
pub struct MenuHandle<V: 'static> {
|
||||
id: ElementId,
|
||||
children: SmallVec<[AnyElement<V>; 2]>,
|
||||
builder: Rc<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyView + 'static>,
|
||||
}
|
||||
|
||||
impl<V: 'static> ParentComponent<V> for MenuHandle<V> {
|
||||
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
|
||||
&mut self.children
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> MenuHandle<V> {
|
||||
fn new(
|
||||
id: impl Into<ElementId>,
|
||||
builder: impl Fn(&mut V, &mut ViewContext<V>) -> AnyView + 'static,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
children: SmallVec::new(),
|
||||
builder: Rc::new(builder),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MenuState<V> {
|
||||
open: Rc<RefCell<bool>>,
|
||||
menu: Option<AnyElement<V>>,
|
||||
}
|
||||
// Here be dragons
|
||||
impl<V: 'static> Element<V> for MenuHandle<V> {
|
||||
type ElementState = MenuState<V>;
|
||||
|
||||
fn element_id(&self) -> Option<gpui::ElementId> {
|
||||
Some(self.id.clone())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) -> (gpui::LayoutId, Self::ElementState) {
|
||||
let mut child_layout_ids = self
|
||||
.children
|
||||
.iter_mut()
|
||||
.map(|child| child.layout(view_state, cx))
|
||||
.collect::<SmallVec<[LayoutId; 2]>>();
|
||||
|
||||
let open = if let Some(element_state) = element_state {
|
||||
element_state.open
|
||||
} else {
|
||||
Rc::new(RefCell::new(false))
|
||||
};
|
||||
|
||||
let mut menu = None;
|
||||
if *open.borrow() {
|
||||
let mut view = (self.builder)(view_state, cx).render();
|
||||
child_layout_ids.push(view.layout(view_state, cx));
|
||||
menu.replace(view);
|
||||
}
|
||||
let layout_id = cx.request_layout(&gpui::Style::default(), child_layout_ids.into_iter());
|
||||
|
||||
(layout_id, MenuState { open, menu })
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: crate::Bounds<gpui::Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) {
|
||||
for child in &mut self.children {
|
||||
child.paint(view_state, cx);
|
||||
}
|
||||
|
||||
if let Some(mut menu) = element_state.menu.as_mut() {
|
||||
menu.paint(view_state, cx);
|
||||
return;
|
||||
}
|
||||
|
||||
let open = element_state.open.clone();
|
||||
cx.on_mouse_event(move |view_state, event: &MouseDownEvent, phase, cx| {
|
||||
dbg!(&event, &phase);
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& event.button == MouseButton::Right
|
||||
&& bounds.contains_point(&event.position)
|
||||
{
|
||||
*open.borrow_mut() = true;
|
||||
cx.notify();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> Component<V> for MenuHandle<V> {
|
||||
fn render(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
struct TestMenu {}
|
||||
impl Render for TestMenu {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
div().child("0MG!")
|
||||
}
|
||||
}
|
||||
|
||||
// here be kittens
|
||||
impl Render for PanelButtons {
|
||||
type Element = Div<Self>;
|
||||
|
@ -807,7 +699,7 @@ impl Render for PanelButtons {
|
|||
Some(
|
||||
MenuHandle::new(
|
||||
SharedString::from(format!("{} tooltip", name)),
|
||||
move |_, cx| Tooltip::text("HELLOOOOOOOOOOOOOO", cx),
|
||||
move |_, cx| cx.build_view(|cx| ContextMenu::new(cx).header("SECTION")),
|
||||
)
|
||||
.child(button),
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue