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 }