mirror of
https://github.com/storytold/craft-libs.git
synced 2026-10-31 07:39:23 +00:00
Merge #244: a native window moved by its only tab joins a body's center
This commit is contained in:
commit
85c8cf1cd5
3 files changed
+47
-6
No files matched your search
@@ -859,6 +859,43 @@ fn the_only_tab_of_a_native_window_docks_it_with_title_bar_docks_off() {
|
||||
assert!(!in_root(&d, 7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_only_tab_of_a_native_window_fills_and_joins_a_frame_bodys_center() {
|
||||
let mut layout = layout(false);
|
||||
layout.floating.push(Floating::single(vec![7], 0, [300.0, 80.0, 240.0, 200.0]));
|
||||
let style = |s: &mut super::DockStyle| {
|
||||
s.side_edge_zones = true;
|
||||
s.title_bar_docks = false;
|
||||
s.float_hint = false;
|
||||
};
|
||||
let mut d = DockDriver::new(layout, Content::default()).with_style(style).with_native_host(ORIGIN);
|
||||
let id = window(&d, 7).id;
|
||||
// The middle of frame [3, 4], in the main window.
|
||||
let middle = pos2(600.0, 300.0);
|
||||
let from = pos2(15.0, TAB_ROW);
|
||||
d.window_step(id, vec![Event::PointerMoved(from), button(from, true)]);
|
||||
d.window_step(id, vec![Event::PointerMoved(from + vec2(8.0, 6.0))]);
|
||||
for _ in 0..2 {
|
||||
let local = d.window_local(id, ORIGIN + middle.to_vec2()).unwrap();
|
||||
d.window_step(id, vec![Event::PointerMoved(local)]);
|
||||
}
|
||||
// The center rectangle is the only zone around the pointer: outlined and filled.
|
||||
let zone = |filled: bool| {
|
||||
d.shapes().iter().any(|clipped| match &clipped.shape {
|
||||
egui::Shape::Path(path) => {
|
||||
path.closed && (path.fill != Color32::TRANSPARENT) == filled && Rect::from_points(&path.points).contains(middle)
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
};
|
||||
assert!(zone(false), "outlined");
|
||||
assert!(zone(true), "filled");
|
||||
let local = d.window_local(id, ORIGIN + middle.to_vec2()).unwrap();
|
||||
let out = d.window_step(id, vec![button(local, false)]);
|
||||
assert!(matches!(window_move(&out), Some(Target::At { anchor: 3 | 4, placement: Placement::Split(super::Zone::Center) })), "{:?}", out.actions);
|
||||
assert!(in_root(&d, 7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_native_window_forwards_no_keys_while_one_of_its_widgets_has_focus() {
|
||||
let mut d = driver(layout(true));
|
||||
|
||||
@@ -116,7 +116,8 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {
|
||||
|
||||
/// The valid target under the pointer for a whole group. A target holding the group
|
||||
/// itself is a no-op proposal; a target the model would reject is no target. A window
|
||||
/// moving live looks through itself and does not split frames or join a body's center.
|
||||
/// moving live looks through itself and does not split frames or, moved by its bar, join
|
||||
/// a body's center.
|
||||
pub(super) fn group_proposal(&self, drag: &GroupDrag<P>, pointer: Pos2) -> Option<DropProposal<P>> {
|
||||
let window = drag.gesture == GroupGesture::Window;
|
||||
if let Some(proposal) = self.extra_proposal(&drag.members, pointer, window) {
|
||||
@@ -148,14 +149,16 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {
|
||||
}
|
||||
let proposal = self.resolve_roomy(&drag.panel, pointer, std::slice::from_ref(target), |to| group_action(drag, to))?;
|
||||
// A window moving live splits only groups of other floating windows. A native
|
||||
// window's bar also takes the main window's frame edges, but not a body's center.
|
||||
// window's bar also takes the main window's frame edges, but not a body's center. A
|
||||
// native window moved by its only tab or group joins a body's center too, as that tab
|
||||
// or group drag would.
|
||||
let into_window = matches!(self.place(&proposal.anchor), Some(Place::Floating { .. }));
|
||||
#[cfg(feature = "native-windows")]
|
||||
let edges = self.cross.bar;
|
||||
let (edges, joins) = (self.cross.bar, self.cross.docks);
|
||||
#[cfg(not(feature = "native-windows"))]
|
||||
let edges = false;
|
||||
let (edges, joins) = (false, false);
|
||||
let split = match proposal.placement {
|
||||
Placement::Split(Zone::Center) => true,
|
||||
Placement::Split(Zone::Center) => !joins,
|
||||
Placement::Split(_) => !edges,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
+2
-1
@@ -439,7 +439,8 @@ that is not floatable, stays in-window. Floating windows get no taskbar or Alt-T
|
||||
`DockStyle::title_bar_docks`; the only tab or group docks either way, since it is the way
|
||||
back in with that flag off. Targets: in the
|
||||
main window a dock line, a frame's tab row or edge zone, or the layout's outer edge; in a
|
||||
floating window a frame zone or tab row. A frame body's center takes no whole window. Over
|
||||
floating window a frame zone or tab row. A frame body's center takes a window moved by its
|
||||
only tab or group, as that tab or group drag would, but not one moved by its bar. Over
|
||||
the desktop, or with Ctrl/Cmd held, it stays where it was moved, and the layout takes its
|
||||
place once, at the release. Escape puts it back. An
|
||||
in-window floating window's title bar still splits only groups of other floating windows.
|
||||
|
||||
Reference in new issue
Block a user