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