Merge branch 'main' into taffy
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
commit
740b105330
41 changed files with 536 additions and 113 deletions
|
@ -54,8 +54,8 @@ pub struct Window {
|
|||
cursor_regions: Vec<CursorRegion>,
|
||||
mouse_regions: Vec<(MouseRegion, usize)>,
|
||||
last_mouse_moved_event: Option<Event>,
|
||||
pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
|
||||
pub(crate) clicked_region_ids: HashSet<MouseRegionId>,
|
||||
pub(crate) hovered_region_ids: Vec<MouseRegionId>,
|
||||
pub(crate) clicked_region_ids: Vec<MouseRegionId>,
|
||||
pub(crate) clicked_region: Option<(MouseRegionId, MouseButton)>,
|
||||
mouse_position: Vector2F,
|
||||
text_layout_cache: TextLayoutCache,
|
||||
|
@ -690,6 +690,7 @@ impl<'a> WindowContext<'a> {
|
|||
let mut highest_z_index = None;
|
||||
let mouse_position = self.window.mouse_position.clone();
|
||||
let window = &mut *self.window;
|
||||
let prev_hovered_regions = mem::take(&mut window.hovered_region_ids);
|
||||
for (region, z_index) in window.mouse_regions.iter().rev() {
|
||||
// Allow mouse regions to appear transparent to hovers
|
||||
if !region.hoverable {
|
||||
|
@ -708,7 +709,11 @@ impl<'a> WindowContext<'a> {
|
|||
// highest_z_index is set.
|
||||
if contains_mouse && z_index == highest_z_index.unwrap() {
|
||||
//Ensure that hover entrance events aren't sent twice
|
||||
if window.hovered_region_ids.insert(region.id()) {
|
||||
if let Err(ix) = window.hovered_region_ids.binary_search(®ion.id()) {
|
||||
window.hovered_region_ids.insert(ix, region.id());
|
||||
}
|
||||
// window.hovered_region_ids.insert(region.id());
|
||||
if !prev_hovered_regions.contains(®ion.id()) {
|
||||
valid_regions.push(region.clone());
|
||||
if region.notify_on_hover {
|
||||
notified_views.insert(region.id().view_id());
|
||||
|
@ -716,7 +721,7 @@ impl<'a> WindowContext<'a> {
|
|||
}
|
||||
} else {
|
||||
// Ensure that hover exit events aren't sent twice
|
||||
if window.hovered_region_ids.remove(®ion.id()) {
|
||||
if prev_hovered_regions.contains(®ion.id()) {
|
||||
valid_regions.push(region.clone());
|
||||
if region.notify_on_hover {
|
||||
notified_views.insert(region.id().view_id());
|
||||
|
|
|
@ -170,7 +170,7 @@ pub trait Element<V: 'static>: 'static {
|
|||
fn with_tooltip<Tag: 'static>(
|
||||
self,
|
||||
id: usize,
|
||||
text: String,
|
||||
text: impl Into<Cow<'static, str>>,
|
||||
action: Option<Box<dyn Action>>,
|
||||
style: TooltipStyle,
|
||||
cx: &mut ViewContext<V>,
|
||||
|
@ -178,7 +178,7 @@ pub trait Element<V: 'static>: 'static {
|
|||
where
|
||||
Self: 'static + Sized,
|
||||
{
|
||||
Tooltip::new::<Tag, V>(id, text, action, style, self.into_any(), cx)
|
||||
Tooltip::new::<Tag>(id, text, action, style, self.into_any(), cx)
|
||||
}
|
||||
|
||||
fn resizable(
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
},
|
||||
json::ToJson,
|
||||
platform::CursorStyle,
|
||||
scene::{self, Border, CursorRegion, Quad},
|
||||
scene::{self, Border, CornerRadii, CursorRegion, Quad},
|
||||
AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
|
@ -29,7 +29,8 @@ pub struct ContainerStyle {
|
|||
#[serde(default)]
|
||||
pub border: Border,
|
||||
#[serde(default)]
|
||||
pub corner_radius: f32,
|
||||
#[serde(alias = "corner_radius")]
|
||||
pub corner_radii: CornerRadii,
|
||||
#[serde(default)]
|
||||
pub shadow: Option<Shadow>,
|
||||
#[serde(default)]
|
||||
|
@ -132,7 +133,10 @@ impl<V> Container<V> {
|
|||
}
|
||||
|
||||
pub fn with_corner_radius(mut self, radius: f32) -> Self {
|
||||
self.style.corner_radius = radius;
|
||||
self.style.corner_radii.top_left = radius;
|
||||
self.style.corner_radii.top_right = radius;
|
||||
self.style.corner_radii.bottom_right = radius;
|
||||
self.style.corner_radii.bottom_left = radius;
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -224,7 +228,7 @@ impl<V: 'static> Element<V> for Container<V> {
|
|||
if let Some(shadow) = self.style.shadow.as_ref() {
|
||||
scene.push_shadow(scene::Shadow {
|
||||
bounds: quad_bounds + shadow.offset,
|
||||
corner_radius: self.style.corner_radius,
|
||||
corner_radii: self.style.corner_radii,
|
||||
sigma: shadow.blur,
|
||||
color: shadow.color,
|
||||
});
|
||||
|
@ -247,7 +251,7 @@ impl<V: 'static> Element<V> for Container<V> {
|
|||
bounds: quad_bounds,
|
||||
background: self.style.background_color,
|
||||
border: Default::default(),
|
||||
corner_radius: self.style.corner_radius,
|
||||
corner_radii: self.style.corner_radii.into(),
|
||||
});
|
||||
|
||||
self.child
|
||||
|
@ -258,7 +262,7 @@ impl<V: 'static> Element<V> for Container<V> {
|
|||
bounds: quad_bounds,
|
||||
background: self.style.overlay_color,
|
||||
border: self.style.border,
|
||||
corner_radius: self.style.corner_radius,
|
||||
corner_radii: self.style.corner_radii.into(),
|
||||
});
|
||||
scene.pop_layer();
|
||||
} else {
|
||||
|
@ -266,7 +270,7 @@ impl<V: 'static> Element<V> for Container<V> {
|
|||
bounds: quad_bounds,
|
||||
background: self.style.background_color,
|
||||
border: self.style.border,
|
||||
corner_radius: self.style.corner_radius,
|
||||
corner_radii: self.style.corner_radii.into(),
|
||||
});
|
||||
|
||||
let child_origin = child_origin
|
||||
|
@ -283,7 +287,7 @@ impl<V: 'static> Element<V> for Container<V> {
|
|||
bounds: quad_bounds,
|
||||
background: self.style.overlay_color,
|
||||
border: Default::default(),
|
||||
corner_radius: 0.,
|
||||
corner_radii: self.style.corner_radii.into(),
|
||||
});
|
||||
scene.pop_layer();
|
||||
}
|
||||
|
@ -327,7 +331,7 @@ impl ToJson for ContainerStyle {
|
|||
"padding": self.padding.to_json(),
|
||||
"background_color": self.background_color.to_json(),
|
||||
"border": self.border.to_json(),
|
||||
"corner_radius": self.corner_radius,
|
||||
"corner_radius": self.corner_radii,
|
||||
"shadow": self.shadow.to_json(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ impl<V: 'static> Element<V> for Image {
|
|||
scene.push_image(scene::Image {
|
||||
bounds,
|
||||
border: self.style.border,
|
||||
corner_radius: self.style.corner_radius,
|
||||
corner_radii: self.style.corner_radius.into(),
|
||||
grayscale: self.style.grayscale,
|
||||
data: data.clone(),
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::{
|
|||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cell::{Cell, RefCell},
|
||||
ops::Range,
|
||||
rc::Rc,
|
||||
|
@ -52,9 +53,9 @@ pub struct KeystrokeStyle {
|
|||
}
|
||||
|
||||
impl<V: 'static> Tooltip<V> {
|
||||
pub fn new<Tag: 'static, T: 'static>(
|
||||
pub fn new<Tag: 'static>(
|
||||
id: usize,
|
||||
text: String,
|
||||
text: impl Into<Cow<'static, str>>,
|
||||
action: Option<Box<dyn Action>>,
|
||||
style: TooltipStyle,
|
||||
child: AnyElement<V>,
|
||||
|
@ -66,6 +67,8 @@ impl<V: 'static> Tooltip<V> {
|
|||
|
||||
let state_handle = cx.default_element_state::<ElementState<Tag>, Rc<TooltipState>>(id);
|
||||
let state = state_handle.read(cx).clone();
|
||||
let text = text.into();
|
||||
|
||||
let tooltip = if state.visible.get() {
|
||||
let mut collapsed_tooltip = Self::render_tooltip(
|
||||
focused_view_id,
|
||||
|
@ -127,7 +130,7 @@ impl<V: 'static> Tooltip<V> {
|
|||
|
||||
pub fn render_tooltip(
|
||||
focused_view_id: Option<usize>,
|
||||
text: String,
|
||||
text: impl Into<Cow<'static, str>>,
|
||||
style: TooltipStyle,
|
||||
action: Option<Box<dyn Action>>,
|
||||
measure: bool,
|
||||
|
|
|
@ -509,10 +509,14 @@ impl Renderer {
|
|||
};
|
||||
for (ix, shadow) in shadows.iter().enumerate() {
|
||||
let shape_bounds = shadow.bounds * scale_factor;
|
||||
let corner_radii = shadow.corner_radii * scale_factor;
|
||||
let shader_shadow = shaders::GPUIShadow {
|
||||
origin: shape_bounds.origin().to_float2(),
|
||||
size: shape_bounds.size().to_float2(),
|
||||
corner_radius: shadow.corner_radius * scale_factor,
|
||||
corner_radius_top_left: corner_radii.top_left,
|
||||
corner_radius_top_right: corner_radii.top_right,
|
||||
corner_radius_bottom_right: corner_radii.bottom_right,
|
||||
corner_radius_bottom_left: corner_radii.bottom_left,
|
||||
sigma: shadow.sigma,
|
||||
color: shadow.color.to_uchar4(),
|
||||
};
|
||||
|
@ -586,7 +590,10 @@ impl Renderer {
|
|||
border_bottom: border_width * (quad.border.bottom as usize as f32),
|
||||
border_left: border_width * (quad.border.left as usize as f32),
|
||||
border_color: quad.border.color.to_uchar4(),
|
||||
corner_radius: quad.corner_radius * scale_factor,
|
||||
corner_radius_top_left: quad.corner_radii.top_left * scale_factor,
|
||||
corner_radius_top_right: quad.corner_radii.top_right * scale_factor,
|
||||
corner_radius_bottom_right: quad.corner_radii.bottom_right * scale_factor,
|
||||
corner_radius_bottom_left: quad.corner_radii.bottom_left * scale_factor,
|
||||
};
|
||||
unsafe {
|
||||
*(buffer_contents.add(ix)) = shader_quad;
|
||||
|
@ -738,7 +745,7 @@ impl Renderer {
|
|||
for image in images {
|
||||
let origin = image.bounds.origin() * scale_factor;
|
||||
let target_size = image.bounds.size() * scale_factor;
|
||||
let corner_radius = image.corner_radius * scale_factor;
|
||||
let corner_radii = image.corner_radii * scale_factor;
|
||||
let border_width = image.border.width * scale_factor;
|
||||
let (alloc_id, atlas_bounds) = self.image_cache.render(&image.data);
|
||||
images_by_atlas
|
||||
|
@ -754,7 +761,10 @@ impl Renderer {
|
|||
border_bottom: border_width * (image.border.bottom as usize as f32),
|
||||
border_left: border_width * (image.border.left as usize as f32),
|
||||
border_color: image.border.color.to_uchar4(),
|
||||
corner_radius,
|
||||
corner_radius_top_left: corner_radii.top_left,
|
||||
corner_radius_top_right: corner_radii.top_right,
|
||||
corner_radius_bottom_right: corner_radii.bottom_right,
|
||||
corner_radius_bottom_left: corner_radii.bottom_left,
|
||||
grayscale: image.grayscale as u8,
|
||||
});
|
||||
}
|
||||
|
@ -777,7 +787,10 @@ impl Renderer {
|
|||
border_bottom: 0.,
|
||||
border_left: 0.,
|
||||
border_color: Default::default(),
|
||||
corner_radius: 0.,
|
||||
corner_radius_top_left: 0.,
|
||||
corner_radius_top_right: 0.,
|
||||
corner_radius_bottom_right: 0.,
|
||||
corner_radius_bottom_left: 0.,
|
||||
grayscale: false as u8,
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -19,7 +19,10 @@ typedef struct {
|
|||
float border_bottom;
|
||||
float border_left;
|
||||
vector_uchar4 border_color;
|
||||
float corner_radius;
|
||||
float corner_radius_top_left;
|
||||
float corner_radius_top_right;
|
||||
float corner_radius_bottom_right;
|
||||
float corner_radius_bottom_left;
|
||||
} GPUIQuad;
|
||||
|
||||
typedef enum {
|
||||
|
@ -31,7 +34,10 @@ typedef enum {
|
|||
typedef struct {
|
||||
vector_float2 origin;
|
||||
vector_float2 size;
|
||||
float corner_radius;
|
||||
float corner_radius_top_left;
|
||||
float corner_radius_top_right;
|
||||
float corner_radius_bottom_right;
|
||||
float corner_radius_bottom_left;
|
||||
float sigma;
|
||||
vector_uchar4 color;
|
||||
} GPUIShadow;
|
||||
|
@ -89,7 +95,10 @@ typedef struct {
|
|||
float border_bottom;
|
||||
float border_left;
|
||||
vector_uchar4 border_color;
|
||||
float corner_radius;
|
||||
float corner_radius_top_left;
|
||||
float corner_radius_top_right;
|
||||
float corner_radius_bottom_right;
|
||||
float corner_radius_bottom_left;
|
||||
uint8_t grayscale;
|
||||
} GPUIImage;
|
||||
|
||||
|
|
|
@ -43,7 +43,10 @@ struct QuadFragmentInput {
|
|||
float border_bottom;
|
||||
float border_left;
|
||||
float4 border_color;
|
||||
float corner_radius;
|
||||
float corner_radius_top_left;
|
||||
float corner_radius_top_right;
|
||||
float corner_radius_bottom_right;
|
||||
float corner_radius_bottom_left;
|
||||
uchar grayscale; // only used in image shader
|
||||
};
|
||||
|
||||
|
@ -51,12 +54,27 @@ float4 quad_sdf(QuadFragmentInput input) {
|
|||
float2 half_size = input.size / 2.;
|
||||
float2 center = input.origin + half_size;
|
||||
float2 center_to_point = input.position.xy - center;
|
||||
float2 rounded_edge_to_point = abs(center_to_point) - half_size + input.corner_radius;
|
||||
float distance = length(max(0., rounded_edge_to_point)) + min(0., max(rounded_edge_to_point.x, rounded_edge_to_point.y)) - input.corner_radius;
|
||||
float corner_radius;
|
||||
if (center_to_point.x < 0.) {
|
||||
if (center_to_point.y < 0.) {
|
||||
corner_radius = input.corner_radius_top_left;
|
||||
} else {
|
||||
corner_radius = input.corner_radius_bottom_left;
|
||||
}
|
||||
} else {
|
||||
if (center_to_point.y < 0.) {
|
||||
corner_radius = input.corner_radius_top_right;
|
||||
} else {
|
||||
corner_radius = input.corner_radius_bottom_right;
|
||||
}
|
||||
}
|
||||
|
||||
float2 rounded_edge_to_point = abs(center_to_point) - half_size + corner_radius;
|
||||
float distance = length(max(0., rounded_edge_to_point)) + min(0., max(rounded_edge_to_point.x, rounded_edge_to_point.y)) - corner_radius;
|
||||
|
||||
float vertical_border = center_to_point.x <= 0. ? input.border_left : input.border_right;
|
||||
float horizontal_border = center_to_point.y <= 0. ? input.border_top : input.border_bottom;
|
||||
float2 inset_size = half_size - input.corner_radius - float2(vertical_border, horizontal_border);
|
||||
float2 inset_size = half_size - corner_radius - float2(vertical_border, horizontal_border);
|
||||
float2 point_to_inset_corner = abs(center_to_point) - inset_size;
|
||||
float border_width;
|
||||
if (point_to_inset_corner.x < 0. && point_to_inset_corner.y < 0.) {
|
||||
|
@ -110,7 +128,10 @@ vertex QuadFragmentInput quad_vertex(
|
|||
quad.border_bottom,
|
||||
quad.border_left,
|
||||
coloru_to_colorf(quad.border_color),
|
||||
quad.corner_radius,
|
||||
quad.corner_radius_top_left,
|
||||
quad.corner_radius_top_right,
|
||||
quad.corner_radius_bottom_right,
|
||||
quad.corner_radius_bottom_left,
|
||||
0,
|
||||
};
|
||||
}
|
||||
|
@ -125,7 +146,10 @@ struct ShadowFragmentInput {
|
|||
float4 position [[position]];
|
||||
vector_float2 origin;
|
||||
vector_float2 size;
|
||||
float corner_radius;
|
||||
float corner_radius_top_left;
|
||||
float corner_radius_top_right;
|
||||
float corner_radius_bottom_right;
|
||||
float corner_radius_bottom_left;
|
||||
float sigma;
|
||||
vector_uchar4 color;
|
||||
};
|
||||
|
@ -148,7 +172,10 @@ vertex ShadowFragmentInput shadow_vertex(
|
|||
device_position,
|
||||
shadow.origin,
|
||||
shadow.size,
|
||||
shadow.corner_radius,
|
||||
shadow.corner_radius_top_left,
|
||||
shadow.corner_radius_top_right,
|
||||
shadow.corner_radius_bottom_right,
|
||||
shadow.corner_radius_bottom_left,
|
||||
shadow.sigma,
|
||||
shadow.color,
|
||||
};
|
||||
|
@ -158,10 +185,24 @@ fragment float4 shadow_fragment(
|
|||
ShadowFragmentInput input [[stage_in]]
|
||||
) {
|
||||
float sigma = input.sigma;
|
||||
float corner_radius = input.corner_radius;
|
||||
float2 half_size = input.size / 2.;
|
||||
float2 center = input.origin + half_size;
|
||||
float2 point = input.position.xy - center;
|
||||
float2 center_to_point = input.position.xy - center;
|
||||
float corner_radius;
|
||||
if (center_to_point.x < 0.) {
|
||||
if (center_to_point.y < 0.) {
|
||||
corner_radius = input.corner_radius_top_left;
|
||||
} else {
|
||||
corner_radius = input.corner_radius_bottom_left;
|
||||
}
|
||||
} else {
|
||||
if (center_to_point.y < 0.) {
|
||||
corner_radius = input.corner_radius_top_right;
|
||||
} else {
|
||||
corner_radius = input.corner_radius_bottom_right;
|
||||
}
|
||||
}
|
||||
|
||||
// The signal is only non-zero in a limited range, so don't waste samples
|
||||
float low = point.y - half_size.y;
|
||||
|
@ -252,7 +293,10 @@ vertex QuadFragmentInput image_vertex(
|
|||
image.border_bottom,
|
||||
image.border_left,
|
||||
coloru_to_colorf(image.border_color),
|
||||
image.corner_radius,
|
||||
image.corner_radius_top_left,
|
||||
image.corner_radius_top_right,
|
||||
image.corner_radius_bottom_right,
|
||||
image.corner_radius_bottom_left,
|
||||
image.grayscale,
|
||||
};
|
||||
}
|
||||
|
@ -266,7 +310,7 @@ fragment float4 image_fragment(
|
|||
if (input.grayscale) {
|
||||
float grayscale =
|
||||
0.2126 * input.background_color.r +
|
||||
0.7152 * input.background_color.g +
|
||||
0.7152 * input.background_color.g +
|
||||
0.0722 * input.background_color.b;
|
||||
input.background_color = float4(grayscale, grayscale, grayscale, input.background_color.a);
|
||||
}
|
||||
|
|
|
@ -1087,7 +1087,10 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
|||
button: MouseButton::Left,
|
||||
modifiers: Modifiers { ctrl: true, .. },
|
||||
..
|
||||
}) => return,
|
||||
}) => {
|
||||
window_state_borrow.synthetic_drag_counter += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
_ => None,
|
||||
};
|
||||
|
|
|
@ -3,8 +3,10 @@ mod mouse_region;
|
|||
|
||||
#[cfg(debug_assertions)]
|
||||
use collections::HashSet;
|
||||
use derive_more::Mul;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde_derive::Serialize;
|
||||
use serde_json::json;
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
|
@ -65,13 +67,73 @@ pub struct Quad {
|
|||
pub bounds: RectF,
|
||||
pub background: Option<Color>,
|
||||
pub border: Border,
|
||||
pub corner_radius: f32,
|
||||
pub corner_radii: CornerRadii,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Mul, Clone, Copy, Serialize, JsonSchema)]
|
||||
pub struct CornerRadii {
|
||||
pub top_left: f32,
|
||||
pub top_right: f32,
|
||||
pub bottom_right: f32,
|
||||
pub bottom_left: f32,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for CornerRadii {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
pub struct CornerRadiiHelper {
|
||||
pub top_left: Option<f32>,
|
||||
pub top_right: Option<f32>,
|
||||
pub bottom_right: Option<f32>,
|
||||
pub bottom_left: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum RadiusOrRadii {
|
||||
Radius(f32),
|
||||
Radii(CornerRadiiHelper),
|
||||
}
|
||||
|
||||
let json = RadiusOrRadii::deserialize(deserializer)?;
|
||||
|
||||
let result = match json {
|
||||
RadiusOrRadii::Radius(radius) => CornerRadii::from(radius),
|
||||
RadiusOrRadii::Radii(CornerRadiiHelper {
|
||||
top_left,
|
||||
top_right,
|
||||
bottom_right,
|
||||
bottom_left,
|
||||
}) => CornerRadii {
|
||||
top_left: top_left.unwrap_or(0.0),
|
||||
top_right: top_right.unwrap_or(0.0),
|
||||
bottom_right: bottom_right.unwrap_or(0.0),
|
||||
bottom_left: bottom_left.unwrap_or(0.0),
|
||||
},
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for CornerRadii {
|
||||
fn from(radius: f32) -> Self {
|
||||
Self {
|
||||
top_left: radius,
|
||||
top_right: radius,
|
||||
bottom_right: radius,
|
||||
bottom_left: radius,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Shadow {
|
||||
pub bounds: RectF,
|
||||
pub corner_radius: f32,
|
||||
pub corner_radii: CornerRadii,
|
||||
pub sigma: f32,
|
||||
pub color: Color,
|
||||
}
|
||||
|
@ -177,7 +239,7 @@ pub struct PathVertex {
|
|||
pub struct Image {
|
||||
pub bounds: RectF,
|
||||
pub border: Border,
|
||||
pub corner_radius: f32,
|
||||
pub corner_radii: CornerRadii,
|
||||
pub grayscale: bool,
|
||||
pub data: Arc<ImageData>,
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ impl MouseRegion {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
|
||||
pub struct MouseRegionId {
|
||||
view_id: usize,
|
||||
tag: TypeId,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue