Merge pull request #1749 from zed-industries/child-view-panic
Prevent `ChildView` from retaining an otherwise dropped view
This commit is contained in:
commit
f5db02a605
29 changed files with 215 additions and 76 deletions
|
@ -200,7 +200,7 @@ impl ChatPanel {
|
|||
let theme = &cx.global::<Settings>().theme;
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Container::new(ChildView::new(&self.channel_select).boxed())
|
||||
Container::new(ChildView::new(&self.channel_select, cx).boxed())
|
||||
.with_style(theme.chat_panel.channel_select.container)
|
||||
.boxed(),
|
||||
)
|
||||
|
@ -265,7 +265,7 @@ impl ChatPanel {
|
|||
|
||||
fn render_input_box(&self, cx: &AppContext) -> ElementBox {
|
||||
let theme = &cx.global::<Settings>().theme;
|
||||
Container::new(ChildView::new(&self.input_editor).boxed())
|
||||
Container::new(ChildView::new(&self.input_editor, cx).boxed())
|
||||
.with_style(theme.chat_panel.input_editor.container)
|
||||
.boxed()
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ use gpui::{
|
|||
};
|
||||
use language::{
|
||||
range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
|
||||
LanguageConfig, LanguageRegistry, OffsetRangeExt, Rope, Point,
|
||||
LanguageConfig, LanguageRegistry, OffsetRangeExt, Point, Rope,
|
||||
};
|
||||
use lsp::{self, FakeLanguageServer};
|
||||
use parking_lot::Mutex;
|
||||
|
|
|
@ -223,7 +223,7 @@ impl CollabTitlebarItem {
|
|||
.with_children(badge)
|
||||
.with_children(self.contacts_popover.as_ref().map(|popover| {
|
||||
Overlay::new(
|
||||
ChildView::new(popover)
|
||||
ChildView::new(popover, cx)
|
||||
.contained()
|
||||
.with_margin_top(titlebar.height)
|
||||
.with_margin_left(titlebar.toggle_contacts_button.default.button_width)
|
||||
|
|
|
@ -32,8 +32,8 @@ impl View for ContactFinder {
|
|||
"ContactFinder"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone()).boxed()
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone(), cx).boxed()
|
||||
}
|
||||
|
||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -1072,7 +1072,7 @@ impl View for ContactList {
|
|||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(
|
||||
ChildView::new(self.filter_editor.clone())
|
||||
ChildView::new(self.filter_editor.clone(), cx)
|
||||
.contained()
|
||||
.with_style(theme.contact_list.user_query_editor.container)
|
||||
.flex(1., true)
|
||||
|
|
|
@ -88,8 +88,8 @@ impl View for ContactsPopover {
|
|||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = cx.global::<Settings>().theme.clone();
|
||||
let child = match &self.child {
|
||||
Child::ContactList(child) => ChildView::new(child),
|
||||
Child::ContactFinder(child) => ChildView::new(child),
|
||||
Child::ContactList(child) => ChildView::new(child, cx),
|
||||
Child::ContactFinder(child) => ChildView::new(child, cx),
|
||||
};
|
||||
|
||||
MouseEventHandler::<ContactsPopover>::new(0, cx, |_, cx| {
|
||||
|
|
|
@ -4,8 +4,8 @@ use gpui::{
|
|||
actions,
|
||||
elements::{ChildView, Flex, Label, ParentElement},
|
||||
keymap::Keystroke,
|
||||
Action, AnyViewHandle, Element, Entity, MouseState, MutableAppContext, View, ViewContext,
|
||||
ViewHandle,
|
||||
Action, AnyViewHandle, Element, Entity, MouseState, MutableAppContext, RenderContext, View,
|
||||
ViewContext, ViewHandle,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use settings::Settings;
|
||||
|
@ -131,8 +131,8 @@ impl View for CommandPalette {
|
|||
"CommandPalette"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox {
|
||||
ChildView::new(self.picker.clone()).boxed()
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
|
||||
ChildView::new(self.picker.clone(), cx).boxed()
|
||||
}
|
||||
|
||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -95,7 +95,7 @@ impl View for ProjectDiagnosticsEditor {
|
|||
.with_style(theme.container)
|
||||
.boxed()
|
||||
} else {
|
||||
ChildView::new(&self.editor).boxed()
|
||||
ChildView::new(&self.editor, cx).boxed()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5206,7 +5206,7 @@ impl Editor {
|
|||
render: Arc::new({
|
||||
let editor = rename_editor.clone();
|
||||
move |cx: &mut BlockContext| {
|
||||
ChildView::new(editor.clone())
|
||||
ChildView::new(editor.clone(), cx)
|
||||
.contained()
|
||||
.with_padding_left(cx.anchor_x)
|
||||
.boxed()
|
||||
|
@ -6270,7 +6270,7 @@ impl View for Editor {
|
|||
.with_child(
|
||||
EditorElement::new(self.handle.clone(), style.clone(), self.cursor_shape).boxed(),
|
||||
)
|
||||
.with_child(ChildView::new(&self.mouse_context_menu).boxed())
|
||||
.with_child(ChildView::new(&self.mouse_context_menu, cx).boxed())
|
||||
.boxed()
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ impl View for FileFinder {
|
|||
"FileFinder"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone()).boxed()
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone(), cx).boxed()
|
||||
}
|
||||
|
||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -165,7 +165,7 @@ impl View for GoToLine {
|
|||
Container::new(
|
||||
Flex::new(Axis::Vertical)
|
||||
.with_child(
|
||||
Container::new(ChildView::new(&self.line_editor).boxed())
|
||||
Container::new(ChildView::new(&self.line_editor, cx).boxed())
|
||||
.with_style(theme.input_editor.container)
|
||||
.boxed(),
|
||||
)
|
||||
|
|
|
@ -2571,6 +2571,10 @@ impl AppContext {
|
|||
.and_then(|window| window.focused_view_id)
|
||||
}
|
||||
|
||||
pub fn view_ui_name(&self, window_id: usize, view_id: usize) -> Option<&'static str> {
|
||||
Some(self.views.get(&(window_id, view_id))?.ui_name())
|
||||
}
|
||||
|
||||
pub fn background(&self) -> &Arc<executor::Background> {
|
||||
&self.background
|
||||
}
|
||||
|
@ -4416,6 +4420,10 @@ impl AnyViewHandle {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn window_id(&self) -> usize {
|
||||
self.window_id
|
||||
}
|
||||
|
||||
pub fn id(&self) -> usize {
|
||||
self.view_id
|
||||
}
|
||||
|
@ -4732,6 +4740,10 @@ pub struct AnyWeakViewHandle {
|
|||
}
|
||||
|
||||
impl AnyWeakViewHandle {
|
||||
pub fn id(&self) -> usize {
|
||||
self.view_id
|
||||
}
|
||||
|
||||
pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
|
||||
cx.upgrade_any_view_handle(self)
|
||||
}
|
||||
|
@ -7032,4 +7044,73 @@ mod tests {
|
|||
cx.simulate_window_activation(Some(window_3));
|
||||
assert_eq!(mem::take(&mut *events.borrow_mut()), []);
|
||||
}
|
||||
|
||||
#[crate::test(self)]
|
||||
fn test_child_view(cx: &mut MutableAppContext) {
|
||||
struct Child {
|
||||
rendered: Rc<Cell<bool>>,
|
||||
dropped: Rc<Cell<bool>>,
|
||||
}
|
||||
|
||||
impl super::Entity for Child {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl super::View for Child {
|
||||
fn ui_name() -> &'static str {
|
||||
"child view"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
self.rendered.set(true);
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Child {
|
||||
fn drop(&mut self) {
|
||||
self.dropped.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
struct Parent {
|
||||
child: Option<ViewHandle<Child>>,
|
||||
}
|
||||
|
||||
impl super::Entity for Parent {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
impl super::View for Parent {
|
||||
fn ui_name() -> &'static str {
|
||||
"parent view"
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
if let Some(child) = self.child.as_ref() {
|
||||
ChildView::new(child, cx).boxed()
|
||||
} else {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let child_rendered = Rc::new(Cell::new(false));
|
||||
let child_dropped = Rc::new(Cell::new(false));
|
||||
let (_, root_view) = cx.add_window(Default::default(), |cx| Parent {
|
||||
child: Some(cx.add_view(|_| Child {
|
||||
rendered: child_rendered.clone(),
|
||||
dropped: child_dropped.clone(),
|
||||
})),
|
||||
});
|
||||
assert!(child_rendered.take());
|
||||
assert!(!child_dropped.take());
|
||||
|
||||
root_view.update(cx, |view, cx| {
|
||||
view.child.take();
|
||||
cx.notify();
|
||||
});
|
||||
assert!(!child_rendered.take());
|
||||
assert!(child_dropped.take());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ use crate::{
|
|||
UpOutRegionEvent, UpRegionEvent,
|
||||
},
|
||||
text_layout::TextLayoutCache,
|
||||
Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, Appearance, AssetCache, ElementBox,
|
||||
Entity, FontSystem, ModelHandle, MouseButton, MouseMovedEvent, MouseRegion, MouseRegionId,
|
||||
ParentId, ReadModel, ReadView, RenderContext, RenderParams, Scene, UpgradeModelHandle,
|
||||
UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle,
|
||||
Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, Appearance,
|
||||
AssetCache, ElementBox, Entity, FontSystem, ModelHandle, MouseButton, MouseMovedEvent,
|
||||
MouseRegion, MouseRegionId, ParentId, ReadModel, ReadView, RenderContext, RenderParams, Scene,
|
||||
UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle,
|
||||
};
|
||||
use collections::{HashMap, HashSet};
|
||||
use pathfinder_geometry::vector::{vec2f, Vector2F};
|
||||
|
@ -972,17 +972,23 @@ impl ToJson for SizeConstraint {
|
|||
}
|
||||
|
||||
pub struct ChildView {
|
||||
view: AnyViewHandle,
|
||||
view: AnyWeakViewHandle,
|
||||
view_name: &'static str,
|
||||
}
|
||||
|
||||
impl ChildView {
|
||||
pub fn new(view: impl Into<AnyViewHandle>) -> Self {
|
||||
Self { view: view.into() }
|
||||
pub fn new(view: impl Into<AnyViewHandle>, cx: &AppContext) -> Self {
|
||||
let view = view.into();
|
||||
let view_name = cx.view_ui_name(view.window_id(), view.id()).unwrap();
|
||||
Self {
|
||||
view: view.downgrade(),
|
||||
view_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for ChildView {
|
||||
type LayoutState = ();
|
||||
type LayoutState = bool;
|
||||
type PaintState = ();
|
||||
|
||||
fn layout(
|
||||
|
@ -990,18 +996,35 @@ impl Element for ChildView {
|
|||
constraint: SizeConstraint,
|
||||
cx: &mut LayoutContext,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let size = cx.layout(self.view.id(), constraint);
|
||||
(size, ())
|
||||
if cx.rendered_views.contains_key(&self.view.id()) {
|
||||
let size = cx.layout(self.view.id(), constraint);
|
||||
(size, true)
|
||||
} else {
|
||||
log::error!(
|
||||
"layout called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
|
||||
self.view.id(),
|
||||
self.view_name
|
||||
);
|
||||
(Vector2F::zero(), false)
|
||||
}
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
view_is_valid: &mut Self::LayoutState,
|
||||
cx: &mut PaintContext,
|
||||
) -> Self::PaintState {
|
||||
cx.paint(self.view.id(), bounds.origin(), visible_bounds);
|
||||
) {
|
||||
if *view_is_valid {
|
||||
cx.paint(self.view.id(), bounds.origin(), visible_bounds);
|
||||
} else {
|
||||
log::error!(
|
||||
"paint called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
|
||||
self.view.id(),
|
||||
self.view_name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch_event(
|
||||
|
@ -1009,11 +1032,20 @@ impl Element for ChildView {
|
|||
event: &Event,
|
||||
_: RectF,
|
||||
_: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
view_is_valid: &mut Self::LayoutState,
|
||||
_: &mut Self::PaintState,
|
||||
cx: &mut EventContext,
|
||||
) -> bool {
|
||||
cx.dispatch_event(self.view.id(), event)
|
||||
if *view_is_valid {
|
||||
cx.dispatch_event(self.view.id(), event)
|
||||
} else {
|
||||
log::error!(
|
||||
"dispatch_event called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
|
||||
self.view.id(),
|
||||
self.view_name
|
||||
);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn rect_for_text_range(
|
||||
|
@ -1021,11 +1053,20 @@ impl Element for ChildView {
|
|||
range_utf16: Range<usize>,
|
||||
_: RectF,
|
||||
_: RectF,
|
||||
_: &Self::LayoutState,
|
||||
view_is_valid: &Self::LayoutState,
|
||||
_: &Self::PaintState,
|
||||
cx: &MeasurementContext,
|
||||
) -> Option<RectF> {
|
||||
cx.rect_for_text_range(self.view.id(), range_utf16)
|
||||
if *view_is_valid {
|
||||
cx.rect_for_text_range(self.view.id(), range_utf16)
|
||||
} else {
|
||||
log::error!(
|
||||
"rect_for_text_range called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
|
||||
self.view.id(),
|
||||
self.view_name
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn debug(
|
||||
|
@ -1039,7 +1080,11 @@ impl Element for ChildView {
|
|||
"type": "ChildView",
|
||||
"view_id": self.view.id(),
|
||||
"bounds": bounds.to_json(),
|
||||
"view": self.view.debug_json(cx.app),
|
||||
"view": if let Some(view) = self.view.upgrade(cx.app) {
|
||||
view.debug_json(cx.app)
|
||||
} else {
|
||||
json!(null)
|
||||
},
|
||||
"child": if let Some(view) = cx.rendered_views.get(&self.view.id()) {
|
||||
view.debug(cx)
|
||||
} else {
|
||||
|
|
|
@ -48,8 +48,8 @@ impl View for OutlineView {
|
|||
"OutlineView"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone()).boxed()
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone(), cx).boxed()
|
||||
}
|
||||
|
||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -63,7 +63,7 @@ impl<D: PickerDelegate> View for Picker<D> {
|
|||
|
||||
Flex::new(Axis::Vertical)
|
||||
.with_child(
|
||||
ChildView::new(&self.query_editor)
|
||||
ChildView::new(&self.query_editor, cx)
|
||||
.contained()
|
||||
.with_style(theme.input_editor.container)
|
||||
.boxed(),
|
||||
|
|
|
@ -1012,7 +1012,7 @@ impl ProjectPanel {
|
|||
) -> ElementBox {
|
||||
let kind = details.kind;
|
||||
let show_editor = details.is_editing && !details.is_processing;
|
||||
MouseEventHandler::<Self>::new(entry_id.to_usize(), cx, |state, _| {
|
||||
MouseEventHandler::<Self>::new(entry_id.to_usize(), cx, |state, cx| {
|
||||
let padding = theme.container.padding.left + details.depth as f32 * theme.indent_width;
|
||||
let mut style = theme.entry.style_for(state, details.is_selected).clone();
|
||||
if details.is_ignored {
|
||||
|
@ -1051,7 +1051,7 @@ impl ProjectPanel {
|
|||
.boxed(),
|
||||
)
|
||||
.with_child(if show_editor {
|
||||
ChildView::new(editor.clone())
|
||||
ChildView::new(editor.clone(), cx)
|
||||
.contained()
|
||||
.with_margin_left(theme.entry.default.icon_spacing)
|
||||
.aligned()
|
||||
|
@ -1147,7 +1147,7 @@ impl View for ProjectPanel {
|
|||
})
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(ChildView::new(&self.context_menu).boxed())
|
||||
.with_child(ChildView::new(&self.context_menu, cx).boxed())
|
||||
.boxed()
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ impl View for ProjectSymbolsView {
|
|||
"ProjectSymbolsView"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone()).boxed()
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone(), cx).boxed()
|
||||
}
|
||||
|
||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -105,7 +105,7 @@ impl View for BufferSearchBar {
|
|||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(
|
||||
ChildView::new(&self.query_editor)
|
||||
ChildView::new(&self.query_editor, cx)
|
||||
.aligned()
|
||||
.left()
|
||||
.flex(1., true)
|
||||
|
|
|
@ -189,7 +189,9 @@ impl View for ProjectSearchView {
|
|||
})
|
||||
.boxed()
|
||||
} else {
|
||||
ChildView::new(&self.results_editor).flex(1., true).boxed()
|
||||
ChildView::new(&self.results_editor, cx)
|
||||
.flex(1., true)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -824,7 +826,7 @@ impl View for ProjectSearchBar {
|
|||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(
|
||||
ChildView::new(&search.query_editor)
|
||||
ChildView::new(&search.query_editor, cx)
|
||||
.aligned()
|
||||
.left()
|
||||
.flex(1., true)
|
||||
|
|
|
@ -162,8 +162,8 @@ impl View for TerminalContainer {
|
|||
|
||||
fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox {
|
||||
let child_view = match &self.content {
|
||||
TerminalContainerContent::Connected(connected) => ChildView::new(connected),
|
||||
TerminalContainerContent::Error(error) => ChildView::new(error),
|
||||
TerminalContainerContent::Connected(connected) => ChildView::new(connected, cx),
|
||||
TerminalContainerContent::Error(error) => ChildView::new(error, cx),
|
||||
};
|
||||
if self.modal {
|
||||
let settings = cx.global::<Settings>();
|
||||
|
|
|
@ -339,7 +339,7 @@ impl View for TerminalView {
|
|||
.contained()
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(ChildView::new(&self.context_menu).boxed())
|
||||
.with_child(ChildView::new(&self.context_menu, cx).boxed())
|
||||
.boxed()
|
||||
}
|
||||
|
||||
|
|
|
@ -262,8 +262,8 @@ impl View for ThemeSelector {
|
|||
"ThemeSelector"
|
||||
}
|
||||
|
||||
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone()).boxed()
|
||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
ChildView::new(self.picker.clone(), cx).boxed()
|
||||
}
|
||||
|
||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -255,7 +255,7 @@ impl Dock {
|
|||
|
||||
enum DockResizeHandle {}
|
||||
|
||||
let resizable = Container::new(ChildView::new(self.pane.clone()).boxed())
|
||||
let resizable = Container::new(ChildView::new(self.pane.clone(), cx).boxed())
|
||||
.with_style(panel_style)
|
||||
.with_resize_handle::<DockResizeHandle, _>(
|
||||
resize_side as usize,
|
||||
|
@ -285,8 +285,8 @@ impl Dock {
|
|||
enum ExpandedDockPane {}
|
||||
Container::new(
|
||||
MouseEventHandler::<ExpandedDockWash>::new(0, cx, |_state, cx| {
|
||||
MouseEventHandler::<ExpandedDockPane>::new(0, cx, |_state, _cx| {
|
||||
ChildView::new(self.pane.clone()).boxed()
|
||||
MouseEventHandler::<ExpandedDockPane>::new(0, cx, |_state, cx| {
|
||||
ChildView::new(&self.pane, cx).boxed()
|
||||
})
|
||||
.capture_all()
|
||||
.contained()
|
||||
|
|
|
@ -1439,8 +1439,8 @@ impl View for Pane {
|
|||
.flex(1., false)
|
||||
.named("tab bar")
|
||||
})
|
||||
.with_child(ChildView::new(&self.toolbar).expanded().boxed())
|
||||
.with_child(ChildView::new(active_item).flex(1., true).boxed())
|
||||
.with_child(ChildView::new(&self.toolbar, cx).expanded().boxed())
|
||||
.with_child(ChildView::new(active_item, cx).flex(1., true).boxed())
|
||||
.boxed()
|
||||
} else {
|
||||
enum EmptyPane {}
|
||||
|
@ -1480,7 +1480,7 @@ impl View for Pane {
|
|||
})
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(ChildView::new(&self.tab_bar_context_menu).boxed())
|
||||
.with_child(ChildView::new(&self.tab_bar_context_menu, cx).boxed())
|
||||
.named("pane")
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,12 @@ impl Member {
|
|||
};
|
||||
|
||||
Stack::new()
|
||||
.with_child(ChildView::new(pane).contained().with_border(border).boxed())
|
||||
.with_child(
|
||||
ChildView::new(pane, cx)
|
||||
.contained()
|
||||
.with_border(border)
|
||||
.boxed(),
|
||||
)
|
||||
.with_children(prompt)
|
||||
.boxed()
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ impl View for Sidebar {
|
|||
if let Some(active_item) = self.active_item() {
|
||||
enum ResizeHandleTag {}
|
||||
let style = &cx.global::<Settings>().theme.workspace.sidebar;
|
||||
ChildView::new(active_item.to_any())
|
||||
ChildView::new(active_item.to_any(), cx)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.with_resize_handle::<ResizeHandleTag, _>(
|
||||
|
|
|
@ -42,14 +42,14 @@ impl View for StatusBar {
|
|||
let theme = &cx.global::<Settings>().theme.workspace.status_bar;
|
||||
Flex::row()
|
||||
.with_children(self.left_items.iter().map(|i| {
|
||||
ChildView::new(i.as_ref())
|
||||
ChildView::new(i.as_ref(), cx)
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_right(theme.item_spacing)
|
||||
.boxed()
|
||||
}))
|
||||
.with_children(self.right_items.iter().rev().map(|i| {
|
||||
ChildView::new(i.as_ref())
|
||||
ChildView::new(i.as_ref(), cx)
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_left(theme.item_spacing)
|
||||
|
|
|
@ -67,7 +67,7 @@ impl View for Toolbar {
|
|||
match *position {
|
||||
ToolbarItemLocation::Hidden => {}
|
||||
ToolbarItemLocation::PrimaryLeft { flex } => {
|
||||
let left_item = ChildView::new(item.as_ref())
|
||||
let left_item = ChildView::new(item.as_ref(), cx)
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_right(spacing);
|
||||
|
@ -78,7 +78,7 @@ impl View for Toolbar {
|
|||
}
|
||||
}
|
||||
ToolbarItemLocation::PrimaryRight { flex } => {
|
||||
let right_item = ChildView::new(item.as_ref())
|
||||
let right_item = ChildView::new(item.as_ref(), cx)
|
||||
.aligned()
|
||||
.contained()
|
||||
.with_margin_left(spacing)
|
||||
|
@ -91,7 +91,7 @@ impl View for Toolbar {
|
|||
}
|
||||
ToolbarItemLocation::Secondary => {
|
||||
secondary_item = Some(
|
||||
ChildView::new(item.as_ref())
|
||||
ChildView::new(item.as_ref(), cx)
|
||||
.constrained()
|
||||
.with_height(theme.height)
|
||||
.boxed(),
|
||||
|
|
|
@ -2126,7 +2126,7 @@ impl Workspace {
|
|||
|
||||
enum TitleBar {}
|
||||
ConstrainedBox::new(
|
||||
MouseEventHandler::<TitleBar>::new(0, cx, |_, _| {
|
||||
MouseEventHandler::<TitleBar>::new(0, cx, |_, cx| {
|
||||
Container::new(
|
||||
Stack::new()
|
||||
.with_child(
|
||||
|
@ -2138,7 +2138,7 @@ impl Workspace {
|
|||
.with_children(
|
||||
self.titlebar_item
|
||||
.as_ref()
|
||||
.map(|item| ChildView::new(item).aligned().right().boxed()),
|
||||
.map(|item| ChildView::new(item, cx).aligned().right().boxed()),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
|
@ -2231,14 +2231,18 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_notifications(&self, theme: &theme::Workspace) -> Option<ElementBox> {
|
||||
fn render_notifications(
|
||||
&self,
|
||||
theme: &theme::Workspace,
|
||||
cx: &AppContext,
|
||||
) -> Option<ElementBox> {
|
||||
if self.notifications.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
Flex::column()
|
||||
.with_children(self.notifications.iter().map(|(_, _, notification)| {
|
||||
ChildView::new(notification.as_ref())
|
||||
ChildView::new(notification.as_ref(), cx)
|
||||
.contained()
|
||||
.with_style(theme.notification)
|
||||
.boxed()
|
||||
|
@ -2570,7 +2574,7 @@ impl View for Workspace {
|
|||
.with_children(
|
||||
if self.left_sidebar.read(cx).active_item().is_some() {
|
||||
Some(
|
||||
ChildView::new(&self.left_sidebar)
|
||||
ChildView::new(&self.left_sidebar, cx)
|
||||
.flex(0.8, false)
|
||||
.boxed(),
|
||||
)
|
||||
|
@ -2606,7 +2610,7 @@ impl View for Workspace {
|
|||
.with_children(
|
||||
if self.right_sidebar.read(cx).active_item().is_some() {
|
||||
Some(
|
||||
ChildView::new(&self.right_sidebar)
|
||||
ChildView::new(&self.right_sidebar, cx)
|
||||
.flex(0.8, false)
|
||||
.boxed(),
|
||||
)
|
||||
|
@ -2624,15 +2628,17 @@ impl View for Workspace {
|
|||
DockAnchor::Expanded,
|
||||
cx,
|
||||
))
|
||||
.with_children(self.modal.as_ref().map(|m| {
|
||||
ChildView::new(m)
|
||||
.with_children(self.modal.as_ref().map(|modal| {
|
||||
ChildView::new(modal, cx)
|
||||
.contained()
|
||||
.with_style(theme.workspace.modal)
|
||||
.aligned()
|
||||
.top()
|
||||
.boxed()
|
||||
}))
|
||||
.with_children(self.render_notifications(&theme.workspace))
|
||||
.with_children(
|
||||
self.render_notifications(&theme.workspace, cx),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
|
@ -2640,7 +2646,7 @@ impl View for Workspace {
|
|||
.flex(1.0, true)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(ChildView::new(&self.status_bar).boxed())
|
||||
.with_child(ChildView::new(&self.status_bar, cx).boxed())
|
||||
.contained()
|
||||
.with_background_color(theme.workspace.background)
|
||||
.boxed(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue