mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-06 02:37:21 +00:00
Clean compile with redesigned element traits
This commit is contained in:
parent
0673606de8
commit
33cd6f520a
35 changed files with 278 additions and 216 deletions
|
@ -3294,7 +3294,7 @@ impl CollabPanel {
|
|||
// .with_width(size.x())
|
||||
// }
|
||||
|
||||
impl Render for CollabPanel {
|
||||
impl Render<Self> for CollabPanel {
|
||||
type Element = Focusable<Self, Div<Self>>;
|
||||
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -31,7 +31,7 @@ use std::sync::Arc;
|
|||
use call::ActiveCall;
|
||||
use client::{Client, UserStore};
|
||||
use gpui::{
|
||||
div, px, rems, AppContext, Component, Div, InteractiveElement, Model, ParentElement, Render,
|
||||
div, px, rems, AppContext, Div, InteractiveElement, Model, ParentElement, Render, RenderOnce,
|
||||
Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext,
|
||||
WeakView, WindowBounds,
|
||||
};
|
||||
|
@ -81,7 +81,7 @@ pub struct CollabTitlebarItem {
|
|||
_subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
impl Render for CollabTitlebarItem {
|
||||
impl Render<Self> for CollabTitlebarItem {
|
||||
type Element = Stateful<Self, Div<Self>>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use collections::{CommandPaletteFilter, HashMap};
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
actions, div, prelude::*, Action, AppContext, Component, Dismiss, Div, FocusHandle, Keystroke,
|
||||
actions, div, prelude::*, Action, AppContext, Dismiss, Div, FocusHandle, Keystroke,
|
||||
ManagedView, ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
|
@ -74,7 +74,7 @@ impl ManagedView for CommandPalette {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for CommandPalette {
|
||||
impl Render<Self> for CommandPalette {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -42,9 +42,9 @@ use gpui::{
|
|||
actions, div, point, prelude::*, px, relative, rems, size, uniform_list, Action, AnyElement,
|
||||
AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Component, Context,
|
||||
EventEmitter, FocusHandle, FocusableView, FontFeatures, FontStyle, FontWeight, HighlightStyle,
|
||||
Hsla, InputHandler, KeyContext, Model, MouseButton, ParentElement, Pixels, Render, Styled,
|
||||
Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext,
|
||||
WeakView, WindowContext,
|
||||
Hsla, InputHandler, KeyContext, Model, MouseButton, ParentElement, Pixels, Render,
|
||||
SharedString, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View,
|
||||
ViewContext, VisualContext, WeakView, WindowContext,
|
||||
};
|
||||
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
||||
use hover_popover::{hide_hover, HoverState};
|
||||
|
@ -1580,7 +1580,8 @@ impl CodeActionsMenu {
|
|||
)
|
||||
.map(|task| task.detach_and_log_err(cx));
|
||||
})
|
||||
.child(action.lsp_action.title.clone())
|
||||
// TASK: It would be good to make lsp_action.title a SharedString to avoid allocating here.
|
||||
.child(SharedString::from(action.lsp_action.title.clone()))
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
|
@ -1595,7 +1596,7 @@ impl CodeActionsMenu {
|
|||
.max_by_key(|(_, action)| action.lsp_action.title.chars().count())
|
||||
.map(|(ix, _)| ix),
|
||||
)
|
||||
.render_once();
|
||||
.render_into_any();
|
||||
|
||||
if self.deployed_from_indicator {
|
||||
*cursor_position.column_mut() = 0;
|
||||
|
@ -4353,19 +4354,19 @@ impl Editor {
|
|||
style: &EditorStyle,
|
||||
is_active: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<AnyElement<Self>> {
|
||||
) -> Option<IconButton<Self>> {
|
||||
if self.available_code_actions.is_some() {
|
||||
Some(
|
||||
IconButton::new("code_actions_indicator", ui::Icon::Bolt)
|
||||
.on_click(|editor: &mut Editor, cx| {
|
||||
IconButton::new("code_actions_indicator", ui::Icon::Bolt).on_click(
|
||||
|editor: &mut Editor, cx| {
|
||||
editor.toggle_code_actions(
|
||||
&ToggleCodeActions {
|
||||
deployed_from_indicator: true,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.into_any(),
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
|
@ -4380,7 +4381,7 @@ impl Editor {
|
|||
line_height: Pixels,
|
||||
gutter_margin: Pixels,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Vec<Option<AnyElement<Self>>> {
|
||||
) -> Vec<Option<IconButton<Self>>> {
|
||||
fold_data
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
@ -4392,16 +4393,16 @@ impl Editor {
|
|||
FoldStatus::Folded => ui::Icon::ChevronRight,
|
||||
FoldStatus::Foldable => ui::Icon::ChevronDown,
|
||||
};
|
||||
IconButton::new(ix as usize, icon)
|
||||
.on_click(move |editor: &mut Editor, cx| match fold_status {
|
||||
IconButton::new(ix as usize, icon).on_click(
|
||||
move |editor: &mut Editor, cx| match fold_status {
|
||||
FoldStatus::Folded => {
|
||||
editor.unfold_at(&UnfoldAt { buffer_row }, cx);
|
||||
}
|
||||
FoldStatus::Foldable => {
|
||||
editor.fold_at(&FoldAt { buffer_row }, cx);
|
||||
}
|
||||
})
|
||||
.into_any()
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
|
@ -7792,7 +7793,7 @@ impl Editor {
|
|||
cx.editor_style.diagnostic_style.clone(),
|
||||
},
|
||||
)))
|
||||
.render_once()
|
||||
.render_into_any()
|
||||
}
|
||||
}),
|
||||
disposition: BlockDisposition::Below,
|
||||
|
@ -9994,7 +9995,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
|
|||
cx.write_to_clipboard(ClipboardItem::new(message.clone()));
|
||||
})
|
||||
.tooltip(|_, cx| Tooltip::text("Copy diagnostic message", cx))
|
||||
.render_once()
|
||||
.render_into_any()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -3048,7 +3048,7 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) {
|
|||
position: snapshot.anchor_after(Point::new(2, 0)),
|
||||
disposition: BlockDisposition::Below,
|
||||
height: 1,
|
||||
render: Arc::new(|_| div().render_once()),
|
||||
render: Arc::new(|_| div().into_any()),
|
||||
}],
|
||||
Some(Autoscroll::fit()),
|
||||
cx,
|
||||
|
|
|
@ -490,6 +490,7 @@ impl EditorElement {
|
|||
|
||||
for (ix, fold_indicator) in layout.fold_indicators.drain(..).enumerate() {
|
||||
if let Some(mut fold_indicator) = fold_indicator {
|
||||
let mut fold_indicator = fold_indicator.render_into_any();
|
||||
let available_space = size(
|
||||
AvailableSpace::MinContent,
|
||||
AvailableSpace::Definite(line_height * 0.55),
|
||||
|
@ -509,20 +510,21 @@ impl EditorElement {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(mut indicator) = layout.code_actions_indicator.take() {
|
||||
if let Some(indicator) = layout.code_actions_indicator.take() {
|
||||
let mut button = indicator.button.render_into_any();
|
||||
let available_space = size(
|
||||
AvailableSpace::MinContent,
|
||||
AvailableSpace::Definite(line_height),
|
||||
);
|
||||
let indicator_size = indicator.element.measure(available_space, editor, cx);
|
||||
let indicator_size = button.measure(available_space, editor, cx);
|
||||
|
||||
let mut x = Pixels::ZERO;
|
||||
let mut y = indicator.row as f32 * line_height - scroll_top;
|
||||
// Center indicator.
|
||||
x += ((layout.gutter_padding + layout.gutter_margin) - indicator_size.width) / 2.;
|
||||
y += (line_height - indicator_size.height) / 2.;
|
||||
indicator
|
||||
.element
|
||||
.draw(bounds.origin + point(x, y), available_space, editor, cx);
|
||||
|
||||
button.draw(bounds.origin + point(x, y), available_space, editor, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1810,7 +1812,7 @@ impl EditorElement {
|
|||
.render_code_actions_indicator(&style, active, cx)
|
||||
.map(|element| CodeActionsIndicator {
|
||||
row: newest_selection_head.row(),
|
||||
element,
|
||||
button: element,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2041,14 +2043,19 @@ impl EditorElement {
|
|||
// Can't use .and_then() because `.file_name()` and `.parent()` return references :(
|
||||
if let Some(path) = path {
|
||||
filename = path.file_name().map(|f| f.to_string_lossy().to_string());
|
||||
parent_path =
|
||||
path.parent().map(|p| p.to_string_lossy().to_string() + "/");
|
||||
parent_path = path
|
||||
.parent()
|
||||
.map(|p| SharedString::from(p.to_string_lossy().to_string() + "/"));
|
||||
}
|
||||
|
||||
h_stack()
|
||||
.size_full()
|
||||
.bg(gpui::red())
|
||||
.child(filename.unwrap_or_else(|| "untitled".to_string()))
|
||||
.child(
|
||||
filename
|
||||
.map(SharedString::from)
|
||||
.unwrap_or_else(|| "untitled".into()),
|
||||
)
|
||||
.children(parent_path)
|
||||
.children(jump_icon) // .p_x(gutter_padding)
|
||||
} else {
|
||||
|
@ -2059,7 +2066,7 @@ impl EditorElement {
|
|||
.child("⋯")
|
||||
.children(jump_icon) // .p_x(gutter_padding)
|
||||
};
|
||||
element.render()
|
||||
element.into_any()
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2391,10 +2398,6 @@ enum Invisible {
|
|||
impl Element<Editor> for EditorElement {
|
||||
type State = ();
|
||||
|
||||
fn element_id(&self) -> Option<gpui::ElementId> {
|
||||
Some(self.editor_id.into())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
editor: &mut Editor,
|
||||
|
@ -2469,6 +2472,10 @@ impl Element<Editor> for EditorElement {
|
|||
impl RenderOnce<Editor> for EditorElement {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<gpui::ElementId> {
|
||||
Some(self.editor_id.into())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -3098,14 +3105,14 @@ pub struct LayoutState {
|
|||
context_menu: Option<(DisplayPoint, AnyElement<Editor>)>,
|
||||
code_actions_indicator: Option<CodeActionsIndicator>,
|
||||
// hover_popovers: Option<(DisplayPoint, Vec<AnyElement<Editor>>)>,
|
||||
fold_indicators: Vec<Option<AnyElement<Editor>>>,
|
||||
fold_indicators: Vec<Option<IconButton<Editor>>>,
|
||||
tab_invisible: ShapedLine,
|
||||
space_invisible: ShapedLine,
|
||||
}
|
||||
|
||||
struct CodeActionsIndicator {
|
||||
row: u32,
|
||||
element: AnyElement<Editor>,
|
||||
button: IconButton<Editor>,
|
||||
}
|
||||
|
||||
struct PositionMap {
|
||||
|
|
|
@ -2,9 +2,8 @@ use collections::HashMap;
|
|||
use editor::{scroll::autoscroll::Autoscroll, Bias, Editor};
|
||||
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
||||
use gpui::{
|
||||
actions, div, AppContext, Component, Dismiss, Div, FocusHandle, InteractiveElement,
|
||||
ManagedView, Model, ParentElement, Render, Styled, Task, View, ViewContext, VisualContext,
|
||||
WeakView,
|
||||
actions, div, AppContext, Dismiss, Div, FocusHandle, InteractiveElement, ManagedView, Model,
|
||||
ParentElement, Render, RenderOnce, Styled, Task, View, ViewContext, VisualContext, WeakView,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId};
|
||||
|
@ -116,7 +115,7 @@ impl ManagedView for FileFinder {
|
|||
self.picker.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
impl Render for FileFinder {
|
||||
impl Render<Self> for FileFinder {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -143,7 +143,7 @@ impl GoToLine {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for GoToLine {
|
||||
impl Render<Self> for GoToLine {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -14,12 +14,50 @@ pub trait Render<V: 'static>: 'static + Sized {
|
|||
pub trait RenderOnce<V: 'static>: Sized {
|
||||
type Element: Element<V> + 'static;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId>;
|
||||
|
||||
fn render_once(self) -> Self::Element;
|
||||
|
||||
fn render_into_any(self) -> AnyElement<V> {
|
||||
self.render_once().into_any()
|
||||
}
|
||||
|
||||
fn draw<T, R>(
|
||||
self,
|
||||
origin: Point<Pixels>,
|
||||
available_space: Size<T>,
|
||||
view_state: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
f: impl FnOnce(&mut <Self::Element as Element<V>>::State, &mut ViewContext<V>) -> R,
|
||||
) -> R
|
||||
where
|
||||
T: Clone + Default + Debug + Into<AvailableSpace>,
|
||||
{
|
||||
let element = self.render_once();
|
||||
let element_id = element.element_id();
|
||||
let element = DrawableElement {
|
||||
element: Some(element),
|
||||
phase: ElementDrawPhase::Start,
|
||||
};
|
||||
let frame_state = DrawableElement::draw(
|
||||
element,
|
||||
origin,
|
||||
available_space.map(Into::into),
|
||||
view_state,
|
||||
cx,
|
||||
);
|
||||
|
||||
if let Some(mut frame_state) = frame_state {
|
||||
f(&mut frame_state, cx)
|
||||
} else {
|
||||
cx.with_element_state(element_id.unwrap(), |element_state, cx| {
|
||||
let mut element_state = element_state.unwrap();
|
||||
let result = f(&mut element_state, cx);
|
||||
(result, element_state)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn map<U>(self, f: impl FnOnce(Self) -> U) -> U
|
||||
where
|
||||
Self: Sized,
|
||||
|
@ -52,8 +90,6 @@ pub trait RenderOnce<V: 'static>: Sized {
|
|||
pub trait Element<V: 'static>: 'static + RenderOnce<V> {
|
||||
type State: 'static;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId>;
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -72,35 +108,6 @@ pub trait Element<V: 'static>: 'static + RenderOnce<V> {
|
|||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
}
|
||||
|
||||
fn draw<T, R>(
|
||||
self,
|
||||
origin: Point<Pixels>,
|
||||
available_space: Size<T>,
|
||||
view_state: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
f: impl FnOnce(&mut Self::State, &mut ViewContext<V>) -> R,
|
||||
) -> R
|
||||
where
|
||||
T: Clone + Default + Debug + Into<AvailableSpace>,
|
||||
{
|
||||
let element_id = self.element_id();
|
||||
let element = DrawableElement {
|
||||
element: Some(self),
|
||||
phase: ElementDrawPhase::Start,
|
||||
};
|
||||
let frame_state = element.draw(origin, available_space.map(Into::into), view_state, cx);
|
||||
|
||||
if let Some(mut frame_state) = frame_state {
|
||||
f(&mut frame_state, cx)
|
||||
} else {
|
||||
cx.with_element_state(element_id.unwrap(), |element_state, cx| {
|
||||
let mut element_state = element_state.unwrap();
|
||||
let result = f(&mut element_state, cx);
|
||||
(result, element_state)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Component<V: 'static>: 'static {
|
||||
|
@ -131,10 +138,6 @@ impl<V, C> CompositeElement<V, C> {
|
|||
impl<V: 'static, C: Component<V>> Element<V> for CompositeElement<V, C> {
|
||||
type State = CompositeElementState<V, C>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view: &mut V,
|
||||
|
@ -174,6 +177,10 @@ impl<V: 'static, C: Component<V>> Element<V> for CompositeElement<V, C> {
|
|||
impl<V: 'static, C: Component<V>> RenderOnce<V> for CompositeElement<V, C> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -231,23 +238,21 @@ pub struct DrawableElement<V: 'static, E: Element<V>> {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
enum ElementDrawPhase<V> {
|
||||
enum ElementDrawPhase<S> {
|
||||
#[default]
|
||||
Start,
|
||||
LayoutRequested {
|
||||
layout_id: LayoutId,
|
||||
frame_state: Option<V>,
|
||||
frame_state: Option<S>,
|
||||
},
|
||||
LayoutComputed {
|
||||
layout_id: LayoutId,
|
||||
available_space: Size<AvailableSpace>,
|
||||
frame_state: Option<V>,
|
||||
frame_state: Option<S>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Internal struct that wraps an element to store Layout and ElementState after the element is rendered.
|
||||
/// It's allocated as a trait object to erase the element type and wrapped in AnyElement<E::State> for
|
||||
/// improved usability.
|
||||
/// A wrapper around an implementer of [Element] that allows it to be drawn in a window.
|
||||
impl<V, E: Element<V>> DrawableElement<V, E> {
|
||||
fn new(element: E) -> Self {
|
||||
DrawableElement {
|
||||
|
@ -379,6 +384,41 @@ impl<V, E: Element<V>> DrawableElement<V, E> {
|
|||
}
|
||||
}
|
||||
|
||||
// impl<V: 'static, E: Element<V>> Element<V> for DrawableElement<V, E> {
|
||||
// type State = <E::Element as Element<V>>::State;
|
||||
|
||||
// fn layout(
|
||||
// &mut self,
|
||||
// view_state: &mut V,
|
||||
// element_state: Option<Self::State>,
|
||||
// cx: &mut ViewContext<V>,
|
||||
// ) -> (LayoutId, Self::State) {
|
||||
|
||||
// }
|
||||
|
||||
// fn paint(
|
||||
// self,
|
||||
// bounds: Bounds<Pixels>,
|
||||
// view_state: &mut V,
|
||||
// element_state: &mut Self::State,
|
||||
// cx: &mut ViewContext<V>,
|
||||
// ) {
|
||||
// todo!()
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<V: 'static, E: 'static + Element<V>> RenderOnce<V> for DrawableElement<V, E> {
|
||||
// type Element = Self;
|
||||
|
||||
// fn element_id(&self) -> Option<ElementId> {
|
||||
// self.element.as_ref()?.element_id()
|
||||
// }
|
||||
|
||||
// fn render_once(self) -> Self::Element {
|
||||
// self
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<V, E> ElementObject<V> for Option<DrawableElement<V, E>>
|
||||
where
|
||||
E: Element<V>,
|
||||
|
@ -476,10 +516,6 @@ impl<V: 'static> AnyElement<V> {
|
|||
impl<V: 'static> Element<V> for AnyElement<V> {
|
||||
type State = ();
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
AnyElement::element_id(self)
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -504,6 +540,10 @@ impl<V: 'static> Element<V> for AnyElement<V> {
|
|||
impl<V: 'static> RenderOnce<V> for AnyElement<V> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
AnyElement::element_id(self)
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -602,10 +602,6 @@ impl<V: 'static> ParentElement<V> for Div<V> {
|
|||
impl<V: 'static> Element<V> for Div<V> {
|
||||
type State = DivState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -694,6 +690,10 @@ impl<V: 'static> Element<V> for Div<V> {
|
|||
impl<V: 'static> RenderOnce<V> for Div<V> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -1293,10 +1293,6 @@ where
|
|||
{
|
||||
type State = E::State;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.element_id()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -1324,6 +1320,10 @@ where
|
|||
{
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.element_id()
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -1381,10 +1381,6 @@ where
|
|||
{
|
||||
type State = E::State;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.element_id()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -1412,6 +1408,10 @@ where
|
|||
{
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.element_id()
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -37,10 +37,6 @@ where
|
|||
impl<V> Element<V> for Img<V> {
|
||||
type State = InteractiveElementState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view_state: &mut V,
|
||||
|
@ -98,6 +94,10 @@ impl<V> Element<V> for Img<V> {
|
|||
impl<V: 'static> RenderOnce<V> for Img<V> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -60,10 +60,6 @@ impl<V: 'static> ParentElement<V> for Overlay<V> {
|
|||
impl<V: 'static> Element<V> for Overlay<V> {
|
||||
type State = OverlayState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -160,6 +156,10 @@ impl<V: 'static> Element<V> for Overlay<V> {
|
|||
impl<V: 'static> RenderOnce<V> for Overlay<V> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -26,10 +26,6 @@ impl<V> Svg<V> {
|
|||
impl<V> Element<V> for Svg<V> {
|
||||
type State = InteractiveElementState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view_state: &mut V,
|
||||
|
@ -62,6 +58,10 @@ impl<V> Element<V> for Svg<V> {
|
|||
impl<V: 'static> RenderOnce<V> for Svg<V> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -11,10 +11,6 @@ use util::ResultExt;
|
|||
impl<V: 'static> Element<V> for &'static str {
|
||||
type State = TextState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
|
@ -40,6 +36,10 @@ impl<V: 'static> Element<V> for &'static str {
|
|||
impl<V: 'static> RenderOnce<V> for &'static str {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -48,10 +48,6 @@ impl<V: 'static> RenderOnce<V> for &'static str {
|
|||
impl<V: 'static> Element<V> for SharedString {
|
||||
type State = TextState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.clone().into())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
|
@ -78,6 +74,10 @@ impl<V: 'static> Element<V> for SharedString {
|
|||
impl<V: 'static> RenderOnce<V> for SharedString {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.clone().into())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -105,10 +105,6 @@ impl StyledText {
|
|||
impl<V: 'static> Element<V> for StyledText {
|
||||
type State = TextState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view: &mut V,
|
||||
|
@ -194,6 +190,10 @@ impl<V: 'static> Element<V> for StyledText {
|
|||
impl<V: 'static> RenderOnce<V> for StyledText {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -300,10 +300,6 @@ struct InteractiveTextState {
|
|||
impl<V: 'static> Element<V> for InteractiveText {
|
||||
type State = InteractiveTextState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.id.clone())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -346,6 +342,10 @@ impl<V: 'static> Element<V> for InteractiveText {
|
|||
impl<V: 'static> RenderOnce<V> for InteractiveText {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.id.clone())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -104,10 +104,6 @@ pub struct UniformListState {
|
|||
impl<V: 'static> Element<V> for UniformList<V> {
|
||||
type State = UniformListState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
Some(self.id.clone())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -255,6 +251,10 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
|||
impl<V> RenderOnce<V> for UniformList<V> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
Some(self.id.clone())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -208,10 +208,6 @@ impl<V: 'static + Render<V>> From<View<V>> for AnyView {
|
|||
impl<V: 'static + Render<V>, ParentV: 'static> Element<ParentV> for View<V> {
|
||||
type State = Option<AnyElement<V>>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.model.entity_id.into())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_parent_view: &mut ParentV,
|
||||
|
@ -241,6 +237,10 @@ impl<V: 'static + Render<V>, ParentV: 'static> Element<ParentV> for View<V> {
|
|||
impl<V: 'static + Render<V>, ParentV: 'static> RenderOnce<ParentV> for View<V> {
|
||||
type Element = View<V>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.model.entity_id.into())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -249,10 +249,6 @@ impl<V: 'static + Render<V>, ParentV: 'static> RenderOnce<ParentV> for View<V> {
|
|||
impl<V: 'static> Element<V> for AnyView {
|
||||
type State = Option<Box<dyn Any>>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.model.entity_id.into())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view_state: &mut V,
|
||||
|
@ -277,6 +273,10 @@ impl<V: 'static> Element<V> for AnyView {
|
|||
impl<ParentV: 'static> RenderOnce<ParentV> for AnyView {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.model.entity_id.into())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -334,10 +334,6 @@ where
|
|||
{
|
||||
type State = Option<AnyElement<V>>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.view.entity_id().into())
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut ParentV,
|
||||
|
@ -371,6 +367,10 @@ where
|
|||
{
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.as_ref().unwrap().element_id()
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ pub fn derive_render_once(input: TokenStream) -> TokenStream {
|
|||
{
|
||||
type Element = gpui::CompositeElement<#view_type, Self>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
gpui::CompositeElement::new(self)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use editor::Editor;
|
||||
use gpui::{
|
||||
div, prelude::*, uniform_list, AppContext, Component, Div, FocusHandle, FocusableView,
|
||||
MouseButton, Render, Task, UniformListScrollHandle, View, ViewContext, WindowContext,
|
||||
div, prelude::*, uniform_list, AppContext, Div, FocusHandle, FocusableView, MouseButton,
|
||||
Render, Task, UniformListScrollHandle, View, ViewContext, WindowContext,
|
||||
};
|
||||
use std::{cmp, sync::Arc};
|
||||
use ui::{prelude::*, v_stack, Divider, Label, TextColor};
|
||||
|
@ -15,7 +15,7 @@ pub struct Picker<D: PickerDelegate> {
|
|||
}
|
||||
|
||||
pub trait PickerDelegate: Sized + 'static {
|
||||
type ListItem: Component<Picker<Self>>;
|
||||
type ListItem: RenderOnce<Picker<Self>>;
|
||||
|
||||
fn match_count(&self) -> usize;
|
||||
fn selected_index(&self) -> usize;
|
||||
|
@ -180,7 +180,7 @@ impl<D: PickerDelegate> Picker<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: PickerDelegate> Render for Picker<D> {
|
||||
impl<D: PickerDelegate> Render<Self> for Picker<D> {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -9,9 +9,9 @@ use file_associations::FileAssociations;
|
|||
use anyhow::{anyhow, Result};
|
||||
use gpui::{
|
||||
actions, div, px, uniform_list, Action, AppContext, AssetSource, AsyncWindowContext,
|
||||
ClipboardItem, Component, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
|
||||
InteractiveElement, Model, MouseButton, ParentElement, Pixels, Point, PromptLevel, Render,
|
||||
Stateful, StatefulInteractiveElement, Styled, Task, UniformListScrollHandle, View, ViewContext,
|
||||
ClipboardItem, Div, EventEmitter, FocusHandle, Focusable, FocusableView, InteractiveElement,
|
||||
Model, MouseButton, ParentElement, Pixels, Point, PromptLevel, Render, RenderOnce, Stateful,
|
||||
StatefulInteractiveElement, Styled, Task, UniformListScrollHandle, View, ViewContext,
|
||||
VisualContext as _, WeakView, WindowContext,
|
||||
};
|
||||
use menu::{Confirm, SelectNext, SelectPrev};
|
||||
|
@ -1423,7 +1423,7 @@ impl ProjectPanel {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for ProjectPanel {
|
||||
impl Render<Self> for ProjectPanel {
|
||||
type Element = Focusable<Self, Stateful<Self, Div<Self>>>;
|
||||
|
||||
fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -5,7 +5,7 @@ use ui::prelude::*;
|
|||
|
||||
pub struct ColorsStory;
|
||||
|
||||
impl Render for ColorsStory {
|
||||
impl Render<Self> for ColorsStory {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
@ -28,7 +28,7 @@ impl Render for ColorsStory {
|
|||
div()
|
||||
.w(px(75.))
|
||||
.line_height(px(24.))
|
||||
.child(scale.name().to_string()),
|
||||
.child(scale.name().clone()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
|
|
|
@ -26,7 +26,7 @@ impl FocusStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for FocusStory {
|
||||
impl Render<Self> for FocusStory {
|
||||
type Element = Focusable<Self, Stateful<Self, Div<Self>>>;
|
||||
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -11,7 +11,7 @@ impl KitchenSinkStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for KitchenSinkStory {
|
||||
impl Render<Self> for KitchenSinkStory {
|
||||
type Element = Stateful<Self, Div<Self>>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use fuzzy::StringMatchCandidate;
|
||||
use gpui::{div, prelude::*, Div, KeyBinding, Render, Styled, Task, View, WindowContext};
|
||||
use gpui::{
|
||||
div, prelude::*, Div, KeyBinding, Render, SharedString, Styled, Task, View, WindowContext,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use std::sync::Arc;
|
||||
use theme2::ActiveTheme;
|
||||
|
@ -54,7 +56,8 @@ impl PickerDelegate for Delegate {
|
|||
let Some(candidate_ix) = self.matches.get(ix) else {
|
||||
return div();
|
||||
};
|
||||
let candidate = self.candidates[*candidate_ix].string.clone();
|
||||
// TASK: Make StringMatchCandidate::string a SharedString
|
||||
let candidate = SharedString::from(self.candidates[*candidate_ix].string.clone());
|
||||
|
||||
div()
|
||||
.text_color(colors.text)
|
||||
|
@ -202,7 +205,7 @@ impl PickerStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for PickerStory {
|
||||
impl Render<Self> for PickerStory {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -10,7 +10,7 @@ impl ScrollStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for ScrollStory {
|
||||
impl Render<Self> for ScrollStory {
|
||||
type Element = Stateful<Self, Div<Self>>;
|
||||
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use gpui::{
|
||||
div, white, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext,
|
||||
};
|
||||
use gpui::{div, white, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext};
|
||||
|
||||
pub struct TextStory;
|
||||
|
||||
|
@ -10,7 +8,7 @@ impl TextStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for TextStory {
|
||||
impl Render<Self> for TextStory {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use gpui::{px, rgb, Div, Hsla, Render};
|
||||
use gpui::{px, rgb, Div, Hsla, Render, RenderOnce};
|
||||
use ui::prelude::*;
|
||||
|
||||
use crate::story::Story;
|
||||
|
@ -7,7 +7,7 @@ use crate::story::Story;
|
|||
/// [https://developer.mozilla.org/en-US/docs/Web/CSS/z-index](https://developer.mozilla.org/en-US/docs/Web/CSS/z-index).
|
||||
pub struct ZIndexStory;
|
||||
|
||||
impl Render for ZIndexStory {
|
||||
impl Render<Self> for ZIndexStory {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
@ -79,17 +79,15 @@ trait Styles: Styled + Sized {
|
|||
|
||||
impl<V: 'static> Styles for Div<V> {}
|
||||
|
||||
// #[derive(RenderOnce)]
|
||||
#[derive(RenderOnce)]
|
||||
struct ZIndexExample {
|
||||
z_index: u32,
|
||||
}
|
||||
|
||||
impl ZIndexExample {
|
||||
pub fn new(z_index: u32) -> Self {
|
||||
Self { z_index }
|
||||
}
|
||||
impl<V: 'static> Component<V> for ZIndexExample {
|
||||
type Rendered = Div<V>;
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
|
||||
div()
|
||||
.relative()
|
||||
.size_full()
|
||||
|
@ -109,14 +107,14 @@ impl ZIndexExample {
|
|||
// HACK: Simulate `text-align: center`.
|
||||
.pl(px(24.))
|
||||
.z_index(self.z_index)
|
||||
.child(format!(
|
||||
.child(SharedString::from(format!(
|
||||
"z-index: {}",
|
||||
if self.z_index == 0 {
|
||||
"auto".to_string()
|
||||
} else {
|
||||
self.z_index.to_string()
|
||||
}
|
||||
)),
|
||||
))),
|
||||
)
|
||||
// Blue blocks.
|
||||
.child(
|
||||
|
@ -173,3 +171,9 @@ impl ZIndexExample {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ZIndexExample {
|
||||
pub fn new(z_index: u32) -> Self {
|
||||
Self { z_index }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ impl StoryWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for StoryWrapper {
|
||||
impl Render<Self> for StoryWrapper {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -335,7 +335,7 @@ impl TerminalPanel {
|
|||
|
||||
impl EventEmitter<PanelEvent> for TerminalPanel {}
|
||||
|
||||
impl Render for TerminalPanel {
|
||||
impl Render<Self> for TerminalPanel {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
|
|
@ -9,7 +9,7 @@ pub mod terminal_panel;
|
|||
// use crate::terminal_element::TerminalElement;
|
||||
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
||||
use gpui::{
|
||||
actions, div, img, red, Action, AnyElement, AppContext, Component, DispatchPhase, Div,
|
||||
actions, div, img, red, Action, AnyElement, AppContext, DispatchPhase, Div, Element,
|
||||
EventEmitter, FocusEvent, FocusHandle, Focusable, FocusableElement, FocusableView,
|
||||
InputHandler, InteractiveElement, KeyDownEvent, Keystroke, Model, MouseButton, ParentElement,
|
||||
Pixels, Render, SharedString, Styled, Task, View, ViewContext, VisualContext, WeakView,
|
||||
|
@ -538,7 +538,7 @@ impl TerminalView {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for TerminalView {
|
||||
impl Render<Self> for TerminalView {
|
||||
type Element = Focusable<Self, Div<Self>>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
|
@ -578,7 +578,7 @@ impl Render for TerminalView {
|
|||
.children(
|
||||
self.context_menu
|
||||
.clone()
|
||||
.map(|context_menu| div().z_index(1).absolute().child(context_menu.render())),
|
||||
.map(|context_menu| div().z_index(1).absolute().child(context_menu)),
|
||||
)
|
||||
.track_focus(&self.focus_handle)
|
||||
.on_focus_in(Self::focus_in)
|
||||
|
@ -756,8 +756,8 @@ impl Item for TerminalView {
|
|||
|
||||
div()
|
||||
.child(img().uri("icons/terminal.svg").bg(red()))
|
||||
.child(title)
|
||||
.render()
|
||||
.child(SharedString::from(title))
|
||||
.into_any()
|
||||
}
|
||||
|
||||
fn clone_on_split(
|
||||
|
|
|
@ -78,7 +78,7 @@ impl Render<Self> for ContextMenu {
|
|||
}
|
||||
|
||||
pub struct MenuHandle<V: 'static, M: ManagedView> {
|
||||
id: Option<ElementId>,
|
||||
id: ElementId,
|
||||
child_builder: Option<Box<dyn FnOnce(bool) -> AnyElement<V> + 'static>>,
|
||||
menu_builder: Option<Rc<dyn Fn(&mut V, &mut ViewContext<V>) -> View<M> + 'static>>,
|
||||
|
||||
|
@ -87,11 +87,6 @@ pub struct MenuHandle<V: 'static, M: ManagedView> {
|
|||
}
|
||||
|
||||
impl<V: 'static, M: ManagedView> MenuHandle<V, M> {
|
||||
pub fn id(mut self, id: impl Into<ElementId>) -> Self {
|
||||
self.id = Some(id.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn menu(mut self, f: impl Fn(&mut V, &mut ViewContext<V>) -> View<M> + 'static) -> Self {
|
||||
self.menu_builder = Some(Rc::new(f));
|
||||
self
|
||||
|
@ -116,9 +111,9 @@ impl<V: 'static, M: ManagedView> MenuHandle<V, M> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn menu_handle<V: 'static, M: ManagedView>() -> MenuHandle<V, M> {
|
||||
pub fn menu_handle<V: 'static, M: ManagedView>(id: impl Into<ElementId>) -> MenuHandle<V, M> {
|
||||
MenuHandle {
|
||||
id: None,
|
||||
id: id.into(),
|
||||
child_builder: None,
|
||||
menu_builder: None,
|
||||
anchor: None,
|
||||
|
@ -136,10 +131,6 @@ pub struct MenuHandleState<V, M> {
|
|||
impl<V: 'static, M: ManagedView> Element<V> for MenuHandle<V, M> {
|
||||
type State = MenuHandleState<V, M>;
|
||||
|
||||
fn element_id(&self) -> Option<gpui::ElementId> {
|
||||
Some(self.id.clone().expect("menu_handle must have an id()"))
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
|
@ -251,6 +242,10 @@ impl<V: 'static, M: ManagedView> Element<V> for MenuHandle<V, M> {
|
|||
impl<V: 'static, M: ManagedView> RenderOnce<V> for MenuHandle<V, M> {
|
||||
type Element = Self;
|
||||
|
||||
fn element_id(&self) -> Option<gpui::ElementId> {
|
||||
Some(self.id.clone())
|
||||
}
|
||||
|
||||
fn render_once(self) -> Self::Element {
|
||||
self
|
||||
}
|
||||
|
@ -297,8 +292,7 @@ mod stories {
|
|||
.flex_col()
|
||||
.justify_between()
|
||||
.child(
|
||||
menu_handle()
|
||||
.id("test2")
|
||||
menu_handle("test2")
|
||||
.child(|is_open| {
|
||||
Label::new(if is_open {
|
||||
"TOP LEFT"
|
||||
|
@ -309,8 +303,7 @@ mod stories {
|
|||
.menu(move |_, cx| build_menu(cx, "top left")),
|
||||
)
|
||||
.child(
|
||||
menu_handle()
|
||||
.id("test1")
|
||||
menu_handle("test1")
|
||||
.child(|is_open| {
|
||||
Label::new(if is_open {
|
||||
"BOTTOM LEFT"
|
||||
|
@ -329,8 +322,7 @@ mod stories {
|
|||
.flex_col()
|
||||
.justify_between()
|
||||
.child(
|
||||
menu_handle()
|
||||
.id("test3")
|
||||
menu_handle("test3")
|
||||
.child(|is_open| {
|
||||
Label::new(if is_open {
|
||||
"TOP RIGHT"
|
||||
|
@ -342,8 +334,7 @@ mod stories {
|
|||
.menu(move |_, cx| build_menu(cx, "top right")),
|
||||
)
|
||||
.child(
|
||||
menu_handle()
|
||||
.id("test4")
|
||||
menu_handle("test4")
|
||||
.child(|is_open| {
|
||||
Label::new(if is_open {
|
||||
"BOTTOM RIGHT"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use gpui::RenderOnce;
|
||||
use gpui::{Div, RenderOnce};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
@ -7,12 +7,29 @@ enum DividerDirection {
|
|||
Vertical,
|
||||
}
|
||||
|
||||
// #[derive(RenderOnce)]
|
||||
#[derive(RenderOnce)]
|
||||
pub struct Divider {
|
||||
direction: DividerDirection,
|
||||
inset: bool,
|
||||
}
|
||||
|
||||
impl<V: 'static> Component<V> for Divider {
|
||||
type Rendered = Div<V>;
|
||||
|
||||
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
|
||||
div()
|
||||
.map(|this| match self.direction {
|
||||
DividerDirection::Horizontal => {
|
||||
this.h_px().w_full().when(self.inset, |this| this.mx_1p5())
|
||||
}
|
||||
DividerDirection::Vertical => {
|
||||
this.w_px().h_full().when(self.inset, |this| this.my_1p5())
|
||||
}
|
||||
})
|
||||
.bg(cx.theme().colors().border_variant)
|
||||
}
|
||||
}
|
||||
|
||||
impl Divider {
|
||||
pub fn horizontal() -> Self {
|
||||
Self {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{status_bar::StatusItemView, Axis, Workspace};
|
||||
use gpui::{
|
||||
div, px, Action, AnchorCorner, AnyView, AppContext, Component, Div, Entity, EntityId,
|
||||
EventEmitter, FocusHandle, FocusableView, ParentElement, Render, RenderOnce, SharedString,
|
||||
Styled, Subscription, View, ViewContext, VisualContext, WeakView, WindowContext,
|
||||
div, px, Action, AnchorCorner, AnyView, AppContext, Div, Entity, EntityId, EventEmitter,
|
||||
FocusHandle, FocusableView, ParentElement, Render, RenderOnce, SharedString, Styled,
|
||||
Subscription, View, ViewContext, VisualContext, WeakView, WindowContext,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -653,8 +653,7 @@ impl Render<Self> for PanelButtons {
|
|||
};
|
||||
|
||||
Some(
|
||||
menu_handle()
|
||||
.id(name)
|
||||
menu_handle(name)
|
||||
.menu(move |_, cx| {
|
||||
cx.build_view(|cx| ContextMenu::new(cx).header("SECTION"))
|
||||
})
|
||||
|
|
|
@ -7,9 +7,9 @@ use crate::{
|
|||
use anyhow::Result;
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
use gpui::{
|
||||
actions, prelude::*, Action, AppContext, AsyncWindowContext, Component, Div, EntityId,
|
||||
EventEmitter, FocusHandle, Focusable, FocusableView, Model, Pixels, Point, PromptLevel, Render,
|
||||
Task, View, ViewContext, VisualContext, WeakView, WindowContext,
|
||||
actions, prelude::*, Action, AppContext, AsyncWindowContext, Div, EntityId, EventEmitter,
|
||||
FocusHandle, Focusable, FocusableView, Model, Pixels, Point, PromptLevel, Render, Task, View,
|
||||
ViewContext, VisualContext, WeakView, WindowContext,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use project2::{Project, ProjectEntryId, ProjectPath};
|
||||
|
|
|
@ -7,8 +7,7 @@ use db2::sqlez::{
|
|||
statement::Statement,
|
||||
};
|
||||
use gpui::{
|
||||
point, size, AnyElement, AnyWeakView, Bounds, Div, Model, Pixels, Point, RenderOnce, View,
|
||||
ViewContext,
|
||||
point, size, AnyWeakView, Bounds, Div, Model, Pixels, Point, RenderOnce, View, ViewContext,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use project2::Project;
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::any::TypeId;
|
|||
|
||||
use crate::{ItemHandle, Pane};
|
||||
use gpui::{
|
||||
div, AnyView, Component, Div, ParentElement, Render, RenderOnce, Styled, Subscription, View,
|
||||
ViewContext, WindowContext,
|
||||
div, AnyView, Div, ParentElement, Render, RenderOnce, Styled, Subscription, View, ViewContext,
|
||||
WindowContext,
|
||||
};
|
||||
use theme2::ActiveTheme;
|
||||
use ui::h_stack;
|
||||
|
|
Loading…
Reference in a new issue