@@ -0,0 +1,63 @@
+use crate::{AnyElement, Bounds, Element, ElementContext, IntoElement, LayoutId, Pixels};
+
+/// Builds a `Deferred` element, which delays the layout and paint of its child.
+pub fn deferred(child: impl IntoElement) -> Deferred {
+ Deferred {
+ child: Some(child.into_any_element()),
+ priority: 0,
+ }
+}
+
+/// An element which delays the painting of its child until after all of
+/// its ancestors, while keeping its layout as part of the current element tree.
+pub struct Deferred {
+ child: Option<AnyElement>,
+ priority: usize,
+}
+
+impl Element for Deferred {
+ type BeforeLayout = ();
+ type AfterLayout = ();
+
+ fn before_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, ()) {
+ let layout_id = self.child.as_mut().unwrap().before_layout(cx);
+ (layout_id, ())
+ }
+
+ fn after_layout(
+ &mut self,
+ _bounds: Bounds<Pixels>,
+ _before_layout: &mut Self::BeforeLayout,
+ cx: &mut ElementContext,
+ ) {
+ let child = self.child.take().unwrap();
+ let element_offset = cx.element_offset();
+ cx.defer_draw(child, element_offset, self.priority)
+ }
+
+ fn paint(
+ &mut self,
+ _bounds: Bounds<Pixels>,
+ _before_layout: &mut Self::BeforeLayout,
+ _after_layout: &mut Self::AfterLayout,
+ _cx: &mut ElementContext,
+ ) {
+ }
+}
+
+impl IntoElement for Deferred {
+ type Element = Self;
+
+ fn into_element(self) -> Self::Element {
+ self
+ }
+}
+
+impl Deferred {
+ /// Sets a priority for the element. A higher priority conceptually means painting the element
+ /// on top of deferred draws with a lower priority (i.e. closer to the viewer).
+ pub fn priority(mut self, priority: usize) -> Self {
+ self.priority = priority;
+ self
+ }
+}
@@ -2,10 +2,10 @@ use crate::persistence::model::DockData;
use crate::DraggedDock;
use crate::{status_bar::StatusItemView, Workspace};
use gpui::{
- div, px, Action, AnchorCorner, AnyView, AppContext, Axis, ClickEvent, Entity, EntityId,
- EventEmitter, FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton, ParentElement,
- Render, SharedString, StyleRefinement, Styled, Subscription, View, ViewContext, VisualContext,
- WeakView, WindowContext,
+ deferred, div, px, Action, AnchorCorner, AnyView, AppContext, Axis, ClickEvent, Entity,
+ EntityId, EventEmitter, FocusHandle, FocusableView, IntoElement, KeyContext, MouseButton,
+ ParentElement, Render, SharedString, StyleRefinement, Styled, Subscription, View, ViewContext,
+ VisualContext, WeakView, WindowContext,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -551,7 +551,7 @@ impl Render for Dock {
let size = entry.panel.size(cx);
let position = self.position;
- let mut handle = div()
+ let handle = div()
.id("resize-handle")
.on_drag(DraggedDock(position), |dock, cx| {
cx.stop_propagation();
@@ -564,36 +564,35 @@ impl Render for Dock {
}
}))
.occlude();
-
- match self.position() {
- DockPosition::Left => {
- handle = handle
+ let handle = match self.position() {
+ DockPosition::Left => deferred(
+ handle
.absolute()
- .right(px(0.))
+ .right(-RESIZE_HANDLE_SIZE / 2.)
.top(px(0.))
.h_full()
.w(RESIZE_HANDLE_SIZE)
- .cursor_col_resize();
- }
- DockPosition::Bottom => {
- handle = handle
+ .cursor_col_resize(),
+ ),
+ DockPosition::Bottom => deferred(
+ handle
.absolute()
- .top(px(0.))
+ .top(-RESIZE_HANDLE_SIZE / 2.)
.left(px(0.))
.w_full()
.h(RESIZE_HANDLE_SIZE)
- .cursor_row_resize();
- }
- DockPosition::Right => {
- handle = handle
+ .cursor_row_resize(),
+ ),
+ DockPosition::Right => deferred(
+ handle
.absolute()
.top(px(0.))
- .left(px(0.))
+ .left(-RESIZE_HANDLE_SIZE / 2.)
.h_full()
.w(RESIZE_HANDLE_SIZE)
- .cursor_col_resize();
- }
- }
+ .cursor_col_resize(),
+ ),
+ };
div()
.key_context(dispatch_context)