Move application of content mask and z-index into Interactivity::paint
This allows the content mask to correctly apply to bounds used in event handlers, which prevents content under opaque borders from being hovered in overflow hidden containers. Co-Authored-By: Antonio <antonio@zed.dev> Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
fffb30ac6d
commit
15f16f08d9
4 changed files with 643 additions and 604 deletions
|
@ -826,18 +826,12 @@ impl Element for Div {
|
||||||
content_size,
|
content_size,
|
||||||
&mut element_state.interactive_state,
|
&mut element_state.interactive_state,
|
||||||
cx,
|
cx,
|
||||||
|style, scroll_offset, cx| {
|
|_style, scroll_offset, cx| {
|
||||||
style.paint(bounds, cx, |cx| {
|
|
||||||
cx.with_text_style(style.text_style().cloned(), |cx| {
|
|
||||||
cx.with_content_mask(style.overflow_mask(bounds), |cx| {
|
|
||||||
cx.with_element_offset(scroll_offset, |cx| {
|
cx.with_element_offset(scroll_offset, |cx| {
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
child.paint(cx);
|
child.paint(cx);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -965,7 +959,7 @@ impl Interactivity {
|
||||||
content_size: Size<Pixels>,
|
content_size: Size<Pixels>,
|
||||||
element_state: &mut InteractiveElementState,
|
element_state: &mut InteractiveElementState,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
f: impl FnOnce(Style, Point<Pixels>, &mut WindowContext),
|
f: impl FnOnce(&Style, Point<Pixels>, &mut WindowContext),
|
||||||
) {
|
) {
|
||||||
let style = self.compute_style(Some(bounds), element_state, cx);
|
let style = self.compute_style(Some(bounds), element_state, cx);
|
||||||
|
|
||||||
|
@ -975,9 +969,14 @@ impl Interactivity {
|
||||||
|
|
||||||
let z_index = style.z_index.unwrap_or(0);
|
let z_index = style.z_index.unwrap_or(0);
|
||||||
cx.with_z_index(z_index, |cx| {
|
cx.with_z_index(z_index, |cx| {
|
||||||
|
style.paint(bounds, cx, |cx| {
|
||||||
|
cx.with_text_style(style.text_style().cloned(), |cx| {
|
||||||
|
cx.with_content_mask(style.overflow_mask(bounds, cx.rem_size()), |cx| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
if self.element_id.is_some()
|
if self.element_id.is_some()
|
||||||
&& (style.debug || style.debug_below || cx.has_global::<crate::DebugBelow>())
|
&& (style.debug
|
||||||
|
|| style.debug_below
|
||||||
|
|| cx.has_global::<crate::DebugBelow>())
|
||||||
&& bounds.contains(&cx.mouse_position())
|
&& bounds.contains(&cx.mouse_position())
|
||||||
{
|
{
|
||||||
const FONT_SIZE: crate::Pixels = crate::Pixels(10.);
|
const FONT_SIZE: crate::Pixels = crate::Pixels(10.);
|
||||||
|
@ -1020,19 +1019,23 @@ impl Interactivity {
|
||||||
});
|
});
|
||||||
|
|
||||||
let hovered = bounds.contains(&cx.mouse_position());
|
let hovered = bounds.contains(&cx.mouse_position());
|
||||||
cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
|
cx.on_mouse_event(
|
||||||
|
move |event: &MouseMoveEvent, phase, cx| {
|
||||||
if phase == DispatchPhase::Capture {
|
if phase == DispatchPhase::Capture {
|
||||||
if bounds.contains(&event.position) != hovered {
|
if bounds.contains(&event.position) != hovered {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
cx.on_mouse_event({
|
cx.on_mouse_event({
|
||||||
let location = self.location.clone().unwrap();
|
let location = self.location.clone().unwrap();
|
||||||
let text_bounds = text_bounds.clone();
|
let text_bounds = text_bounds.clone();
|
||||||
move |e: &crate::MouseDownEvent, phase, cx| {
|
move |e: &crate::MouseDownEvent, phase, cx| {
|
||||||
if text_bounds.contains(&e.position) && phase.capture() {
|
if text_bounds.contains(&e.position)
|
||||||
|
&& phase.capture()
|
||||||
|
{
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
let Ok(dir) = std::env::current_dir() else {
|
let Ok(dir) = std::env::current_dir() else {
|
||||||
return;
|
return;
|
||||||
|
@ -1061,7 +1064,10 @@ impl Interactivity {
|
||||||
cx.paint_quad(crate::outline(
|
cx.paint_quad(crate::outline(
|
||||||
crate::Bounds {
|
crate::Bounds {
|
||||||
origin: bounds.origin
|
origin: bounds.origin
|
||||||
+ crate::point(crate::px(0.), FONT_SIZE - px(2.)),
|
+ crate::point(
|
||||||
|
crate::px(0.),
|
||||||
|
FONT_SIZE - px(2.),
|
||||||
|
),
|
||||||
size: crate::Size {
|
size: crate::Size {
|
||||||
width: text_bounds.size.width,
|
width: text_bounds.size.width,
|
||||||
height: crate::px(1.),
|
height: crate::px(1.),
|
||||||
|
@ -1087,10 +1093,9 @@ impl Interactivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.block_mouse
|
if self.block_mouse
|
||||||
|| style
|
|| style.background.as_ref().is_some_and(|fill| {
|
||||||
.background
|
fill.color().is_some_and(|color| !color.is_transparent())
|
||||||
.as_ref()
|
})
|
||||||
.is_some_and(|fill| fill.color().is_some_and(|color| !color.is_transparent()))
|
|
||||||
{
|
{
|
||||||
cx.add_opaque_layer(bounds)
|
cx.add_opaque_layer(bounds)
|
||||||
}
|
}
|
||||||
|
@ -1197,15 +1202,15 @@ impl Interactivity {
|
||||||
move |event: &MouseUpEvent, phase, cx| {
|
move |event: &MouseUpEvent, phase, cx| {
|
||||||
if let Some(drag) = &cx.active_drag {
|
if let Some(drag) = &cx.active_drag {
|
||||||
if phase == DispatchPhase::Bubble
|
if phase == DispatchPhase::Bubble
|
||||||
&& interactive_bounds.drag_target_contains(&event.position, cx)
|
&& interactive_bounds
|
||||||
|
.drag_target_contains(&event.position, cx)
|
||||||
{
|
{
|
||||||
let drag_state_type = drag.value.as_ref().type_id();
|
let drag_state_type = drag.value.as_ref().type_id();
|
||||||
for (drop_state_type, listener) in &drop_listeners {
|
for (drop_state_type, listener) in &drop_listeners {
|
||||||
if *drop_state_type == drag_state_type {
|
if *drop_state_type == drag_state_type {
|
||||||
let drag = cx
|
let drag = cx.active_drag.take().expect(
|
||||||
.active_drag
|
"checked for type drag state type above",
|
||||||
.take()
|
);
|
||||||
.expect("checked for type drag state type above");
|
|
||||||
|
|
||||||
listener(drag.value.as_ref(), cx);
|
listener(drag.value.as_ref(), cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -1256,8 +1261,11 @@ impl Interactivity {
|
||||||
&& (event.position - mouse_down.position).magnitude()
|
&& (event.position - mouse_down.position).magnitude()
|
||||||
> DRAG_THRESHOLD
|
> DRAG_THRESHOLD
|
||||||
{
|
{
|
||||||
if let Some((drag_value, drag_listener)) = drag_listener.take() {
|
if let Some((drag_value, drag_listener)) =
|
||||||
*clicked_state.borrow_mut() = ElementClickedState::default();
|
drag_listener.take()
|
||||||
|
{
|
||||||
|
*clicked_state.borrow_mut() =
|
||||||
|
ElementClickedState::default();
|
||||||
let cursor_offset = event.position - bounds.origin;
|
let cursor_offset = event.position - bounds.origin;
|
||||||
let drag = (drag_listener)(drag_value.as_ref(), cx);
|
let drag = (drag_listener)(drag_value.as_ref(), cx);
|
||||||
cx.active_drag = Some(AnyDrag {
|
cx.active_drag = Some(AnyDrag {
|
||||||
|
@ -1282,7 +1290,8 @@ impl Interactivity {
|
||||||
// so that it happens even if another event handler stops
|
// so that it happens even if another event handler stops
|
||||||
// propagation.
|
// propagation.
|
||||||
DispatchPhase::Capture => {
|
DispatchPhase::Capture => {
|
||||||
let mut pending_mouse_down = pending_mouse_down.borrow_mut();
|
let mut pending_mouse_down =
|
||||||
|
pending_mouse_down.borrow_mut();
|
||||||
if pending_mouse_down.is_some() {
|
if pending_mouse_down.is_some() {
|
||||||
captured_mouse_down = pending_mouse_down.take();
|
captured_mouse_down = pending_mouse_down.take();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -1291,7 +1300,9 @@ impl Interactivity {
|
||||||
// Fire click handlers during the bubble phase.
|
// Fire click handlers during the bubble phase.
|
||||||
DispatchPhase::Bubble => {
|
DispatchPhase::Bubble => {
|
||||||
if let Some(mouse_down) = captured_mouse_down.take() {
|
if let Some(mouse_down) = captured_mouse_down.take() {
|
||||||
if interactive_bounds.visibly_contains(&event.position, cx) {
|
if interactive_bounds
|
||||||
|
.visibly_contains(&event.position, cx)
|
||||||
|
{
|
||||||
let mouse_click = ClickEvent {
|
let mouse_click = ClickEvent {
|
||||||
down: mouse_down,
|
down: mouse_down,
|
||||||
up: event.clone(),
|
up: event.clone(),
|
||||||
|
@ -1321,7 +1332,8 @@ impl Interactivity {
|
||||||
if phase != DispatchPhase::Bubble {
|
if phase != DispatchPhase::Bubble {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let is_hovered = interactive_bounds.visibly_contains(&event.position, cx)
|
let is_hovered = interactive_bounds
|
||||||
|
.visibly_contains(&event.position, cx)
|
||||||
&& !cx.has_active_drag()
|
&& !cx.has_active_drag()
|
||||||
&& has_mouse_down.borrow().is_none();
|
&& has_mouse_down.borrow().is_none();
|
||||||
let mut was_hovered = was_hovered.borrow_mut();
|
let mut was_hovered = was_hovered.borrow_mut();
|
||||||
|
@ -1347,7 +1359,8 @@ impl Interactivity {
|
||||||
let interactive_bounds = interactive_bounds.clone();
|
let interactive_bounds = interactive_bounds.clone();
|
||||||
|
|
||||||
cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
|
cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
|
||||||
let is_hovered = interactive_bounds.visibly_contains(&event.position, cx)
|
let is_hovered = interactive_bounds
|
||||||
|
.visibly_contains(&event.position, cx)
|
||||||
&& pending_mouse_down.borrow().is_none();
|
&& pending_mouse_down.borrow().is_none();
|
||||||
if !is_hovered {
|
if !is_hovered {
|
||||||
active_tooltip.borrow_mut().take();
|
active_tooltip.borrow_mut().take();
|
||||||
|
@ -1366,13 +1379,15 @@ impl Interactivity {
|
||||||
move |mut cx| async move {
|
move |mut cx| async move {
|
||||||
cx.background_executor().timer(TOOLTIP_DELAY).await;
|
cx.background_executor().timer(TOOLTIP_DELAY).await;
|
||||||
cx.update(|_, cx| {
|
cx.update(|_, cx| {
|
||||||
active_tooltip.borrow_mut().replace(ActiveTooltip {
|
active_tooltip.borrow_mut().replace(
|
||||||
|
ActiveTooltip {
|
||||||
tooltip: Some(AnyTooltip {
|
tooltip: Some(AnyTooltip {
|
||||||
view: tooltip_builder(cx),
|
view: tooltip_builder(cx),
|
||||||
cursor_offset: cx.mouse_position(),
|
cursor_offset: cx.mouse_position(),
|
||||||
}),
|
}),
|
||||||
_task: None,
|
_task: None,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
@ -1426,9 +1441,11 @@ impl Interactivity {
|
||||||
if phase == DispatchPhase::Bubble && !cx.default_prevented() {
|
if phase == DispatchPhase::Bubble && !cx.default_prevented() {
|
||||||
let group = active_group_bounds
|
let group = active_group_bounds
|
||||||
.map_or(false, |bounds| bounds.contains(&down.position));
|
.map_or(false, |bounds| bounds.contains(&down.position));
|
||||||
let element = interactive_bounds.visibly_contains(&down.position, cx);
|
let element =
|
||||||
|
interactive_bounds.visibly_contains(&down.position, cx);
|
||||||
if group || element {
|
if group || element {
|
||||||
*clicked_state.borrow_mut() = ElementClickedState { group, element };
|
*clicked_state.borrow_mut() =
|
||||||
|
ElementClickedState { group, element };
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1458,13 +1475,13 @@ impl Interactivity {
|
||||||
let delta = event.delta.pixel_delta(line_height);
|
let delta = event.delta.pixel_delta(line_height);
|
||||||
|
|
||||||
if overflow.x == Overflow::Scroll {
|
if overflow.x == Overflow::Scroll {
|
||||||
scroll_offset.x =
|
scroll_offset.x = (scroll_offset.x + delta.x)
|
||||||
(scroll_offset.x + delta.x).clamp(-scroll_max.width, px(0.));
|
.clamp(-scroll_max.width, px(0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
if overflow.y == Overflow::Scroll {
|
if overflow.y == Overflow::Scroll {
|
||||||
scroll_offset.y =
|
scroll_offset.y = (scroll_offset.y + delta.y)
|
||||||
(scroll_offset.y + delta.y).clamp(-scroll_max.height, px(0.));
|
.clamp(-scroll_max.height, px(0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
if *scroll_offset != old_scroll_offset {
|
if *scroll_offset != old_scroll_offset {
|
||||||
|
@ -1507,14 +1524,7 @@ impl Interactivity {
|
||||||
cx.on_action(action_type, listener)
|
cx.on_action(action_type, listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.with_z_index(style.z_index.unwrap_or(0), |cx| {
|
f(&style, scroll_offset.unwrap_or_default(), cx)
|
||||||
if style.background.as_ref().is_some_and(|fill| {
|
|
||||||
fill.color().is_some_and(|color| !color.is_transparent())
|
|
||||||
}) {
|
|
||||||
cx.add_opaque_layer(bounds)
|
|
||||||
}
|
|
||||||
f(style, scroll_offset.unwrap_or_default(), cx)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1522,6 +1532,9 @@ impl Interactivity {
|
||||||
GroupBounds::pop(group, cx);
|
GroupBounds::pop(group, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_style(
|
pub fn compute_style(
|
||||||
|
|
|
@ -200,7 +200,6 @@ impl Element for UniformList {
|
||||||
bounds.lower_right() - point(border.right + padding.right, border.bottom),
|
bounds.lower_right() - point(border.right + padding.right, border.bottom),
|
||||||
);
|
);
|
||||||
|
|
||||||
style.paint(bounds, cx, |cx| {
|
|
||||||
if self.item_count > 0 {
|
if self.item_count > 0 {
|
||||||
let content_height =
|
let content_height =
|
||||||
item_height * self.item_count + padding.top + padding.bottom;
|
item_height * self.item_count + padding.top + padding.bottom;
|
||||||
|
@ -222,9 +221,9 @@ impl Element for UniformList {
|
||||||
|
|
||||||
let first_visible_element_ix =
|
let first_visible_element_ix =
|
||||||
(-(scroll_offset.y + padding.top) / item_height).floor() as usize;
|
(-(scroll_offset.y + padding.top) / item_height).floor() as usize;
|
||||||
let last_visible_element_ix =
|
let last_visible_element_ix = ((-scroll_offset.y + padded_bounds.size.height)
|
||||||
((-scroll_offset.y + padded_bounds.size.height) / item_height).ceil()
|
/ item_height)
|
||||||
as usize;
|
.ceil() as usize;
|
||||||
let visible_range = first_visible_element_ix
|
let visible_range = first_visible_element_ix
|
||||||
..cmp::min(last_visible_element_ix, self.item_count);
|
..cmp::min(last_visible_element_ix, self.item_count);
|
||||||
|
|
||||||
|
@ -247,7 +246,6 @@ impl Element for UniformList {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,16 +258,30 @@ impl Style {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn overflow_mask(&self, bounds: Bounds<Pixels>) -> Option<ContentMask<Pixels>> {
|
pub fn overflow_mask(
|
||||||
|
&self,
|
||||||
|
bounds: Bounds<Pixels>,
|
||||||
|
rem_size: Pixels,
|
||||||
|
) -> Option<ContentMask<Pixels>> {
|
||||||
match self.overflow {
|
match self.overflow {
|
||||||
Point {
|
Point {
|
||||||
x: Overflow::Visible,
|
x: Overflow::Visible,
|
||||||
y: Overflow::Visible,
|
y: Overflow::Visible,
|
||||||
} => None,
|
} => None,
|
||||||
_ => {
|
_ => {
|
||||||
let current_mask = bounds;
|
let mut min = bounds.origin;
|
||||||
let min = current_mask.origin;
|
let mut max = bounds.lower_right();
|
||||||
let max = current_mask.lower_right();
|
|
||||||
|
if self
|
||||||
|
.border_color
|
||||||
|
.map_or(false, |color| !color.is_transparent())
|
||||||
|
{
|
||||||
|
min.x += self.border_widths.left.to_pixels(rem_size);
|
||||||
|
max.x -= self.border_widths.right.to_pixels(rem_size);
|
||||||
|
min.y += self.border_widths.top.to_pixels(rem_size);
|
||||||
|
max.y -= self.border_widths.bottom.to_pixels(rem_size);
|
||||||
|
}
|
||||||
|
|
||||||
let bounds = match (
|
let bounds = match (
|
||||||
self.overflow.x == Overflow::Visible,
|
self.overflow.x == Overflow::Visible,
|
||||||
self.overflow.y == Overflow::Visible,
|
self.overflow.y == Overflow::Visible,
|
||||||
|
@ -285,61 +299,62 @@ impl Style {
|
||||||
point(bounds.lower_right().x, max.y),
|
point(bounds.lower_right().x, max.y),
|
||||||
),
|
),
|
||||||
// both hidden
|
// both hidden
|
||||||
(false, false) => bounds,
|
(false, false) => Bounds::from_corners(min, max),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(ContentMask { bounds })
|
Some(ContentMask { bounds })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_text_style<C, F, R>(&self, cx: &mut C, f: F) -> R
|
// pub fn apply_text_style<C, F, R>(&self, cx: &mut C, f: F) -> R
|
||||||
where
|
// where
|
||||||
C: BorrowAppContext,
|
// C: BorrowAppContext,
|
||||||
F: FnOnce(&mut C) -> R,
|
// F: FnOnce(&mut C) -> R,
|
||||||
{
|
// {
|
||||||
if self.text.is_some() {
|
// if self.text.is_some() {
|
||||||
cx.with_text_style(Some(self.text.clone()), f)
|
// cx.with_text_style(Some(self.text.clone()), f)
|
||||||
} else {
|
// } else {
|
||||||
f(cx)
|
// f(cx)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Apply overflow to content mask
|
// /// Apply overflow to content mask
|
||||||
pub fn apply_overflow<C, F, R>(&self, bounds: Bounds<Pixels>, cx: &mut C, f: F) -> R
|
// pub fn apply_overflow<C, F, R>(&self, bounds: Bounds<Pixels>, cx: &mut C, f: F) -> R
|
||||||
where
|
// where
|
||||||
C: BorrowWindow,
|
// C: BorrowWindow,
|
||||||
F: FnOnce(&mut C) -> R,
|
// F: FnOnce(&mut C) -> R,
|
||||||
{
|
// {
|
||||||
let current_mask = cx.content_mask();
|
// let current_mask = cx.content_mask();
|
||||||
|
|
||||||
let min = current_mask.bounds.origin;
|
// let min = current_mask.bounds.origin;
|
||||||
let max = current_mask.bounds.lower_right();
|
// let max = current_mask.bounds.lower_right();
|
||||||
|
|
||||||
let mask_bounds = match (
|
// let mask_bounds = match (
|
||||||
self.overflow.x == Overflow::Visible,
|
// self.overflow.x == Overflow::Visible,
|
||||||
self.overflow.y == Overflow::Visible,
|
// self.overflow.y == Overflow::Visible,
|
||||||
) {
|
// ) {
|
||||||
// x and y both visible
|
// // x and y both visible
|
||||||
(true, true) => return f(cx),
|
// (true, true) => return f(cx),
|
||||||
// x visible, y hidden
|
// // x visible, y hidden
|
||||||
(true, false) => Bounds::from_corners(
|
// (true, false) => Bounds::from_corners(
|
||||||
point(min.x, bounds.origin.y),
|
// point(min.x, bounds.origin.y),
|
||||||
point(max.x, bounds.lower_right().y),
|
// point(max.x, bounds.lower_right().y),
|
||||||
),
|
// ),
|
||||||
// x hidden, y visible
|
// // x hidden, y visible
|
||||||
(false, true) => Bounds::from_corners(
|
// (false, true) => Bounds::from_corners(
|
||||||
point(bounds.origin.x, min.y),
|
// point(bounds.origin.x, min.y),
|
||||||
point(bounds.lower_right().x, max.y),
|
// point(bounds.lower_right().x, max.y),
|
||||||
),
|
// ),
|
||||||
// both hidden
|
// // both hidden
|
||||||
(false, false) => bounds,
|
// (false, false) => bounds,
|
||||||
};
|
// };
|
||||||
let mask = ContentMask {
|
// let mask = ContentMask {
|
||||||
bounds: mask_bounds,
|
// bounds: mask_bounds,
|
||||||
};
|
// };
|
||||||
|
|
||||||
cx.with_content_mask(Some(mask), f)
|
// cx.with_content_mask(Some(mask), f)
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Paints the background of an element styled with this style.
|
/// Paints the background of an element styled with this style.
|
||||||
pub fn paint(
|
pub fn paint(
|
||||||
|
@ -369,14 +384,14 @@ impl Style {
|
||||||
});
|
});
|
||||||
|
|
||||||
let background_color = self.background.as_ref().and_then(Fill::color);
|
let background_color = self.background.as_ref().and_then(Fill::color);
|
||||||
if background_color.is_some() || self.is_border_visible() {
|
if background_color.is_some() {
|
||||||
cx.with_z_index(1, |cx| {
|
cx.with_z_index(1, |cx| {
|
||||||
cx.paint_quad(quad(
|
cx.paint_quad(quad(
|
||||||
bounds,
|
bounds,
|
||||||
self.corner_radii.to_pixels(bounds.size, rem_size),
|
self.corner_radii.to_pixels(bounds.size, rem_size),
|
||||||
background_color.unwrap_or_default(),
|
background_color.unwrap_or_default(),
|
||||||
self.border_widths.to_pixels(rem_size),
|
Edges::default(),
|
||||||
self.border_color.unwrap_or_default(),
|
Hsla::transparent_black(),
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -385,6 +400,18 @@ impl Style {
|
||||||
continuation(cx);
|
continuation(cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if self.is_border_visible() {
|
||||||
|
cx.with_z_index(3, |cx| {
|
||||||
|
cx.paint_quad(quad(
|
||||||
|
bounds,
|
||||||
|
self.corner_radii.to_pixels(bounds.size, rem_size),
|
||||||
|
Hsla::transparent_black(),
|
||||||
|
self.border_widths.to_pixels(rem_size),
|
||||||
|
self.border_color.unwrap_or_default(),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
if self.debug_below {
|
if self.debug_below {
|
||||||
cx.remove_global::<DebugBelow>();
|
cx.remove_global::<DebugBelow>();
|
||||||
|
|
|
@ -537,6 +537,7 @@ impl Render for Dock {
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
.border_color(cx.theme().colors().border)
|
.border_color(cx.theme().colors().border)
|
||||||
|
.overflow_hidden()
|
||||||
.map(|this| match self.position().axis() {
|
.map(|this| match self.position().axis() {
|
||||||
Axis::Horizontal => this.w(px(size)).h_full().flex_row(),
|
Axis::Horizontal => this.w(px(size)).h_full().flex_row(),
|
||||||
Axis::Vertical => this.h(px(size)).w_full().flex_col(),
|
Axis::Vertical => this.h(px(size)).w_full().flex_col(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue