Compare commits
1 commit
main
...
post-layou
Author | SHA1 | Date | |
---|---|---|---|
![]() |
da3031c2db |
15 changed files with 613 additions and 293 deletions
|
@ -773,11 +773,11 @@ impl CompletionsMenu {
|
|||
cx,
|
||||
);
|
||||
|
||||
return cx.spawn(move |this, mut cx| async move {
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
if let Some(true) = resolve_task.await.log_err() {
|
||||
this.update(&mut cx, |_, cx| cx.notify()).ok();
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
fn attempt_resolve_selected_completion_documentation(
|
||||
|
|
|
@ -374,7 +374,7 @@ impl EditorElement {
|
|||
) {
|
||||
let mouse_position = cx.mouse_position();
|
||||
if !text_bounds.contains(&mouse_position)
|
||||
|| !cx.was_top_layer(&mouse_position, stacking_order)
|
||||
|| !cx.is_top_layer(&mouse_position, stacking_order)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ impl EditorElement {
|
|||
} else if !text_bounds.contains(&event.position) {
|
||||
return;
|
||||
}
|
||||
if !cx.was_top_layer(&event.position, stacking_order) {
|
||||
if !cx.is_top_layer(&event.position, stacking_order) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -478,11 +478,11 @@ impl EditorElement {
|
|||
editor.select(SelectPhase::End, cx);
|
||||
}
|
||||
|
||||
if interactive_bounds.visibly_contains(&event.position, cx)
|
||||
if interactive_bounds.did_visibly_contains(&event.position, cx)
|
||||
&& !pending_nonempty_selections
|
||||
&& event.modifiers.command
|
||||
&& text_bounds.contains(&event.position)
|
||||
&& cx.was_top_layer(&event.position, stacking_order)
|
||||
&& cx.is_top_layer(&event.position, stacking_order)
|
||||
{
|
||||
let point = position_map.point_for_position(text_bounds, event.position);
|
||||
editor.handle_click_hovered_link(point, event.modifiers, cx);
|
||||
|
@ -550,7 +550,7 @@ impl EditorElement {
|
|||
let modifiers = event.modifiers;
|
||||
let text_hovered = text_bounds.contains(&event.position);
|
||||
let gutter_hovered = gutter_bounds.contains(&event.position);
|
||||
let was_top = cx.was_top_layer(&event.position, stacking_order);
|
||||
let was_top = cx.is_top_layer(&event.position, stacking_order);
|
||||
|
||||
editor.set_gutter_hovered(gutter_hovered, cx);
|
||||
|
||||
|
@ -903,7 +903,7 @@ impl EditorElement {
|
|||
bounds: text_bounds,
|
||||
stacking_order: cx.stacking_order().clone(),
|
||||
};
|
||||
if interactive_text_bounds.visibly_contains(&cx.mouse_position(), cx) {
|
||||
if interactive_text_bounds.did_visibly_contains(&cx.mouse_position(), cx) {
|
||||
if self
|
||||
.editor
|
||||
.read(cx)
|
||||
|
@ -1242,7 +1242,7 @@ impl EditorElement {
|
|||
popover_origin.x = popover_origin.x + x_out_of_bounds;
|
||||
}
|
||||
|
||||
if cx.was_top_layer(&popover_origin, cx.stacking_order()) {
|
||||
if cx.is_top_layer(&popover_origin, cx.stacking_order()) {
|
||||
cx.break_content_mask(|cx| {
|
||||
hover_popover.draw(popover_origin, available_space, cx)
|
||||
});
|
||||
|
@ -1537,7 +1537,7 @@ impl EditorElement {
|
|||
stacking_order: cx.stacking_order().clone(),
|
||||
};
|
||||
let mut mouse_position = cx.mouse_position();
|
||||
if interactive_track_bounds.visibly_contains(&mouse_position, cx) {
|
||||
if interactive_track_bounds.did_visibly_contains(&mouse_position, cx) {
|
||||
cx.set_cursor_style(CursorStyle::Arrow);
|
||||
}
|
||||
|
||||
|
@ -1567,7 +1567,7 @@ impl EditorElement {
|
|||
cx.stop_propagation();
|
||||
} else {
|
||||
editor.scroll_manager.set_is_dragging_scrollbar(false, cx);
|
||||
if interactive_track_bounds.visibly_contains(&event.position, cx) {
|
||||
if interactive_track_bounds.did_visibly_contains(&event.position, cx) {
|
||||
editor.scroll_manager.show_scrollbar(cx);
|
||||
}
|
||||
}
|
||||
|
@ -2652,14 +2652,14 @@ impl EditorElement {
|
|||
|
||||
move |event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
&& interactive_bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
delta = delta.coalesce(event.delta);
|
||||
editor.update(cx, |editor, cx| {
|
||||
let position = event.position;
|
||||
let position_map: &PositionMap = &position_map;
|
||||
let bounds = &interactive_bounds;
|
||||
if !bounds.visibly_contains(&position, cx) {
|
||||
if !bounds.did_visibly_contains(&position, cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2719,7 +2719,7 @@ impl EditorElement {
|
|||
|
||||
move |event: &MouseDownEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
&& interactive_bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
match event.button {
|
||||
MouseButton::Left => editor.update(cx, |editor, cx| {
|
||||
|
@ -2786,7 +2786,7 @@ impl EditorElement {
|
|||
)
|
||||
}
|
||||
|
||||
if interactive_bounds.visibly_contains(&event.position, cx) {
|
||||
if interactive_bounds.did_visibly_contains(&event.position, cx) {
|
||||
Self::mouse_moved(
|
||||
editor,
|
||||
event,
|
||||
|
@ -3067,7 +3067,7 @@ impl Element for EditorElement {
|
|||
) {
|
||||
let editor = self.editor.clone();
|
||||
|
||||
cx.paint_view(self.editor.entity_id(), |cx| {
|
||||
cx.with_view(self.editor.entity_id(), |cx| {
|
||||
cx.with_text_style(
|
||||
Some(gpui::TextStyleRefinement {
|
||||
font_size: Some(self.style.text.font_size),
|
||||
|
|
|
@ -40,7 +40,7 @@ use crate::{
|
|||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
pub(crate) use smallvec::SmallVec;
|
||||
use std::{any::Any, fmt::Debug, ops::DerefMut};
|
||||
use std::{any::{type_name_of_val, Any}, fmt::Debug, ops::DerefMut};
|
||||
|
||||
/// Implemented by types that participate in laying out and painting the contents of a window.
|
||||
/// Elements form a tree and are laid out according to web-based layout rules, as implemented by Taffy.
|
||||
|
@ -59,6 +59,19 @@ pub trait Element: 'static + IntoElement {
|
|||
cx: &mut ElementContext,
|
||||
) -> (LayoutId, Self::State);
|
||||
|
||||
/// After layout is performed, we assign each element its bounds. Some elements may
|
||||
/// need to use these bounds to render and layout the appropriate children. This is
|
||||
/// also each element's opportunity to add opaque layers before painting [`crate::window::element_cx::add_opaque_layer`].
|
||||
fn post_layout(
|
||||
&mut self,
|
||||
_bounds: Bounds<Pixels>,
|
||||
_state: &mut Self::State,
|
||||
_cx: &mut ElementContext,
|
||||
) {
|
||||
dbg!(type_name_of_val(self));
|
||||
// TODO: Delete this default implementation once we've implemented it everywhere.
|
||||
}
|
||||
|
||||
/// Once layout has been completed, this method will be called to paint the element to the screen.
|
||||
/// The state argument is the same state that was returned from [`Element::request_layout()`].
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext);
|
||||
|
@ -229,6 +242,8 @@ trait ElementObject {
|
|||
|
||||
fn request_layout(&mut self, cx: &mut ElementContext) -> LayoutId;
|
||||
|
||||
fn post_layout(&mut self, cx: &mut ElementContext);
|
||||
|
||||
fn paint(&mut self, cx: &mut ElementContext);
|
||||
|
||||
fn measure(
|
||||
|
@ -301,6 +316,44 @@ impl<E: Element> DrawableElement<E> {
|
|||
layout_id
|
||||
}
|
||||
|
||||
fn post_layout(&mut self, cx: &mut ElementContext) {
|
||||
println!("DrawableElement post_layout");
|
||||
match &mut self.phase {
|
||||
ElementDrawPhase::LayoutRequested {
|
||||
layout_id,
|
||||
frame_state,
|
||||
..
|
||||
}
|
||||
| ElementDrawPhase::LayoutComputed {
|
||||
layout_id,
|
||||
frame_state,
|
||||
..
|
||||
} => {
|
||||
let bounds = cx.layout_bounds(*layout_id);
|
||||
let element = self.element.as_mut().unwrap();
|
||||
|
||||
if let Some(frame_state) = frame_state.as_mut() {
|
||||
println!("Some");
|
||||
element.post_layout(bounds, frame_state, cx);
|
||||
} else {
|
||||
println!("Else");
|
||||
let element_id = element
|
||||
.element_id()
|
||||
.expect("if we don't have frame state, we should have element state");
|
||||
|
||||
cx.with_element_state(element_id, |element_state, cx| {
|
||||
println!("with_element_state");
|
||||
let mut element_state = element_state.unwrap();
|
||||
element.post_layout(bounds, &mut element_state, cx);
|
||||
((), element_state)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_ => panic!("must call layout before post_layout"),
|
||||
}
|
||||
}
|
||||
|
||||
fn paint(mut self, cx: &mut ElementContext) -> Option<E::State> {
|
||||
match self.phase {
|
||||
ElementDrawPhase::LayoutRequested {
|
||||
|
@ -407,6 +460,11 @@ where
|
|||
DrawableElement::request_layout(self.as_mut().unwrap(), cx)
|
||||
}
|
||||
|
||||
fn post_layout(&mut self, cx: &mut ElementContext) {
|
||||
println!("ElementObject post_layout");
|
||||
DrawableElement::post_layout(self.as_mut().unwrap(), cx)
|
||||
}
|
||||
|
||||
fn paint(&mut self, cx: &mut ElementContext) {
|
||||
DrawableElement::paint(self.take().unwrap(), cx);
|
||||
}
|
||||
|
@ -450,6 +508,12 @@ impl AnyElement {
|
|||
self.0.request_layout(cx)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn post_layout(&mut self, cx: &mut ElementContext) {
|
||||
println!("AnyElement post_layout");
|
||||
self.0.post_layout(cx)
|
||||
}
|
||||
|
||||
/// Paints the element stored in this `AnyElement`.
|
||||
pub fn paint(&mut self, cx: &mut ElementContext) {
|
||||
self.0.paint(cx)
|
||||
|
@ -491,6 +555,16 @@ impl Element for AnyElement {
|
|||
let layout_id = self.request_layout(cx);
|
||||
(layout_id, ())
|
||||
}
|
||||
|
||||
fn post_layout(
|
||||
&mut self,
|
||||
_bounds: Bounds<Pixels>,
|
||||
_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
self.0.post_layout(cx);
|
||||
}
|
||||
|
||||
|
||||
fn paint(&mut self, _: Bounds<Pixels>, _: &mut Self::State, cx: &mut ElementContext) {
|
||||
self.paint(cx)
|
||||
|
|
|
@ -88,7 +88,7 @@ impl Interactivity {
|
|||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& event.button == button
|
||||
&& bounds.visibly_contains(&event.position, cx)
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
|
@ -105,7 +105,9 @@ impl Interactivity {
|
|||
) {
|
||||
self.mouse_down_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Capture && bounds.visibly_contains(&event.position, cx) {
|
||||
if phase == DispatchPhase::Capture
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
}));
|
||||
|
@ -121,7 +123,9 @@ impl Interactivity {
|
|||
) {
|
||||
self.mouse_down_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
}));
|
||||
|
@ -140,7 +144,7 @@ impl Interactivity {
|
|||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& event.button == button
|
||||
&& bounds.visibly_contains(&event.position, cx)
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
|
@ -157,7 +161,9 @@ impl Interactivity {
|
|||
) {
|
||||
self.mouse_up_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Capture && bounds.visibly_contains(&event.position, cx) {
|
||||
if phase == DispatchPhase::Capture
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
}));
|
||||
|
@ -173,7 +179,9 @@ impl Interactivity {
|
|||
) {
|
||||
self.mouse_up_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
}));
|
||||
|
@ -190,7 +198,8 @@ impl Interactivity {
|
|||
) {
|
||||
self.mouse_down_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Capture && !bounds.visibly_contains(&event.position, cx)
|
||||
if phase == DispatchPhase::Capture
|
||||
&& !bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx)
|
||||
}
|
||||
|
@ -211,7 +220,7 @@ impl Interactivity {
|
|||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Capture
|
||||
&& event.button == button
|
||||
&& !bounds.visibly_contains(&event.position, cx)
|
||||
&& !bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx);
|
||||
}
|
||||
|
@ -228,7 +237,9 @@ impl Interactivity {
|
|||
) {
|
||||
self.mouse_move_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx);
|
||||
}
|
||||
}));
|
||||
|
@ -277,7 +288,9 @@ impl Interactivity {
|
|||
) {
|
||||
self.scroll_wheel_listeners
|
||||
.push(Box::new(move |event, bounds, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble && bounds.visibly_contains(&event.position, cx) {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
(listener)(event, cx);
|
||||
}
|
||||
}));
|
||||
|
@ -564,7 +577,7 @@ pub trait InteractiveElement: Sized {
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
// #[cfg(any(test, feature = "test-support"))]
|
||||
/// Set a key that can be used to look up this element's bounds
|
||||
/// in the [`VisualTestContext::debug_bounds`] map
|
||||
/// This is a noop in release builds
|
||||
|
@ -573,14 +586,14 @@ pub trait InteractiveElement: Sized {
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
/// Set a key that can be used to look up this element's bounds
|
||||
/// in the [`VisualTestContext::debug_bounds`] map
|
||||
/// This is a noop in release builds
|
||||
#[inline]
|
||||
fn debug_selector(self, _: impl FnOnce() -> String) -> Self {
|
||||
self
|
||||
}
|
||||
// #[cfg(not(any(test, feature = "test-support")))]
|
||||
// /// Set a key that can be used to look up this element's bounds
|
||||
// /// in the [`VisualTestContext::debug_bounds`] map
|
||||
// /// This is a noop in release builds
|
||||
// #[inline]
|
||||
// fn debug_selector(self, _: impl FnOnce() -> String) -> Self {
|
||||
// self
|
||||
// }
|
||||
|
||||
/// Bind the given callback to the mouse down event for any button, during the capture phase
|
||||
/// the fluent API equivalent to [`Interactivity::capture_any_mouse_down`]
|
||||
|
@ -1072,6 +1085,7 @@ impl Element for Div {
|
|||
})
|
||||
},
|
||||
);
|
||||
|
||||
(
|
||||
layout_id,
|
||||
DivState {
|
||||
|
@ -1081,6 +1095,30 @@ impl Element for Div {
|
|||
)
|
||||
}
|
||||
|
||||
fn post_layout(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
dbg!(self.children.len());
|
||||
self.interactivity.post_layout(
|
||||
bounds,
|
||||
&mut element_state.interactive_state,
|
||||
cx,
|
||||
|_, scroll_offset, cx| {
|
||||
println!("in continuation");
|
||||
cx.with_element_offset(scroll_offset, |cx| {
|
||||
println!("in with_element_offset");
|
||||
for child in &mut self.children {
|
||||
println!("child");
|
||||
child.post_layout(cx);
|
||||
}
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
|
@ -1207,7 +1245,7 @@ pub struct Interactivity {
|
|||
#[cfg(debug_assertions)]
|
||||
pub(crate) location: Option<core::panic::Location<'static>>,
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
// #[cfg(any(test, feature = "test-support"))]
|
||||
pub(crate) debug_selector: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1260,7 @@ pub struct InteractiveBounds {
|
|||
|
||||
impl InteractiveBounds {
|
||||
/// Checks whether this point was inside these bounds, and that these bounds where the topmost layer
|
||||
pub fn visibly_contains(&self, point: &Point<Pixels>, cx: &WindowContext) -> bool {
|
||||
pub fn did_visibly_contains(&self, point: &Point<Pixels>, cx: &WindowContext) -> bool {
|
||||
self.bounds.contains(point) && cx.was_top_layer(point, &self.stacking_order)
|
||||
}
|
||||
|
||||
|
@ -1230,7 +1268,7 @@ impl InteractiveBounds {
|
|||
/// under an active drag
|
||||
pub fn drag_target_contains(&self, point: &Point<Pixels>, cx: &WindowContext) -> bool {
|
||||
self.bounds.contains(point)
|
||||
&& cx.was_top_layer_under_active_drag(point, &self.stacking_order)
|
||||
&& cx.is_top_layer_under_active_drag(point, &self.stacking_order)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1274,6 +1312,29 @@ impl Interactivity {
|
|||
(layout_id, element_state)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub fn post_layout(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
element_state: &mut InteractiveElementState,
|
||||
cx: &mut ElementContext,
|
||||
continuation: impl FnOnce(Bounds<Pixels>, Point<Pixels>, &mut ElementContext),
|
||||
) {
|
||||
let z_index = self.base_style.z_index.unwrap_or(0);
|
||||
|
||||
cx.with_z_index(z_index, |cx| {
|
||||
println!("interactivity post_layout is adding an opaque layer");
|
||||
cx.add_opaque_layer(bounds.intersect(&cx.content_mask().bounds));
|
||||
|
||||
let scroll_offset = element_state
|
||||
.scroll_offset
|
||||
.as_ref()
|
||||
.map(|scroll_offset| *scroll_offset.borrow())
|
||||
.unwrap_or_default();
|
||||
continuation(bounds, scroll_offset, cx);
|
||||
});
|
||||
}
|
||||
|
||||
/// Paint this element according to this interactivity state's configured styles
|
||||
/// and bind the element's mouse and keyboard events.
|
||||
///
|
||||
|
@ -1288,11 +1349,8 @@ impl Interactivity {
|
|||
content_size: Size<Pixels>,
|
||||
element_state: &mut InteractiveElementState,
|
||||
cx: &mut ElementContext,
|
||||
f: impl FnOnce(&Style, Point<Pixels>, &mut ElementContext),
|
||||
continuation: impl FnOnce(&Style, Point<Pixels>, &mut ElementContext),
|
||||
) {
|
||||
let style = self.compute_style(Some(bounds), element_state, cx);
|
||||
let z_index = style.z_index.unwrap_or(0);
|
||||
|
||||
#[cfg(any(feature = "test-support", test))]
|
||||
if let Some(debug_selector) = &self.debug_selector {
|
||||
cx.window
|
||||
|
@ -1301,8 +1359,8 @@ impl Interactivity {
|
|||
.insert(debug_selector.clone(), bounds);
|
||||
}
|
||||
|
||||
let paint_hover_group_handler = |cx: &mut ElementContext| {
|
||||
let hover_group_bounds = self
|
||||
let paint_hover_group_handler = |this: &Self, cx: &mut ElementContext| {
|
||||
let hover_group_bounds = this
|
||||
.group_hover_style
|
||||
.as_ref()
|
||||
.and_then(|group_hover| GroupBounds::get(&group_hover.group, cx));
|
||||
|
@ -1319,12 +1377,15 @@ impl Interactivity {
|
|||
}
|
||||
};
|
||||
|
||||
if style.visibility == Visibility::Hidden {
|
||||
cx.with_z_index(z_index, |cx| paint_hover_group_handler(cx));
|
||||
return;
|
||||
}
|
||||
|
||||
let z_index = self.base_style.z_index.unwrap_or(0);
|
||||
cx.with_z_index(z_index, |cx| {
|
||||
let style = self.compute_style(Some(bounds), element_state, cx);
|
||||
|
||||
if style.visibility == Visibility::Hidden {
|
||||
paint_hover_group_handler(self, cx);
|
||||
return;
|
||||
}
|
||||
|
||||
style.paint(bounds, cx, |cx: &mut ElementContext| {
|
||||
cx.with_text_style(style.text_style().cloned(), |cx| {
|
||||
cx.with_content_mask(style.overflow_mask(bounds, cx.rem_size()), |cx| {
|
||||
|
@ -1439,19 +1500,19 @@ impl Interactivity {
|
|||
stacking_order: cx.stacking_order().clone(),
|
||||
};
|
||||
|
||||
if self.block_mouse
|
||||
|| style.background.as_ref().is_some_and(|fill| {
|
||||
fill.color().is_some_and(|color| !color.is_transparent())
|
||||
})
|
||||
{
|
||||
cx.add_opaque_layer(interactive_bounds.bounds);
|
||||
}
|
||||
// if self.block_mouse
|
||||
// || style.background.as_ref().is_some_and(|fill| {
|
||||
// fill.color().is_some_and(|color| !color.is_transparent())
|
||||
// })
|
||||
// {
|
||||
// cx.add_opaque_layer(interactive_bounds.bounds);
|
||||
// }
|
||||
|
||||
if !cx.has_active_drag() {
|
||||
if let Some(mouse_cursor) = style.mouse_cursor {
|
||||
let mouse_position = &cx.mouse_position();
|
||||
let hovered =
|
||||
interactive_bounds.visibly_contains(mouse_position, cx);
|
||||
interactive_bounds.did_visibly_contains(mouse_position, cx);
|
||||
if hovered {
|
||||
cx.set_cursor_style(mouse_cursor);
|
||||
}
|
||||
|
@ -1467,7 +1528,8 @@ impl Interactivity {
|
|||
move |event: &MouseDownEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& !cx.default_prevented()
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
&& interactive_bounds
|
||||
.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
cx.focus(&focus_handle);
|
||||
// If there is a parent that is also focusable, prevent it
|
||||
|
@ -1506,7 +1568,7 @@ impl Interactivity {
|
|||
})
|
||||
}
|
||||
|
||||
paint_hover_group_handler(cx);
|
||||
paint_hover_group_handler(self, cx);
|
||||
|
||||
if self.hover_style.is_some()
|
||||
|| self.base_style.mouse_cursor.is_some()
|
||||
|
@ -1585,7 +1647,8 @@ impl Interactivity {
|
|||
move |event: &MouseDownEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& event.button == MouseButton::Left
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
&& interactive_bounds
|
||||
.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
*pending_mouse_down.borrow_mut() = Some(event.clone());
|
||||
cx.refresh();
|
||||
|
@ -1646,7 +1709,7 @@ impl Interactivity {
|
|||
DispatchPhase::Bubble => {
|
||||
if let Some(mouse_down) = captured_mouse_down.take() {
|
||||
if interactive_bounds
|
||||
.visibly_contains(&event.position, cx)
|
||||
.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
let mouse_click = ClickEvent {
|
||||
down: mouse_down,
|
||||
|
@ -1678,7 +1741,7 @@ impl Interactivity {
|
|||
return;
|
||||
}
|
||||
let is_hovered = interactive_bounds
|
||||
.visibly_contains(&event.position, cx)
|
||||
.did_visibly_contains(&event.position, cx)
|
||||
&& has_mouse_down.borrow().is_none()
|
||||
&& !cx.has_active_drag();
|
||||
let mut was_hovered = was_hovered.borrow_mut();
|
||||
|
@ -1705,7 +1768,7 @@ impl Interactivity {
|
|||
|
||||
cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
|
||||
let is_hovered = interactive_bounds
|
||||
.visibly_contains(&event.position, cx)
|
||||
.did_visibly_contains(&event.position, cx)
|
||||
&& pending_mouse_down.borrow().is_none();
|
||||
if !is_hovered {
|
||||
active_tooltip.borrow_mut().take();
|
||||
|
@ -1787,7 +1850,7 @@ impl Interactivity {
|
|||
let group = active_group_bounds
|
||||
.map_or(false, |bounds| bounds.contains(&down.position));
|
||||
let element =
|
||||
interactive_bounds.visibly_contains(&down.position, cx);
|
||||
interactive_bounds.did_visibly_contains(&down.position, cx);
|
||||
if group || element {
|
||||
*active_state.borrow_mut() =
|
||||
ElementClickedState { group, element };
|
||||
|
@ -1840,7 +1903,7 @@ impl Interactivity {
|
|||
let interactive_bounds = interactive_bounds.clone();
|
||||
cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
&& interactive_bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
let mut scroll_offset = scroll_offset.borrow_mut();
|
||||
let old_scroll_offset = *scroll_offset;
|
||||
|
@ -1910,7 +1973,7 @@ impl Interactivity {
|
|||
cx.on_action(action_type, listener)
|
||||
}
|
||||
|
||||
f(&style, scroll_offset.unwrap_or_default(), cx)
|
||||
continuation(&style, scroll_offset.unwrap_or_default(), cx)
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -1933,101 +1996,107 @@ impl Interactivity {
|
|||
let mut style = Style::default();
|
||||
style.refine(&self.base_style);
|
||||
|
||||
cx.with_z_index(style.z_index.unwrap_or(0), |cx| {
|
||||
if let Some(focus_handle) = self.tracked_focus_handle.as_ref() {
|
||||
if let Some(in_focus_style) = self.in_focus_style.as_ref() {
|
||||
if focus_handle.within_focused(cx) {
|
||||
style.refine(in_focus_style);
|
||||
// cx.with_z_index(style.z_index.unwrap_or(0), |cx| {
|
||||
if let Some(focus_handle) = self.tracked_focus_handle.as_ref() {
|
||||
if let Some(in_focus_style) = self.in_focus_style.as_ref() {
|
||||
if focus_handle.within_focused(cx) {
|
||||
style.refine(in_focus_style);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(focus_style) = self.focus_style.as_ref() {
|
||||
if focus_handle.is_focused(cx) {
|
||||
style.refine(focus_style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(bounds) = bounds {
|
||||
let mouse_position = cx.mouse_position();
|
||||
if !cx.has_active_drag() {
|
||||
if let Some(group_hover) = self.group_hover_style.as_ref() {
|
||||
if let Some(group_bounds) = GroupBounds::get(&group_hover.group, cx.deref_mut())
|
||||
{
|
||||
if group_bounds.contains(&mouse_position)
|
||||
&& cx.is_top_layer(&mouse_position, cx.stacking_order())
|
||||
{
|
||||
style.refine(&group_hover.style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(focus_style) = self.focus_style.as_ref() {
|
||||
if focus_handle.is_focused(cx) {
|
||||
style.refine(focus_style);
|
||||
if let Some(hover_style) = self.hover_style.as_ref() {
|
||||
let outer_button = self.debug_selector.as_deref() == Some("outer_button");
|
||||
let inner_button = self.debug_selector.as_deref() == Some("inner_button");
|
||||
if outer_button {
|
||||
cx.is_top_layer_debug(&mouse_position, cx.stacking_order());
|
||||
}
|
||||
println!("\n\n\n");
|
||||
|
||||
if bounds
|
||||
.intersect(&cx.content_mask().bounds)
|
||||
.contains(&mouse_position)
|
||||
&& cx.is_top_layer(&mouse_position, cx.stacking_order())
|
||||
{
|
||||
style.refine(hover_style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(bounds) = bounds {
|
||||
let mouse_position = cx.mouse_position();
|
||||
if !cx.has_active_drag() {
|
||||
if let Some(group_hover) = self.group_hover_style.as_ref() {
|
||||
if let Some(drag) = cx.active_drag.take() {
|
||||
let mut can_drop = true;
|
||||
if let Some(can_drop_predicate) = &self.can_drop_predicate {
|
||||
can_drop = can_drop_predicate(drag.value.as_ref(), cx.deref_mut());
|
||||
}
|
||||
|
||||
if can_drop {
|
||||
for (state_type, group_drag_style) in &self.group_drag_over_styles {
|
||||
if let Some(group_bounds) =
|
||||
GroupBounds::get(&group_hover.group, cx.deref_mut())
|
||||
GroupBounds::get(&group_drag_style.group, cx.deref_mut())
|
||||
{
|
||||
if group_bounds.contains(&mouse_position)
|
||||
&& cx.was_top_layer(&mouse_position, cx.stacking_order())
|
||||
{
|
||||
style.refine(&group_hover.style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(hover_style) = self.hover_style.as_ref() {
|
||||
if bounds
|
||||
.intersect(&cx.content_mask().bounds)
|
||||
.contains(&mouse_position)
|
||||
&& cx.was_top_layer(&mouse_position, cx.stacking_order())
|
||||
{
|
||||
style.refine(hover_style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(drag) = cx.active_drag.take() {
|
||||
let mut can_drop = true;
|
||||
if let Some(can_drop_predicate) = &self.can_drop_predicate {
|
||||
can_drop = can_drop_predicate(drag.value.as_ref(), cx.deref_mut());
|
||||
}
|
||||
|
||||
if can_drop {
|
||||
for (state_type, group_drag_style) in &self.group_drag_over_styles {
|
||||
if let Some(group_bounds) =
|
||||
GroupBounds::get(&group_drag_style.group, cx.deref_mut())
|
||||
{
|
||||
if *state_type == drag.value.as_ref().type_id()
|
||||
&& group_bounds.contains(&mouse_position)
|
||||
{
|
||||
style.refine(&group_drag_style.style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (state_type, build_drag_over_style) in &self.drag_over_styles {
|
||||
if *state_type == drag.value.as_ref().type_id()
|
||||
&& bounds
|
||||
.intersect(&cx.content_mask().bounds)
|
||||
.contains(&mouse_position)
|
||||
&& cx.was_top_layer_under_active_drag(
|
||||
&mouse_position,
|
||||
cx.stacking_order(),
|
||||
)
|
||||
&& group_bounds.contains(&mouse_position)
|
||||
{
|
||||
style.refine(&build_drag_over_style(drag.value.as_ref(), cx));
|
||||
style.refine(&group_drag_style.style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cx.active_drag = Some(drag);
|
||||
for (state_type, build_drag_over_style) in &self.drag_over_styles {
|
||||
if *state_type == drag.value.as_ref().type_id()
|
||||
&& bounds
|
||||
.intersect(&cx.content_mask().bounds)
|
||||
.contains(&mouse_position)
|
||||
&& cx.is_top_layer_under_active_drag(
|
||||
&mouse_position,
|
||||
cx.stacking_order(),
|
||||
)
|
||||
{
|
||||
style.refine(&build_drag_over_style(drag.value.as_ref(), cx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let clicked_state = element_state
|
||||
.clicked_state
|
||||
.get_or_insert_with(Default::default)
|
||||
.borrow();
|
||||
if clicked_state.group {
|
||||
if let Some(group) = self.group_active_style.as_ref() {
|
||||
style.refine(&group.style)
|
||||
}
|
||||
cx.active_drag = Some(drag);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(active_style) = self.active_style.as_ref() {
|
||||
if clicked_state.element {
|
||||
style.refine(active_style)
|
||||
}
|
||||
let clicked_state = element_state
|
||||
.clicked_state
|
||||
.get_or_insert_with(Default::default)
|
||||
.borrow();
|
||||
if clicked_state.group {
|
||||
if let Some(group) = self.group_active_style.as_ref() {
|
||||
style.refine(&group.style)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(active_style) = self.active_style.as_ref() {
|
||||
if clicked_state.element {
|
||||
style.refine(active_style)
|
||||
}
|
||||
}
|
||||
// });
|
||||
|
||||
style
|
||||
}
|
||||
|
@ -2211,6 +2280,15 @@ where
|
|||
self.element.request_layout(state, cx)
|
||||
}
|
||||
|
||||
fn post_layout(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
self.element.post_layout(bounds, state, cx);
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
self.element.paint(bounds, state, cx)
|
||||
}
|
||||
|
|
|
@ -520,7 +520,7 @@ impl Element for List {
|
|||
cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& bounds.contains(&event.position)
|
||||
&& cx.was_top_layer(&event.position, cx.stacking_order())
|
||||
&& cx.is_top_layer(&event.position, cx.stacking_order())
|
||||
{
|
||||
list_state.0.borrow_mut().scroll(
|
||||
&scroll_top,
|
||||
|
|
|
@ -427,7 +427,7 @@ impl Element for InteractiveText {
|
|||
.clickable_ranges
|
||||
.iter()
|
||||
.any(|range| range.contains(&ix))
|
||||
&& cx.was_top_layer(&mouse_position, cx.stacking_order())
|
||||
&& cx.is_top_layer(&mouse_position, cx.stacking_order())
|
||||
{
|
||||
cx.set_cursor_style(crate::CursorStyle::PointingHand)
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ impl<V: Render> Element for View<V> {
|
|||
}
|
||||
|
||||
fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut ElementContext) {
|
||||
cx.paint_view(self.entity_id(), |cx| element.take().unwrap().paint(cx));
|
||||
cx.with_view(self.entity_id(), |cx| element.take().unwrap().paint(cx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,7 @@ impl<V> Eq for WeakView<V> {}
|
|||
pub struct AnyView {
|
||||
model: AnyModel,
|
||||
request_layout: fn(&AnyView, &mut ElementContext) -> (LayoutId, AnyElement),
|
||||
post_layout: fn(&mut AnyElement, &mut ElementContext),
|
||||
cache: bool,
|
||||
}
|
||||
|
||||
|
@ -220,7 +221,8 @@ impl AnyView {
|
|||
pub fn downgrade(&self) -> AnyWeakView {
|
||||
AnyWeakView {
|
||||
model: self.model.downgrade(),
|
||||
layout: self.request_layout,
|
||||
request_layout: self.request_layout,
|
||||
post_layout: self.post_layout,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,6 +234,7 @@ impl AnyView {
|
|||
Err(model) => Err(Self {
|
||||
model,
|
||||
request_layout: self.request_layout,
|
||||
post_layout: self.post_layout,
|
||||
cache: self.cache,
|
||||
}),
|
||||
}
|
||||
|
@ -247,20 +250,34 @@ impl AnyView {
|
|||
self.model.entity_id()
|
||||
}
|
||||
|
||||
pub(crate) fn draw(
|
||||
pub(crate) fn layout_and_post_layout(
|
||||
&self,
|
||||
origin: Point<Pixels>,
|
||||
available_space: Size<AvailableSpace>,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
cx.paint_view(self.entity_id(), |cx| {
|
||||
) -> AnyElement {
|
||||
cx.with_view(self.entity_id(), |cx| {
|
||||
cx.with_absolute_element_offset(origin, |cx| {
|
||||
let (layout_id, mut rendered_element) = (self.request_layout)(self, cx);
|
||||
cx.compute_layout(layout_id, available_space);
|
||||
rendered_element.paint(cx)
|
||||
});
|
||||
(self.post_layout)(&mut rendered_element, cx);
|
||||
rendered_element
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn paint(
|
||||
&self,
|
||||
origin: Point<Pixels>,
|
||||
mut rendered_element: AnyElement,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
cx.with_view(self.entity_id(), |cx| {
|
||||
cx.with_absolute_element_offset(origin, |cx| {
|
||||
rendered_element.paint(cx);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Render> From<View<V>> for AnyView {
|
||||
|
@ -268,6 +285,7 @@ impl<V: Render> From<View<V>> for AnyView {
|
|||
AnyView {
|
||||
model: value.model.into_any(),
|
||||
request_layout: any_view::request_layout::<V>,
|
||||
post_layout: any_view::post_layout,
|
||||
cache: false,
|
||||
}
|
||||
}
|
||||
|
@ -300,9 +318,19 @@ impl Element for AnyView {
|
|||
(layout_id, state)
|
||||
})
|
||||
}
|
||||
|
||||
fn post_layout(
|
||||
&mut self,
|
||||
_bounds: Bounds<Pixels>,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
// todo!("move parts of caching")
|
||||
state.element.as_mut().unwrap().post_layout(cx);
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
cx.paint_view(self.entity_id(), |cx| {
|
||||
cx.with_view(self.entity_id(), |cx| {
|
||||
if !self.cache {
|
||||
state.element.take().unwrap().paint(cx);
|
||||
return;
|
||||
|
@ -328,13 +356,8 @@ impl Element for AnyView {
|
|||
element.draw(bounds.origin, bounds.size.into(), cx);
|
||||
}
|
||||
|
||||
state.next_stacking_order_id = cx
|
||||
.window
|
||||
.next_frame
|
||||
.next_stacking_order_ids
|
||||
.last()
|
||||
.copied()
|
||||
.unwrap();
|
||||
state.next_stacking_order_id =
|
||||
cx.window.next_stacking_order_ids.last().copied().unwrap();
|
||||
state.cache_key = Some(ViewCacheKey {
|
||||
bounds,
|
||||
stacking_order: cx.stacking_order().clone(),
|
||||
|
@ -372,7 +395,8 @@ impl IntoElement for AnyView {
|
|||
/// A weak, dynamically-typed view handle that does not prevent the view from being released.
|
||||
pub struct AnyWeakView {
|
||||
model: AnyWeakModel,
|
||||
layout: fn(&AnyView, &mut ElementContext) -> (LayoutId, AnyElement),
|
||||
request_layout: fn(&AnyView, &mut ElementContext) -> (LayoutId, AnyElement),
|
||||
post_layout: fn(&mut AnyElement, &mut ElementContext),
|
||||
}
|
||||
|
||||
impl AnyWeakView {
|
||||
|
@ -381,7 +405,8 @@ impl AnyWeakView {
|
|||
let model = self.model.upgrade()?;
|
||||
Some(AnyView {
|
||||
model,
|
||||
request_layout: self.layout,
|
||||
request_layout: self.request_layout,
|
||||
post_layout: self.post_layout,
|
||||
cache: false,
|
||||
})
|
||||
}
|
||||
|
@ -391,7 +416,8 @@ impl<V: 'static + Render> From<WeakView<V>> for AnyWeakView {
|
|||
fn from(view: WeakView<V>) -> Self {
|
||||
Self {
|
||||
model: view.model.into(),
|
||||
layout: any_view::request_layout::<V>,
|
||||
request_layout: any_view::request_layout::<V>,
|
||||
post_layout: any_view::post_layout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -422,4 +448,8 @@ mod any_view {
|
|||
let layout_id = element.request_layout(cx);
|
||||
(layout_id, element)
|
||||
}
|
||||
|
||||
pub(crate) fn post_layout(element: &mut AnyElement, cx: &mut ElementContext) {
|
||||
element.post_layout(cx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -257,6 +257,9 @@ pub struct Window {
|
|||
pub(crate) element_id_stack: GlobalElementId,
|
||||
pub(crate) rendered_frame: Frame,
|
||||
pub(crate) next_frame: Frame,
|
||||
pub(crate) z_index_stack: StackingOrder,
|
||||
pub(crate) next_stacking_order_ids: Vec<u16>,
|
||||
pub(crate) next_root_z_index: u16,
|
||||
next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>>,
|
||||
pub(crate) dirty_views: FxHashSet<EntityId>,
|
||||
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
||||
|
@ -441,6 +444,9 @@ impl Window {
|
|||
element_id_stack: GlobalElementId::default(),
|
||||
rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
|
||||
next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
|
||||
z_index_stack: StackingOrder::default(),
|
||||
next_stacking_order_ids: vec![0],
|
||||
next_root_z_index: 0,
|
||||
next_frame_callbacks,
|
||||
dirty_views: FxHashSet::default(),
|
||||
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
|
||||
|
@ -466,6 +472,7 @@ impl Window {
|
|||
graphics_profiler_enabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_focus_listener(
|
||||
&mut self,
|
||||
value: AnyWindowFocusListener,
|
||||
|
@ -848,6 +855,49 @@ impl<'a> WindowContext<'a> {
|
|||
self.window.modifiers
|
||||
}
|
||||
|
||||
/// Returns true if there is no opaque layer containing the given point
|
||||
/// on top of the given level. Layers who are extensions of the queried layer
|
||||
/// are not considered to be on top of queried layer.
|
||||
pub fn is_top_layer_debug(&self, point: &Point<Pixels>, layer: &StackingOrder) -> bool {
|
||||
dbg!(point, layer);
|
||||
dbg!(&self.window.next_frame.depth_map);
|
||||
// Precondition: the depth map is ordered from topmost to bottomost.
|
||||
|
||||
for (opaque_layer, _, bounds) in self.window.next_frame.depth_map.iter() {
|
||||
dbg!(opaque_layer);
|
||||
if layer >= opaque_layer {
|
||||
// The queried layer is either above or is the same as the this opaque layer.
|
||||
// Anything after this point is guaranteed to be below the queried layer.
|
||||
println!("is above or equal");
|
||||
return true;
|
||||
}
|
||||
|
||||
if !bounds.contains(point) {
|
||||
// This opaque layer is above the queried layer but it doesn't contain
|
||||
// the given position, so we can ignore it even if it's above.
|
||||
println!("does not contain point");
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point, we've established that this opaque layer is on top of the queried layer
|
||||
// and contains the position:
|
||||
// If neither the opaque layer or the queried layer is an extension of the other then
|
||||
// we know they are on different stacking orders, and return false.
|
||||
// let is_on_same_layer = opaque_layer
|
||||
// .iter()
|
||||
// .zip(layer.iter())
|
||||
// .all(|(a, b)| a.z_index == b.z_index);
|
||||
|
||||
// if !is_on_same_layer {
|
||||
// return false;
|
||||
// }
|
||||
println!("returning false");
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns true if there is no opaque layer containing the given point
|
||||
/// on top of the given level. Layers who are extensions of the queried layer
|
||||
/// are not considered to be on top of queried layer.
|
||||
|
@ -871,27 +921,65 @@ impl<'a> WindowContext<'a> {
|
|||
// and contains the position:
|
||||
// If neither the opaque layer or the queried layer is an extension of the other then
|
||||
// we know they are on different stacking orders, and return false.
|
||||
let is_on_same_layer = opaque_layer
|
||||
.iter()
|
||||
.zip(layer.iter())
|
||||
.all(|(a, b)| a.z_index == b.z_index);
|
||||
// let is_on_same_layer = opaque_layer
|
||||
// .iter()
|
||||
// .zip(layer.iter())
|
||||
// .all(|(a, b)| a.z_index == b.z_index);
|
||||
|
||||
if !is_on_same_layer {
|
||||
return false;
|
||||
}
|
||||
// if !is_on_same_layer {
|
||||
// return false;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn was_top_layer_under_active_drag(
|
||||
/// Returns true if there is no opaque layer containing the given point
|
||||
/// on top of the given level. Layers who are extensions of the queried layer
|
||||
/// are not considered to be on top of queried layer.
|
||||
pub fn is_top_layer(&self, point: &Point<Pixels>, layer: &StackingOrder) -> bool {
|
||||
// Precondition: the depth map is ordered from topmost to bottomost.
|
||||
|
||||
for (opaque_layer, _, bounds) in self.window.next_frame.depth_map.iter() {
|
||||
if layer >= opaque_layer {
|
||||
// The queried layer is either above or is the same as the this opaque layer.
|
||||
// Anything after this point is guaranteed to be below the queried layer.
|
||||
return true;
|
||||
}
|
||||
|
||||
if !bounds.contains(point) {
|
||||
// This opaque layer is above the queried layer but it doesn't contain
|
||||
// the given position, so we can ignore it even if it's above.
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point, we've established that this opaque layer is on top of the queried layer
|
||||
// and contains the position:
|
||||
// If neither the opaque layer or the queried layer is an extension of the other then
|
||||
// we know they are on different stacking orders, and return false.
|
||||
// let is_on_same_layer = opaque_layer
|
||||
// .iter()
|
||||
// .zip(layer.iter())
|
||||
// .all(|(a, b)| a.z_index == b.z_index);
|
||||
|
||||
// if !is_on_same_layer {
|
||||
// return false;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn is_top_layer_under_active_drag(
|
||||
&self,
|
||||
point: &Point<Pixels>,
|
||||
layer: &StackingOrder,
|
||||
) -> bool {
|
||||
// Precondition: the depth map is ordered from topmost to bottomost.
|
||||
|
||||
for (opaque_layer, _, bounds) in self.window.rendered_frame.depth_map.iter() {
|
||||
for (opaque_layer, _, bounds) in self.window.next_frame.depth_map.iter() {
|
||||
if layer >= opaque_layer {
|
||||
// The queried layer is either above or is the same as the this opaque layer.
|
||||
// Anything after this point is guaranteed to be below the queried layer.
|
||||
|
@ -919,14 +1007,15 @@ impl<'a> WindowContext<'a> {
|
|||
// and contains the position:
|
||||
// If neither the opaque layer or the queried layer is an extension of the other then
|
||||
// we know they are on different stacking orders, and return false.
|
||||
let is_on_same_layer = opaque_layer
|
||||
.iter()
|
||||
.zip(layer.iter())
|
||||
.all(|(a, b)| a.z_index == b.z_index);
|
||||
// let is_on_same_layer = opaque_layer
|
||||
// .iter()
|
||||
// .zip(layer.iter())
|
||||
// .all(|(a, b)| a.z_index == b.z_index);
|
||||
|
||||
if !is_on_same_layer {
|
||||
return false;
|
||||
}
|
||||
// if !is_on_same_layer {
|
||||
// return false;
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
|
@ -934,7 +1023,7 @@ impl<'a> WindowContext<'a> {
|
|||
|
||||
/// Called during painting to get the current stacking order.
|
||||
pub fn stacking_order(&self) -> &StackingOrder {
|
||||
&self.window.next_frame.z_index_stack
|
||||
&self.window.z_index_stack
|
||||
}
|
||||
|
||||
/// Produces a new frame and assigns it to `rendered_frame`. To actually show
|
||||
|
@ -950,6 +1039,48 @@ impl<'a> WindowContext<'a> {
|
|||
}
|
||||
|
||||
let root_view = self.window.root_view.take().unwrap();
|
||||
let root_element = self.with_element_context(|cx| {
|
||||
cx.with_z_index(0, |cx| {
|
||||
let available_space = cx.window.viewport_size.map(Into::into);
|
||||
root_view.layout_and_post_layout(Point::default(), available_space, cx)
|
||||
})
|
||||
});
|
||||
|
||||
let active_drag = self.app.active_drag.take();
|
||||
let tooltip_request = self.window.next_frame.tooltip_request.take();
|
||||
|
||||
let drag_or_tooltip_element = if let Some(active_drag) = &active_drag {
|
||||
self.with_element_context(|cx| {
|
||||
cx.with_z_index(ACTIVE_DRAG_Z_INDEX, |cx| {
|
||||
let offset = cx.mouse_position() - active_drag.cursor_offset;
|
||||
let available_space =
|
||||
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
Some(
|
||||
active_drag
|
||||
.view
|
||||
.layout_and_post_layout(offset, available_space, cx),
|
||||
)
|
||||
})
|
||||
})
|
||||
} else if let Some(tooltip_request) = &tooltip_request {
|
||||
self.with_element_context(|cx| {
|
||||
cx.with_z_index(1, |cx| {
|
||||
let available_space =
|
||||
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
Some(tooltip_request.tooltip.view.layout_and_post_layout(
|
||||
tooltip_request.tooltip.cursor_offset,
|
||||
available_space,
|
||||
cx,
|
||||
))
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
assert_eq!(self.window.z_index_stack.len(), 0);
|
||||
self.window.next_stacking_order_ids = vec![0];
|
||||
|
||||
self.with_element_context(|cx| {
|
||||
cx.with_z_index(0, |cx| {
|
||||
cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| {
|
||||
|
@ -967,36 +1098,35 @@ impl<'a> WindowContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let available_space = cx.window.viewport_size.map(Into::into);
|
||||
root_view.draw(Point::default(), available_space, cx);
|
||||
root_view.paint(Point::default(), root_element, cx);
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(active_drag) = self.app.active_drag.take() {
|
||||
if let Some(active_drag) = &active_drag {
|
||||
self.with_element_context(|cx| {
|
||||
cx.with_z_index(ACTIVE_DRAG_Z_INDEX, |cx| {
|
||||
let offset = cx.mouse_position() - active_drag.cursor_offset;
|
||||
let available_space =
|
||||
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
active_drag.view.draw(offset, available_space, cx);
|
||||
})
|
||||
active_drag
|
||||
.view
|
||||
.paint(offset, drag_or_tooltip_element.unwrap(), cx);
|
||||
});
|
||||
});
|
||||
self.active_drag = Some(active_drag);
|
||||
} else if let Some(tooltip_request) = self.window.next_frame.tooltip_request.take() {
|
||||
} else if let Some(tooltip_request) = &tooltip_request {
|
||||
self.with_element_context(|cx| {
|
||||
cx.with_z_index(1, |cx| {
|
||||
let available_space =
|
||||
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
tooltip_request.tooltip.view.draw(
|
||||
tooltip_request.tooltip.view.paint(
|
||||
tooltip_request.tooltip.cursor_offset,
|
||||
available_space,
|
||||
drag_or_tooltip_element.unwrap(),
|
||||
cx,
|
||||
);
|
||||
})
|
||||
});
|
||||
self.window.next_frame.tooltip_request = Some(tooltip_request);
|
||||
}
|
||||
|
||||
self.active_drag = active_drag;
|
||||
self.window.next_frame.tooltip_request = tooltip_request;
|
||||
|
||||
self.window.dirty_views.clear();
|
||||
|
||||
self.window
|
||||
|
@ -1046,6 +1176,9 @@ impl<'a> WindowContext<'a> {
|
|||
let previous_window_active = self.window.rendered_frame.window_active;
|
||||
mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
|
||||
self.window.next_frame.clear();
|
||||
self.window.next_stacking_order_ids = vec![0];
|
||||
self.window.next_root_z_index = 0;
|
||||
self.window.z_index_stack.clear();
|
||||
let current_focus_path = self.window.rendered_frame.focus_path();
|
||||
let current_window_active = self.window.rendered_frame.window_active;
|
||||
|
||||
|
@ -1078,6 +1211,8 @@ impl<'a> WindowContext<'a> {
|
|||
}
|
||||
self.window.refreshing = false;
|
||||
self.window.drawing = false;
|
||||
|
||||
println!("\n\n\n\n");
|
||||
}
|
||||
|
||||
fn present(&self) {
|
||||
|
|
|
@ -59,9 +59,6 @@ pub(crate) struct Frame {
|
|||
pub(crate) dispatch_tree: DispatchTree,
|
||||
pub(crate) scene: Scene,
|
||||
pub(crate) depth_map: Vec<(StackingOrder, EntityId, Bounds<Pixels>)>,
|
||||
pub(crate) z_index_stack: StackingOrder,
|
||||
pub(crate) next_stacking_order_ids: Vec<u16>,
|
||||
pub(crate) next_root_z_index: u16,
|
||||
pub(crate) content_mask_stack: Vec<ContentMask<Pixels>>,
|
||||
pub(crate) element_offset_stack: Vec<Point<Pixels>>,
|
||||
pub(crate) requested_input_handler: Option<RequestedInputHandler>,
|
||||
|
@ -85,9 +82,6 @@ impl Frame {
|
|||
dispatch_tree,
|
||||
scene: Scene::default(),
|
||||
depth_map: Vec::new(),
|
||||
z_index_stack: StackingOrder::default(),
|
||||
next_stacking_order_ids: vec![0],
|
||||
next_root_z_index: 0,
|
||||
content_mask_stack: Vec::new(),
|
||||
element_offset_stack: Vec::new(),
|
||||
requested_input_handler: None,
|
||||
|
@ -107,8 +101,6 @@ impl Frame {
|
|||
self.mouse_listeners.values_mut().for_each(Vec::clear);
|
||||
self.dispatch_tree.clear();
|
||||
self.depth_map.clear();
|
||||
self.next_stacking_order_ids = vec![0];
|
||||
self.next_root_z_index = 0;
|
||||
self.reused_views.clear();
|
||||
self.scene.clear();
|
||||
self.requested_input_handler.take();
|
||||
|
@ -318,6 +310,7 @@ impl<'a> ElementContext<'a> {
|
|||
.next_frame
|
||||
.dispatch_tree
|
||||
.reuse_view(view_id, &mut self.cx.window.rendered_frame.dispatch_tree);
|
||||
|
||||
for view_id in grafted_view_ids {
|
||||
assert!(self.window.next_frame.reused_views.insert(view_id));
|
||||
|
||||
|
@ -353,21 +346,9 @@ impl<'a> ElementContext<'a> {
|
|||
}
|
||||
|
||||
debug_assert!(
|
||||
next_stacking_order_id
|
||||
>= self
|
||||
.window
|
||||
.next_frame
|
||||
.next_stacking_order_ids
|
||||
.last()
|
||||
.copied()
|
||||
.unwrap()
|
||||
next_stacking_order_id >= self.window.next_stacking_order_ids.last().copied().unwrap()
|
||||
);
|
||||
*self
|
||||
.window
|
||||
.next_frame
|
||||
.next_stacking_order_ids
|
||||
.last_mut()
|
||||
.unwrap() = next_stacking_order_id;
|
||||
*self.window.next_stacking_order_ids.last_mut().unwrap() = next_stacking_order_id;
|
||||
}
|
||||
|
||||
/// Push a text style onto the stack, and call a function with that style active.
|
||||
|
@ -440,6 +421,7 @@ impl<'a> ElementContext<'a> {
|
|||
|
||||
/// Invoke the given function with the content mask reset to that
|
||||
/// of the window.
|
||||
/// TODO: Don't call this during paint, that is very bad and broken
|
||||
pub fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
let mask = ContentMask {
|
||||
bounds: Bounds {
|
||||
|
@ -448,10 +430,9 @@ impl<'a> ElementContext<'a> {
|
|||
},
|
||||
};
|
||||
|
||||
let new_root_z_index = post_inc(&mut self.window_mut().next_frame.next_root_z_index);
|
||||
let new_root_z_index = post_inc(&mut self.window_mut().next_root_z_index);
|
||||
let new_stacking_order_id = post_inc(
|
||||
self.window_mut()
|
||||
.next_frame
|
||||
.next_stacking_order_ids
|
||||
.last_mut()
|
||||
.unwrap(),
|
||||
|
@ -461,13 +442,13 @@ impl<'a> ElementContext<'a> {
|
|||
id: new_stacking_order_id,
|
||||
};
|
||||
|
||||
let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
|
||||
let old_stacking_order = mem::take(&mut self.window_mut().z_index_stack);
|
||||
|
||||
self.window_mut().next_frame.z_index_stack.push(new_context);
|
||||
self.window_mut().z_index_stack.push(new_context);
|
||||
self.window_mut().next_frame.content_mask_stack.push(mask);
|
||||
let result = f(self);
|
||||
self.window_mut().next_frame.content_mask_stack.pop();
|
||||
self.window_mut().next_frame.z_index_stack = old_stacking_order;
|
||||
self.window_mut().z_index_stack = old_stacking_order;
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -477,22 +458,29 @@ impl<'a> ElementContext<'a> {
|
|||
pub fn with_z_index<R>(&mut self, z_index: u16, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
let new_stacking_order_id = post_inc(
|
||||
self.window_mut()
|
||||
.next_frame
|
||||
.next_stacking_order_ids
|
||||
.last_mut()
|
||||
.unwrap(),
|
||||
);
|
||||
self.window_mut().next_frame.next_stacking_order_ids.push(0);
|
||||
self.window_mut().next_stacking_order_ids.push(0);
|
||||
let new_context = StackingContext {
|
||||
z_index,
|
||||
id: new_stacking_order_id,
|
||||
};
|
||||
|
||||
self.window_mut().next_frame.z_index_stack.push(new_context);
|
||||
let result = f(self);
|
||||
self.window_mut().next_frame.z_index_stack.pop();
|
||||
self.window_mut().z_index_stack.push(new_context);
|
||||
|
||||
if self.window.z_index_stack.len() == 2 {
|
||||
let last = self.window.z_index_stack.last().unwrap();
|
||||
if last.z_index == 0 && last.id == 5 {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
self.window_mut().next_frame.next_stacking_order_ids.pop();
|
||||
let result = f(self);
|
||||
self.window_mut().z_index_stack.pop();
|
||||
|
||||
self.window_mut().next_stacking_order_ids.pop();
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -667,7 +655,7 @@ impl<'a> ElementContext<'a> {
|
|||
shadow_bounds.origin += shadow.offset;
|
||||
shadow_bounds.dilate(shadow.spread_radius);
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
Shadow {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -693,7 +681,7 @@ impl<'a> ElementContext<'a> {
|
|||
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
Quad {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -721,7 +709,7 @@ impl<'a> ElementContext<'a> {
|
|||
window
|
||||
.next_frame
|
||||
.scene
|
||||
.insert(&window.next_frame.z_index_stack, path.scale(scale_factor));
|
||||
.insert(&window.z_index_stack, path.scale(scale_factor));
|
||||
}
|
||||
|
||||
/// Paint an underline into the scene for the next frame at the current z-index.
|
||||
|
@ -746,7 +734,7 @@ impl<'a> ElementContext<'a> {
|
|||
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
Underline {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -778,7 +766,7 @@ impl<'a> ElementContext<'a> {
|
|||
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
Underline {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -838,7 +826,7 @@ impl<'a> ElementContext<'a> {
|
|||
let view_id = self.parent_view_id();
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
MonochromeSprite {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -896,7 +884,7 @@ impl<'a> ElementContext<'a> {
|
|||
let window = &mut *self.window;
|
||||
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
PolychromeSprite {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -942,7 +930,7 @@ impl<'a> ElementContext<'a> {
|
|||
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
MonochromeSprite {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -981,7 +969,7 @@ impl<'a> ElementContext<'a> {
|
|||
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
PolychromeSprite {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -1006,7 +994,7 @@ impl<'a> ElementContext<'a> {
|
|||
let view_id = self.parent_view_id();
|
||||
let window = &mut *self.window;
|
||||
window.next_frame.scene.insert(
|
||||
&window.next_frame.z_index_stack,
|
||||
&window.z_index_stack,
|
||||
crate::Surface {
|
||||
view_id: view_id.into(),
|
||||
layer_id: 0,
|
||||
|
@ -1092,9 +1080,10 @@ impl<'a> ElementContext<'a> {
|
|||
.requested_style(layout_id)
|
||||
}
|
||||
|
||||
/// Called during painting to track which z-index is on top at each pixel position
|
||||
/// TODO
|
||||
pub fn add_opaque_layer(&mut self, bounds: Bounds<Pixels>) {
|
||||
let stacking_order = self.window.next_frame.z_index_stack.clone();
|
||||
assert_ne!(self.window.z_index_stack.last().cloned().unwrap().id, 6);
|
||||
let stacking_order = self.window.z_index_stack.clone();
|
||||
let view_id = self.parent_view_id();
|
||||
let depth_map = &mut self.window.next_frame.depth_map;
|
||||
match depth_map.binary_search_by(|(level, _, _)| stacking_order.cmp(level)) {
|
||||
|
@ -1141,8 +1130,8 @@ impl<'a> ElementContext<'a> {
|
|||
}
|
||||
|
||||
/// Invoke the given function with the given view id present on the view stack.
|
||||
/// This is a fairly low-level method used to paint views.
|
||||
pub fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
/// This is a fairly low-level method used to in the post-layout and paint phase of views.
|
||||
pub fn with_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
let text_system = self.text_system().clone();
|
||||
text_system.with_view(view_id, || {
|
||||
if self.window.next_frame.view_stack.last() == Some(&view_id) {
|
||||
|
@ -1188,7 +1177,7 @@ impl<'a> ElementContext<'a> {
|
|||
mut handler: impl FnMut(&Event, DispatchPhase, &mut ElementContext) + 'static,
|
||||
) {
|
||||
let view_id = self.parent_view_id();
|
||||
let order = self.window.next_frame.z_index_stack.clone();
|
||||
let order = self.window.z_index_stack.clone();
|
||||
self.window
|
||||
.next_frame
|
||||
.mouse_listeners
|
||||
|
|
|
@ -10,37 +10,49 @@ impl Render for ZIndexStory {
|
|||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
Story::container().child(Story::title("z-index")).child(
|
||||
div()
|
||||
.flex()
|
||||
.debug_selector(|| "outer_button".into())
|
||||
.size_20()
|
||||
.bg(gpui::red())
|
||||
.hover(|s| s.bg(gpui::green()))
|
||||
.child(
|
||||
div()
|
||||
.w(px(250.))
|
||||
.child(Story::label("z-index: auto"))
|
||||
.child(ZIndexExample::new(0)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(250.))
|
||||
.child(Story::label("z-index: 1"))
|
||||
.child(ZIndexExample::new(1)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(250.))
|
||||
.child(Story::label("z-index: 3"))
|
||||
.child(ZIndexExample::new(3)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(250.))
|
||||
.child(Story::label("z-index: 5"))
|
||||
.child(ZIndexExample::new(5)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(250.))
|
||||
.child(Story::label("z-index: 7"))
|
||||
.child(ZIndexExample::new(7)),
|
||||
),
|
||||
.debug_selector(|| "inner_button".into())
|
||||
.z_index(0)
|
||||
.size_8()
|
||||
.bg(gpui::yellow())
|
||||
.hover(|s| s.bg(gpui::blue())),
|
||||
), // div()
|
||||
// .flex()
|
||||
// .child(
|
||||
// div()
|
||||
// .w(px(250.))
|
||||
// .child(Story::label("z-index: auto"))
|
||||
// .child(ZIndexExample::new(0)),
|
||||
// )
|
||||
// .child(
|
||||
// div()
|
||||
// .w(px(250.))
|
||||
// .child(Story::label("z-index: 1"))
|
||||
// .child(ZIndexExample::new(1)),
|
||||
// )
|
||||
// .child(
|
||||
// div()
|
||||
// .w(px(250.))
|
||||
// .child(Story::label("z-index: 3"))
|
||||
// .child(ZIndexExample::new(3)),
|
||||
// )
|
||||
// .child(
|
||||
// div()
|
||||
// .w(px(250.))
|
||||
// .child(Story::label("z-index: 5"))
|
||||
// .child(ZIndexExample::new(5)),
|
||||
// )
|
||||
// .child(
|
||||
// div()
|
||||
// .w(px(250.))
|
||||
// .child(Story::label("z-index: 7"))
|
||||
// .child(ZIndexExample::new(7)),
|
||||
// ),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,26 +37,27 @@ fn main() {
|
|||
|
||||
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
|
||||
|
||||
let args = Args::parse();
|
||||
// let args = Args::parse();
|
||||
|
||||
let story_selector = args.story.clone().unwrap_or_else(|| {
|
||||
let stories = ComponentStory::iter().collect::<Vec<_>>();
|
||||
// let story_selector = args.story.clone().unwrap_or_else(|| {
|
||||
// let stories = ComponentStory::iter().collect::<Vec<_>>();
|
||||
|
||||
ctrlc::set_handler(move || {}).unwrap();
|
||||
// ctrlc::set_handler(move || {}).unwrap();
|
||||
|
||||
let result = FuzzySelect::new()
|
||||
.with_prompt("Choose a story to run:")
|
||||
.items(&stories)
|
||||
.interact();
|
||||
// let result = FuzzySelect::new()
|
||||
// .with_prompt("Choose a story to run:")
|
||||
// .items(&stories)
|
||||
// .interact();
|
||||
|
||||
let Ok(selection) = result else {
|
||||
dialoguer::console::Term::stderr().show_cursor().unwrap();
|
||||
std::process::exit(0);
|
||||
};
|
||||
// let Ok(selection) = result else {
|
||||
// dialoguer::console::Term::stderr().show_cursor().unwrap();
|
||||
// std::process::exit(0);
|
||||
// };
|
||||
|
||||
StorySelector::Component(stories[selection])
|
||||
});
|
||||
let theme_name = args.theme.unwrap_or("One Dark".to_string());
|
||||
// StorySelector::Component(stories[selection])
|
||||
// });
|
||||
// let theme_name = args.theme.unwrap_or("One Dark".to_string());
|
||||
let theme_name = "One Dark".to_string();
|
||||
|
||||
gpui::App::new().with_assets(Assets).run(move |cx| {
|
||||
load_embedded_fonts(cx).unwrap();
|
||||
|
@ -69,7 +70,7 @@ fn main() {
|
|||
|
||||
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
|
||||
|
||||
let selector = story_selector;
|
||||
// let selector = story_selector;
|
||||
|
||||
let theme_registry = ThemeRegistry::global(cx);
|
||||
let mut theme_settings = ThemeSettings::get_global(cx).clone();
|
||||
|
@ -91,7 +92,8 @@ fn main() {
|
|||
let ui_font_size = ThemeSettings::get_global(cx).ui_font_size;
|
||||
cx.set_rem_size(ui_font_size);
|
||||
|
||||
cx.new_view(|cx| StoryWrapper::new(selector.story(cx)))
|
||||
// cx.new_view(|cx| StoryWrapper::new(selector.story(cx)))
|
||||
cx.new_view(|cx| stories::ZIndexStory)
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -493,7 +493,7 @@ impl TerminalElement {
|
|||
bounds,
|
||||
stacking_order: cx.stacking_order().clone(),
|
||||
};
|
||||
if interactive_text_bounds.visibly_contains(&cx.mouse_position(), cx) {
|
||||
if interactive_text_bounds.did_visibly_contains(&cx.mouse_position(), cx) {
|
||||
if self.can_navigate_to_selected_word && last_hovered_word.is_some() {
|
||||
cx.set_cursor_style(gpui::CursorStyle::PointingHand)
|
||||
} else {
|
||||
|
@ -658,7 +658,7 @@ impl TerminalElement {
|
|||
}
|
||||
|
||||
if e.pressed_button.is_some() && !cx.has_active_drag() {
|
||||
let visibly_contains = interactive_bounds.visibly_contains(&e.position, cx);
|
||||
let visibly_contains = interactive_bounds.did_visibly_contains(&e.position, cx);
|
||||
terminal.update(cx, |terminal, cx| {
|
||||
if !terminal.selection_started() {
|
||||
if visibly_contains {
|
||||
|
@ -672,7 +672,7 @@ impl TerminalElement {
|
|||
})
|
||||
}
|
||||
|
||||
if interactive_bounds.visibly_contains(&e.position, cx) {
|
||||
if interactive_bounds.did_visibly_contains(&e.position, cx) {
|
||||
terminal.update(cx, |terminal, cx| {
|
||||
terminal.mouse_move(&e, origin);
|
||||
cx.notify();
|
||||
|
|
|
@ -212,7 +212,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
|
|||
// want a click on the toggle to re-open it.
|
||||
cx.on_mouse_event(move |e: &MouseDownEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&e.position, cx)
|
||||
&& interactive_bounds.did_visibly_contains(&e.position, cx)
|
||||
{
|
||||
cx.stop_propagation()
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
|
|||
cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& event.button == MouseButton::Right
|
||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||
&& interactive_bounds.did_visibly_contains(&event.position, cx)
|
||||
{
|
||||
cx.stop_propagation();
|
||||
cx.prevent_default();
|
||||
|
|
|
@ -758,7 +758,7 @@ mod element {
|
|||
bounds: handle_bounds,
|
||||
stacking_order: cx.stacking_order().clone(),
|
||||
};
|
||||
if interactive_handle_bounds.visibly_contains(&cx.mouse_position(), cx) {
|
||||
if interactive_handle_bounds.did_visibly_contains(&cx.mouse_position(), cx) {
|
||||
cx.set_cursor_style(match axis {
|
||||
Axis::Vertical => CursorStyle::ResizeUpDown,
|
||||
Axis::Horizontal => CursorStyle::ResizeLeftRight,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue