1 module nodes.scroll_input;
2 
3 import std.range;
4 import fluid;
5 import nodes.scroll;
6 
7 @safe:
8 
9 @("ScrollInput draws a track and a handle")
10 unittest {
11 
12     auto frame = sizeLock!vscrollFrame(
13         .sizeLimit(250, 250),
14         .testTheme,
15         tallBox(),
16     );
17     auto root = testSpace(frame);
18 
19     root.drawAndAssert(
20         frame.scrollBar       .drawsRectangle(240,   0, 10, 250).ofColor("#ff0000"),
21         frame.scrollBar.handle.drawsRectangle(240,   0, 10,  50).ofColor("#0000ff"),
22     );
23     frame.scroll = 2500;
24     root.drawAndAssert(
25         frame.scrollBar       .drawsRectangle(240,   0, 10, 250).ofColor("#ff0000"),
26         frame.scrollBar.handle.drawsRectangle(240, 100, 10,  50).ofColor("#0000ff"),
27     );
28 
29 }
30 
31 @("ScrollInput works by dragging")
32 unittest {
33 
34     Button btn;
35 
36     auto frame = sizeLock!vscrollFrame(
37         .testTheme,
38         .sizeLimit(200, 100),
39         btn = button(.layout!"fill", "Button to test hover slipping", delegate { assert(false); }),
40         label("Text long enough to overflow this very small viewport and create a scrollbar"),
41     );
42     auto hover = hoverChain();
43     auto root = testSpace(
44         chain(
45             inputMapChain(),
46             hover,
47             frame,
48         )
49     );
50 
51     root.draw();
52 
53     float scrollDiff;
54 
55     // Grab the scrollbar
56     hover.point(195, 10)
57         .then((a) {
58             assert(a.isHovered(frame.scrollBar.handle));
59             a.press(false);
60 
61             // Drag the scrollbar 10 pixels lower
62             return a.move(195, 20);
63         })
64         .then((a) {
65             a.press(false);
66 
67             // Note down the difference in scroll
68             scrollDiff = frame.scroll;
69             assert(scrollDiff > 5);
70 
71             // Drag the scrollbar 10 pixels lower, but also move it out of the scrollbar's area
72             return a.move(150, 30);
73         })
74         .then((a) {
75             const target = scrollDiff*2;
76 
77             a.press(false);
78             assert(target-1 <= frame.scroll && frame.scroll <= target+1,
79                 "Scrollbar should operate at the same rate, even if the cursor is outside");
80 
81             // Make sure the button is hovered
82             return a.move(150, 20);
83         })
84         .then((a) {
85             assert(a.isHovered(frame.scrollBar.handle),
86                 "The scrollbar should retain hover control");
87 
88             // Release the mouse while it's hovering the button
89             return a.stayIdle;
90         })
91         .then((a) {
92             assert(a.isHovered(btn));
93         })
94         .runWhileDrawing(root);
95 
96 }