mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-29 20:48:33 -06:00
Title bar: window-gesture policy (drag, double-click zoom, full-screen exempt)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
7b47ba7894
commit
1e27991cf1
@@ -25,6 +25,7 @@ pub mod softpaint;
|
||||
pub mod state;
|
||||
pub mod tasks;
|
||||
pub mod theme;
|
||||
pub mod titlebar;
|
||||
pub mod widgets;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
//! The integrated title bar's window gestures (macOS: the native title bar is hidden and the top
|
||||
//! bar takes its place, so dragging and double-click-to-zoom have to be done here).
|
||||
//!
|
||||
//! Pure policy, no egui widgets: [`command_for`] maps a gesture on the bar's empty space and the
|
||||
//! window's current state to the viewport command the host should run.
|
||||
|
||||
use egui::ViewportCommand;
|
||||
|
||||
/// What the user did on the bar's empty space.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Gesture {
|
||||
/// A primary-button drag began: the window follows the pointer.
|
||||
DragStarted,
|
||||
/// A primary-button double-click: zoom the window, or restore it when already zoomed.
|
||||
DoubleClicked,
|
||||
}
|
||||
|
||||
/// The window as the host reports it.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct WindowState {
|
||||
/// Zoomed (macOS) / maximized (elsewhere).
|
||||
pub maximized: bool,
|
||||
/// In the OS's full-screen mode.
|
||||
pub fullscreen: bool,
|
||||
}
|
||||
|
||||
/// The viewport command for `gesture`, if any. Full screen has no title bar to drag or zoom.
|
||||
pub fn command_for(gesture: Gesture, window: WindowState) -> Option<ViewportCommand> {
|
||||
if window.fullscreen {
|
||||
return None;
|
||||
}
|
||||
match gesture {
|
||||
Gesture::DragStarted => Some(ViewportCommand::StartDrag),
|
||||
Gesture::DoubleClicked => Some(ViewportCommand::Maximized(!window.maximized)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const NORMAL: WindowState = WindowState { maximized: false, fullscreen: false };
|
||||
const ZOOMED: WindowState = WindowState { maximized: true, fullscreen: false };
|
||||
const FULL: WindowState = WindowState { maximized: false, fullscreen: true };
|
||||
|
||||
// Scenario: dragging the title bar moves the window
|
||||
#[test]
|
||||
fn given_a_normal_window_when_dragging_then_the_window_follows_the_pointer() {
|
||||
assert_eq!(command_for(Gesture::DragStarted, NORMAL), Some(ViewportCommand::StartDrag));
|
||||
}
|
||||
|
||||
// Scenario: a zoomed window can still be dragged (macOS lets you pull it free)
|
||||
#[test]
|
||||
fn given_a_zoomed_window_when_dragging_then_the_window_follows_the_pointer() {
|
||||
assert_eq!(command_for(Gesture::DragStarted, ZOOMED), Some(ViewportCommand::StartDrag));
|
||||
}
|
||||
|
||||
// Scenario: double-click zooms
|
||||
#[test]
|
||||
fn given_a_normal_window_when_double_clicking_then_it_zooms() {
|
||||
assert_eq!(command_for(Gesture::DoubleClicked, NORMAL), Some(ViewportCommand::Maximized(true)));
|
||||
}
|
||||
|
||||
// Scenario: double-click again restores
|
||||
#[test]
|
||||
fn given_a_zoomed_window_when_double_clicking_then_it_is_restored() {
|
||||
assert_eq!(command_for(Gesture::DoubleClicked, ZOOMED), Some(ViewportCommand::Maximized(false)));
|
||||
}
|
||||
|
||||
// Scenario: full screen ignores both
|
||||
#[test]
|
||||
fn given_a_full_screen_window_then_neither_gesture_does_anything() {
|
||||
assert_eq!(command_for(Gesture::DragStarted, FULL), None);
|
||||
assert_eq!(command_for(Gesture::DoubleClicked, FULL), None);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user