cranpose 0.1.164

Cranpose runtime and UI facade
Documentation
use cranpose_app_shell::RotaryScrollEvent;
use cranpose_platform_desktop_winit::DesktopWinitPlatform;
use winit::{dpi::PhysicalPosition, event::MouseScrollDelta};

use super::*;

const NOTCH_PIXELS: f32 = 40.0;

fn wheel_for(delta: MouseScrollDelta, scale_factor: f64) -> WheelScroll {
    let platform = DesktopWinitPlatform::new(scale_factor);
    let logical_delta = platform
        .scroll_delta(delta)
        .expect("line and pixel deltas are both scroll kinds the platform converts");
    wheel_scroll_from_winit(logical_delta, ModifiersState::empty(), 0)
}

fn rotary_for(delta: MouseScrollDelta, scale_factor: f64) -> RotaryScrollEvent {
    let wheel = wheel_for(delta, scale_factor);
    RotaryScrollEvent::from_wheel_pixels(wheel.delta.y, wheel.delta.x, wheel.uptime_millis)
}

#[test]
fn line_delta_scroll_up_produces_negative_vertical_pixels() {
    let event = rotary_for(MouseScrollDelta::LineDelta(0.0, 1.0), 1.0);

    assert_eq!(event.vertical_scroll_pixels, -NOTCH_PIXELS);
    assert_eq!(event.horizontal_scroll_pixels, 0.0);
}

#[test]
fn line_delta_scroll_down_produces_positive_vertical_pixels() {
    let event = rotary_for(MouseScrollDelta::LineDelta(0.0, -1.0), 1.0);

    assert_eq!(event.vertical_scroll_pixels, NOTCH_PIXELS);
}

#[test]
fn line_delta_maps_horizontal_axis_too() {
    let event = rotary_for(MouseScrollDelta::LineDelta(2.0, 0.0), 1.0);

    assert_eq!(event.horizontal_scroll_pixels, -2.0 * NOTCH_PIXELS);
    assert_eq!(event.vertical_scroll_pixels, 0.0);
}

#[test]
fn pixel_delta_is_converted_and_negated() {
    let event = rotary_for(
        MouseScrollDelta::PixelDelta(PhysicalPosition { x: 0.0, y: 12.0 }),
        1.0,
    );

    assert_eq!(event.vertical_scroll_pixels, -12.0);
}

#[test]
fn pixel_delta_respects_hidpi_scale_factor() {
    let event = rotary_for(
        MouseScrollDelta::PixelDelta(PhysicalPosition { x: 8.0, y: 24.0 }),
        2.0,
    );

    assert_eq!(event.vertical_scroll_pixels, -12.0);
    assert_eq!(event.horizontal_scroll_pixels, -4.0);
}

#[test]
fn both_delta_variants_agree_on_direction() {
    let line = rotary_for(MouseScrollDelta::LineDelta(0.0, 1.0), 1.0);
    let pixel = rotary_for(
        MouseScrollDelta::PixelDelta(PhysicalPosition { x: 0.0, y: 40.0 }),
        1.0,
    );

    assert_eq!(line.vertical_scroll_pixels, pixel.vertical_scroll_pixels);
    assert!(line.vertical_scroll_pixels < 0.0);
}

#[test]
fn desktop_sign_matches_the_android_detent_path() {
    let desktop = rotary_for(MouseScrollDelta::LineDelta(0.0, 1.0), 1.0);
    let android = RotaryScrollEvent::from_detents(1.0, NOTCH_PIXELS, NOTCH_PIXELS, 0);

    assert_eq!(
        desktop.vertical_scroll_pixels,
        android.vertical_scroll_pixels
    );
}

#[test]
fn a_wheel_scrolled_up_asks_the_content_to_move_down() {
    let up = wheel_for(MouseScrollDelta::LineDelta(0.0, 1.0), 1.0);

    assert_eq!(up.delta.y, NOTCH_PIXELS);
    assert!(!up.is_zoom());
    assert_eq!(up.scroll_delta(), up.delta);
}

#[test]
fn zero_delta_produces_an_empty_event() {
    let event = rotary_for(MouseScrollDelta::LineDelta(0.0, 0.0), 1.0);

    assert!(event.is_empty());
}

#[test]
fn uptime_is_carried_through() {
    let wheel = wheel_scroll_from_winit(Point { x: 0.0, y: 1.0 }, ModifiersState::empty(), 9876);

    assert_eq!(wheel.uptime_millis, 9_876);
}

#[test]
fn winit_modifiers_reach_the_shell_policy() {
    let ctrl = wheel_scroll_from_winit(Point { x: 0.0, y: 40.0 }, ModifiersState::CONTROL, 0);
    let alt = wheel_scroll_from_winit(Point { x: 0.0, y: 40.0 }, ModifiersState::ALT, 0);

    assert!(ctrl.is_zoom());
    assert!(!alt.is_zoom());
    assert_eq!(alt.scroll_delta(), Point { x: 40.0, y: 0.0 });
}