1 ///
2 module fluid.button;
3 
4 import fluid.node;
5 import fluid.frame;
6 import fluid.input;
7 import fluid.label;
8 import fluid.utils;
9 import fluid.style;
10 import fluid.backend;
11 
12 alias button = simpleConstructor!(Button!Label);
13 alias frameButton = simpleConstructor!(Button!Frame);
14 
15 @safe:
16 
17 /// A button can be pressed by the user to trigger an action.
18 ///
19 /// Styles: $(UL
20 ///   $(LI `styleKey` = Default style for the button.)
21 ///   $(LI `hoverStyleKey` = Style to apply when the button is hovered.)
22 ///   $(LI `pressStyleKey` = Style to apply when the button is pressed.)
23 ///   $(LI `focusStyleKey` = Style to apply when the button is focused.)
24 /// )
25 class Button(T : Node = Label) : InputNode!T {
26 
27     mixin DefineStyles!(
28         "pressStyle", q{ hoverStyle },
29     );
30     mixin enableInputActions;
31 
32     /// Callback to run when the button is pressed.
33     alias pressed = submitted;
34 
35     // Button status
36     public {
37 
38         // If true, this button is currenly held down.
39         bool isPressed;
40 
41     }
42 
43     /// Create a new button.
44     /// Params:
45     ///     pressed = Action to perform when the button is pressed.
46     this(T...)(T sup, void delegate() @trusted pressed) {
47 
48         super(sup);
49         this.pressed = pressed;
50 
51     }
52 
53     protected override void drawImpl(Rectangle outer, Rectangle inner) {
54 
55         // Check if pressed
56         isPressed = checkIsPressed;
57         // TODO this should be *false* if key is held down, but wasn't pressed while in focus
58 
59         // Draw the button
60         super.drawImpl(outer, inner);
61 
62     }
63 
64     /// Handle mouse input. By default, this will call the `pressed` delegate if the button is pressed.
65     @(FluidInputAction.press)
66     protected void _pressed() @trusted {
67 
68         // Run the callback
69         pressed();
70 
71     }
72 
73     /// Pick the style.
74     protected override inout(Style) pickStyle() inout {
75 
76         // If pressed
77         if (isPressed) return pressStyle;
78 
79         // If focused
80         if (isFocused) return focusStyle;
81 
82         // If hovered
83         if (isHovered) return hoverStyle;
84 
85         // No decision — normal state
86         return super.pickStyle();
87 
88     }
89 
90     static if (is(typeof(text) : string))
91     override string toString() const {
92 
93         import std.format;
94         return format!"button(%s)"(text);
95 
96     }
97 
98 }