freya-components 0.5.0

Components for Freya apps
Documentation
use std::time::Duration;

use freya::prelude::*;
use freya_testing::prelude::*;

fn setup(virtualized: bool, platform: TargetPlatform) -> (TestingRunner, ScrollController) {
    let (mut test, controller) = TestingRunner::new(
        move || {
            let controller = use_consume::<ScrollController>();
            if virtualized {
                VirtualScrollView::new_controlled(
                    |item, _| rect().key(item.index).height(Size::px(50.)).into(),
                    controller,
                )
                .length(100usize)
                .item_size(50.)
                .into_element()
            } else {
                ScrollView::new_controlled(controller)
                    .child(rect().height(Size::px(5000.)))
                    .into_element()
            }
        },
        (500., 500.).into(),
        |runner| {
            runner.provide_root_context(|| platform);
            runner.provide_root_context(|| ScrollController::new(0, 0))
        },
        1.,
    );
    test.sync_and_update();
    (test, controller)
}

fn wheel(test: &mut TestingRunner, phase: TouchPhase, delta: f64) {
    test.send_event(PlatformEvent::Wheel {
        name: WheelEventName::Wheel,
        scroll: (0., delta).into(),
        cursor: (5., 5.).into(),
        source: WheelSource::Pixel,
        phase,
    });
    test.sync_and_update();
}

fn position(test: &TestingRunner, controller: ScrollController) -> (f32, i32) {
    test.run_in(|| {
        let (horizontal, vertical): (i32, i32) = controller.into();
        let rendered = controller.animated_position((horizontal as f32, vertical as f32).into());
        (rendered.y, vertical)
    })
}

#[test]
fn linux_scroll_gesture_smoothing_momentum_and_interruption() {
    for virtualized in [false, true] {
        let (mut test, controller) = setup(virtualized, TargetPlatform::Linux);
        wheel(&mut test, TouchPhase::Started, -40.);
        let (rendered, target) = position(&test, controller);
        assert_eq!(rendered, 0.);
        assert_eq!(target, -40);

        test.poll(Duration::from_millis(8), Duration::from_millis(32));
        wheel(&mut test, TouchPhase::Moved, -40.);
        test.poll(Duration::from_millis(8), Duration::from_millis(32));
        wheel(&mut test, TouchPhase::Moved, -40.);
        let (rendered, target) = position(&test, controller);
        assert!(rendered < 0. && rendered > target as f32);
        wheel(&mut test, TouchPhase::Ended, 0.);
        assert!(position(&test, controller).1 < target);

        test.poll(Duration::from_millis(8), Duration::from_millis(32));
        wheel(&mut test, TouchPhase::Started, 0.);
        wheel(&mut test, TouchPhase::Cancelled, 0.);
        let stopped = position(&test, controller);
        test.poll(Duration::from_millis(8), Duration::from_millis(150));
        assert_eq!(position(&test, controller), stopped);
    }
}

#[test]
fn linux_scroll_gesture_pause_does_not_fling() {
    for virtualized in [false, true] {
        let (mut test, controller) = setup(virtualized, TargetPlatform::Linux);
        wheel(&mut test, TouchPhase::Started, -40.);
        test.poll(Duration::from_millis(8), Duration::from_millis(32));
        wheel(&mut test, TouchPhase::Moved, -40.);
        test.poll(Duration::from_millis(8), Duration::from_millis(150));
        let target = position(&test, controller).1;
        wheel(&mut test, TouchPhase::Ended, 0.);
        assert_eq!(position(&test, controller).1, target);
    }
}

#[test]
fn other_platforms_keep_direct_pixel_scrolling() {
    for platform in [TargetPlatform::MacOs, TargetPlatform::Windows] {
        for virtualized in [false, true] {
            let (mut test, controller) = setup(virtualized, platform);
            wheel(&mut test, TouchPhase::Started, -40.);
            assert_eq!(position(&test, controller), (-40., -40));
            wheel(&mut test, TouchPhase::Moved, -40.);
            wheel(&mut test, TouchPhase::Ended, 0.);
            assert_eq!(position(&test, controller), (-80., -80));
        }
    }
}