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