1 /// 2 module glui.input; 3 4 import raylib; 5 6 import std.meta; 7 8 import glui.node; 9 import glui.structs; 10 import glui.style; 11 12 @safe: 13 14 // TODO This could probably be just a plain interface, replacing GluiFocusable 15 16 /// Represents a general input node. 17 /// 18 /// Styles: $(UL 19 /// $(LI `styleKey` = Default style for the input.) 20 /// $(LI `focusStyleKey` = Style for when the input is focused.) 21 /// $(LI `disabledStyleKey` = Style for when the input is disabled.) 22 /// ) 23 abstract class GluiInput(Parent : GluiNode) : Parent, GluiFocusable { 24 25 mixin DefineStyles!( 26 "focusStyle", q{ style }, 27 "hoverStyle", q{ style }, 28 "disabledStyle", q{ style }, 29 ); 30 31 /// Callback to run when the input value is altered. 32 void delegate() changed; 33 34 /// Callback to run when the input is submitted. 35 void delegate() submitted; 36 37 this(T...)(T sup) { 38 39 super(sup); 40 41 } 42 43 override ref inout(bool) isDisabled() inout { return super.isDisabled; } 44 45 override const(Style) pickStyle() const { 46 47 // Disabled 48 if (isDisabledInherited) return disabledStyle; 49 50 // Focused 51 else if (isFocused) return focusStyle; 52 53 // Hovered 54 else if (isHovered) return hoverStyle; 55 56 // Other 57 else return style; 58 59 } 60 61 /// Handle mouse input. 62 /// 63 /// Only one node can run its `inputImpl` callback per frame, specifically, the last one to register its input. 64 /// This is to prevent parents or overlapping children to take input when another node is drawn on them. 65 protected abstract void mouseImpl(); 66 67 /// Handle keyboard input. 68 /// 69 /// This will be called each frame as long as this node has focus. 70 /// 71 /// Returns: True if the input was handled, false if not. 72 protected abstract bool keyboardImpl(); 73 74 /// Change the focus to this node. 75 void focus() { 76 77 // Ignore if disabled 78 if (isDisabled) return; 79 80 tree.focus = this; 81 82 } 83 84 // TODO naming consistence?? 85 @property { 86 87 /// Check if the node has focus. 88 bool isFocused() const { 89 90 return tree.focus is this; 91 92 } 93 94 /// Set or remove focus from this node. 95 bool isFocused(bool enable) { 96 97 if (enable) focus(); 98 else if (isFocused) tree.focus = null; 99 100 return enable; 101 102 } 103 104 } 105 106 }