Improve pane selection when resizing a PaneGrid
This commit is contained in:
parent
eb5e2251bd
commit
ec334bdd36
@ -14,7 +14,7 @@ pub use state::{Focus, State};
|
|||||||
use crate::{
|
use crate::{
|
||||||
input::{keyboard, mouse, ButtonState},
|
input::{keyboard, mouse, ButtonState},
|
||||||
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Size,
|
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Size,
|
||||||
Vector, Widget,
|
Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
@ -131,17 +131,17 @@ impl<'a, Message, Renderer> PaneGrid<'a, Message, Renderer> {
|
|||||||
let ratio = match axis {
|
let ratio = match axis {
|
||||||
Axis::Horizontal => {
|
Axis::Horizontal => {
|
||||||
let position =
|
let position =
|
||||||
cursor_position.x - bounds.x + rectangle.x;
|
cursor_position.y - bounds.y + rectangle.y;
|
||||||
|
|
||||||
(position / (rectangle.x + rectangle.width))
|
(position / (rectangle.y + rectangle.height))
|
||||||
.max(0.1)
|
.max(0.1)
|
||||||
.min(0.9)
|
.min(0.9)
|
||||||
}
|
}
|
||||||
Axis::Vertical => {
|
Axis::Vertical => {
|
||||||
let position =
|
let position =
|
||||||
cursor_position.y - bounds.y + rectangle.y;
|
cursor_position.x - bounds.x + rectangle.x;
|
||||||
|
|
||||||
(position / (rectangle.y + rectangle.height))
|
(position / (rectangle.x + rectangle.width))
|
||||||
.max(0.1)
|
.max(0.1)
|
||||||
.min(0.9)
|
.min(0.9)
|
||||||
}
|
}
|
||||||
@ -279,60 +279,62 @@ where
|
|||||||
},
|
},
|
||||||
Event::Mouse(mouse::Event::Input {
|
Event::Mouse(mouse::Event::Input {
|
||||||
button: mouse::Button::Right,
|
button: mouse::Button::Right,
|
||||||
state,
|
state: ButtonState::Pressed,
|
||||||
}) if self.on_resize.is_some()
|
}) if self.on_resize.is_some()
|
||||||
&& self.state.picked_pane().is_none()
|
&& self.state.picked_pane().is_none()
|
||||||
&& self.modifiers.alt =>
|
&& self.modifiers.alt =>
|
||||||
{
|
{
|
||||||
match state {
|
|
||||||
ButtonState::Pressed => {
|
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
let relative_cursor = Point::new(
|
||||||
|
cursor_position.x - bounds.x,
|
||||||
|
cursor_position.y - bounds.y,
|
||||||
|
);
|
||||||
|
|
||||||
let splits = self.state.splits(
|
let splits = self.state.splits(
|
||||||
f32::from(self.spacing),
|
f32::from(self.spacing),
|
||||||
Size::new(bounds.width, bounds.height),
|
Size::new(bounds.width, bounds.height),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sorted_splits: Vec<_> = splits.iter().collect();
|
let mut sorted_splits: Vec<_> = splits
|
||||||
let offset = Vector::new(bounds.x, bounds.y);
|
.iter()
|
||||||
|
.filter(|(_, (axis, rectangle, _))| match axis {
|
||||||
|
Axis::Horizontal => {
|
||||||
|
relative_cursor.x > rectangle.x
|
||||||
|
&& relative_cursor.x
|
||||||
|
< rectangle.x + rectangle.width
|
||||||
|
}
|
||||||
|
Axis::Vertical => {
|
||||||
|
relative_cursor.y > rectangle.y
|
||||||
|
&& relative_cursor.y
|
||||||
|
< rectangle.y + rectangle.height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
sorted_splits.sort_by_key(
|
sorted_splits.sort_by_key(|(_, (axis, rectangle, ratio))| {
|
||||||
|(_, (axis, rectangle, ratio))| {
|
let distance = match axis {
|
||||||
let center = match axis {
|
Axis::Horizontal => (relative_cursor.y
|
||||||
Axis::Horizontal => Point::new(
|
- (rectangle.y + rectangle.height * ratio))
|
||||||
rectangle.x + rectangle.width / 2.0,
|
.abs(),
|
||||||
rectangle.y + rectangle.height * ratio,
|
Axis::Vertical => (relative_cursor.x
|
||||||
),
|
- (rectangle.x + rectangle.width * ratio))
|
||||||
|
.abs(),
|
||||||
Axis::Vertical => Point::new(
|
|
||||||
rectangle.x + rectangle.width * ratio,
|
|
||||||
rectangle.y + rectangle.height / 2.0,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cursor_position
|
distance.round() as u32
|
||||||
.distance(center + offset)
|
});
|
||||||
.round()
|
|
||||||
as u32
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some((split, (axis, _, _))) =
|
if let Some((split, (axis, _, _))) = sorted_splits.first() {
|
||||||
sorted_splits.first()
|
|
||||||
{
|
|
||||||
self.state.pick_split(split, *axis);
|
self.state.pick_split(split, *axis);
|
||||||
self.trigger_resize(
|
self.trigger_resize(layout, cursor_position, messages);
|
||||||
layout,
|
|
||||||
cursor_position,
|
|
||||||
messages,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ButtonState::Released => {
|
Event::Mouse(mouse::Event::Input {
|
||||||
|
button: mouse::Button::Right,
|
||||||
|
state: ButtonState::Released,
|
||||||
|
}) if self.state.picked_split().is_some() => {
|
||||||
self.state.drop_split();
|
self.state.drop_split();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
|
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
|
||||||
self.trigger_resize(layout, cursor_position, messages);
|
self.trigger_resize(layout, cursor_position, messages);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,23 +15,6 @@ impl Axis {
|
|||||||
) -> (Rectangle, Rectangle) {
|
) -> (Rectangle, Rectangle) {
|
||||||
match self {
|
match self {
|
||||||
Axis::Horizontal => {
|
Axis::Horizontal => {
|
||||||
let width_left =
|
|
||||||
(rectangle.width * ratio).round() - halved_spacing;
|
|
||||||
let width_right = rectangle.width - width_left - halved_spacing;
|
|
||||||
|
|
||||||
(
|
|
||||||
Rectangle {
|
|
||||||
width: width_left,
|
|
||||||
..*rectangle
|
|
||||||
},
|
|
||||||
Rectangle {
|
|
||||||
x: rectangle.x + width_left + halved_spacing,
|
|
||||||
width: width_right,
|
|
||||||
..*rectangle
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Axis::Vertical => {
|
|
||||||
let height_top =
|
let height_top =
|
||||||
(rectangle.height * ratio).round() - halved_spacing;
|
(rectangle.height * ratio).round() - halved_spacing;
|
||||||
let height_bottom =
|
let height_bottom =
|
||||||
@ -49,6 +32,23 @@ impl Axis {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Axis::Vertical => {
|
||||||
|
let width_left =
|
||||||
|
(rectangle.width * ratio).round() - halved_spacing;
|
||||||
|
let width_right = rectangle.width - width_left - halved_spacing;
|
||||||
|
|
||||||
|
(
|
||||||
|
Rectangle {
|
||||||
|
width: width_left,
|
||||||
|
..*rectangle
|
||||||
|
},
|
||||||
|
Rectangle {
|
||||||
|
x: rectangle.x + width_left + halved_spacing,
|
||||||
|
width: width_right,
|
||||||
|
..*rectangle
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,8 +73,8 @@ impl pane_grid::Renderer for Renderer {
|
|||||||
MouseCursor::Grabbing
|
MouseCursor::Grabbing
|
||||||
} else if let Some(axis) = resizing {
|
} else if let Some(axis) = resizing {
|
||||||
match axis {
|
match axis {
|
||||||
Axis::Horizontal => MouseCursor::ResizingHorizontally,
|
Axis::Horizontal => MouseCursor::ResizingVertically,
|
||||||
Axis::Vertical => MouseCursor::ResizingVertically,
|
Axis::Vertical => MouseCursor::ResizingHorizontally,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mouse_cursor
|
mouse_cursor
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user