1 ///
2 module fluid.hover_button;
3 
4 import fluid.node;
5 import fluid.frame;
6 import fluid.input;
7 import fluid.label;
8 import fluid.style;
9 import fluid.utils;
10 import fluid.button;
11 
12 alias hoverButton = simpleConstructor!(HoverButton!Label);
13 alias frameHoverButton = simpleConstructor!(HoverButton!Frame);
14 
15 @safe:
16 
17 /// An button that triggers every frame as long as the button is hovered. Useful for advanced buttons which react to
18 /// more than just left button click.
19 ///
20 /// Note, this is a somewhat low-level node and the hover event, as stated, triggers every frame. There are no hover
21 /// entry nor hover leave events. Make sure you know what you're doing when using this node!
22 class HoverButton(T : Node = Label) : Button!T {
23 
24     mixin defineStyles;
25     mixin enableInputActions;
26 
27     /// Create a new hover button.
28     /// Params:
29     ///     pressed = Action to perform when the button is hovered.
30     this(T...)(T sup) {
31 
32         super(sup);
33 
34     }
35 
36     // Disable action on `press`.
37     protected override void _pressed() {
38 
39     }
40 
41     /// Check events
42     protected override void mouseImpl() {
43 
44         // Simple enough
45         submitted();
46 
47     }
48 
49     protected override bool keyboardImpl() {
50 
51         return false;
52 
53     }
54 
55 }
56 
57 // TODO Needs an example
58 
59 unittest {
60 
61     import fluid.backend;
62 
63     int hoverFrameCount;
64 
65     auto io = new HeadlessBackend;
66     auto root = hoverButton(.nullTheme, "Hello, World!", delegate { hoverFrameCount += 1; });
67 
68     root.io = io;
69 
70     // Move the mouse away from the button
71     io.mousePosition = io.windowSize;
72     root.draw();
73 
74     assert(hoverFrameCount == 0);
75 
76     // Hover the button now
77     io.nextFrame;
78     io.mousePosition = Vector2(0, 0);
79     root.draw();
80 
81     assert(hoverFrameCount == 1);
82 
83     // Press the button
84     io.nextFrame;
85     io.press(MouseButton.left);
86     root.draw();
87 
88     assert(io.isDown(MouseButton.left));
89     assert(hoverFrameCount == 2);
90 
91     // Wait while the button is pressed
92     io.nextFrame;
93     root.draw();
94 
95     assert(io.isDown(MouseButton.left));
96     assert(hoverFrameCount == 3);
97 
98     // Release the button
99     io.nextFrame;
100     io.release(MouseButton.left);
101     root.draw();
102 
103     assert(io.isUp(MouseButton.left));
104     assert(hoverFrameCount == 4);
105 
106     // Move the mouse elsewhere
107     io.nextFrame;
108     io.mousePosition = Vector2(-1, -1);
109     root.draw();
110 
111     assert(hoverFrameCount == 4);
112 
113     // Press the button outside
114     io.nextFrame;
115     io.press(MouseButton.left);
116     root.draw();
117 
118     assert(hoverFrameCount == 4);
119 
120 
121 }