1 module iota.controls.types; 2 3 public import iota.etc.window; 4 import std.conv : to; 5 /* 6 * If `iota_hi_prec_timestamp` is supplied as a version identifier, then MonoTime will be used for timestamps, 7 * otherwise uint will be used. 8 * 9 * However it's not ensured that higher precision will be actually provided, or that it'll be useful. 10 */ 11 version (iota_hi_prec_timestamp) { 12 public import core.time; 13 alias Timestamp = MonoTime; 14 } else { 15 alias Timestamp = uint; 16 } 17 /** 18 * Defines the types of the input devices. 19 */ 20 public enum InputDeviceType : ubyte { 21 init, 22 Keyboard, 23 Mouse, 24 GameController, ///Joysticks, gamepads, etc. 25 Pen, ///Graphics tablet, etc. 26 TouchScreen, 27 Gyro, ///Built-in Gyro device. 28 System, ///Misc. system related input devices and events. 29 MIDI, ///If enabled, MIDI devices can function as regular input devices creating regular input events from key press and control change commands. 30 } 31 /** 32 * Defines possible input event types. 33 */ 34 public enum InputEventType { 35 init, 36 Keyboard, 37 TextInput, 38 TextCommand, 39 TextEdit, 40 MouseClick, 41 MouseMove, 42 MouseScroll, 43 GCButton, 44 GCAxis, 45 GCHat, 46 Pen, 47 DeviceAdded, 48 DeviceRemoved, 49 Clipboard, 50 WindowClose, 51 WindowResize, 52 WindowMinimize, 53 WindowMaximize, 54 WindowRestore, 55 WindowMove, 56 ApplExit, 57 } 58 /** 59 * Defines text command event types. 60 */ 61 public enum TextCommandType { 62 init, 63 Cursor, 64 CursorV, 65 66 Home, 67 End, 68 PageUp, 69 PageDown, 70 71 Delete, 72 73 Insert, 74 75 NewLine, 76 NewPara, 77 78 } 79 /** 80 * Defines return codes for event polling. 81 */ 82 public enum EventPollStatus { 83 Done = 0, 84 HasMore = 1, 85 DeviceInvalidated, 86 DeviceError, 87 NoDevsFound, 88 } 89 /** 90 * Defines text edit event flags. 91 */ 92 public enum TextCommandFlags { 93 PerWord = 1<<0, ///Modifies cursor and delete to work on a per-word basis (essentially holding down the Ctrl key) 94 Select = 1<<1, ///Modifies cursor and other nav commands 95 } 96 /** 97 * Contains basic info about the input device. 98 * Child classes might also contain references to OS variables and pointers. 99 */ 100 public abstract class InputDevice { 101 protected InputDeviceType _type; /// Defines the type of the input device 102 protected ubyte _devNum; /// Defines the number of the input device within the group of same types 103 protected ubyte _battP; /// Current percentage of the battery 104 /// Status flags of the device. 105 /// Bits 0-7 are common, 8-15 are special to each device/interface type. 106 /// Note: flags related to indicators/etc should be kept separately. 107 protected ushort status; 108 /** 109 * Defines common status codes 110 */ 111 public enum StatusFlags : ushort { 112 IsConnected = 1<<0, 113 IsInvalidated = 1<<1, 114 HasBattery = 1<<2, 115 IsAnalog = 1<<3, 116 IsVirtual = 1<<4, 117 } 118 /** 119 * Returns the type of the device. 120 */ 121 public InputDeviceType type() @nogc @safe pure nothrow const @property { 122 return _type; 123 } 124 /** 125 * Returns the device number. 126 */ 127 public ubyte devNum() @nogc @safe pure nothrow const @property { 128 return _devNum; 129 } 130 /** 131 * Returns true if the device is connected. 132 */ 133 public bool isConnected() @nogc @safe pure nothrow const @property { 134 return (status & StatusFlags.IsConnected); 135 } 136 /** 137 * Returns true if device got invalidated (disconnected, etc). 138 */ 139 public bool isInvalidated() @nogc @safe pure nothrow const @property { 140 return (status & StatusFlags.IsInvalidated) != 0; 141 } 142 /** 143 * Returns true if device has analog capabilities. 144 */ 145 public bool isAnalog() @nogc @safe pure nothrow const @property { 146 return (status & StatusFlags.IsAnalog) != 0; 147 } 148 /** 149 * Returns true if device is virtual, emulated, etc. 150 */ 151 public bool isVirtual() @nogc @safe pure nothrow const @property { 152 return (status & StatusFlags.IsVirtual) != 0; 153 } 154 /** 155 * Returns the battery percentage of the device, or ubyte.max if it doesn't have a battery. 156 */ 157 public ubyte battP() @nogc @safe pure nothrow const @property { 158 if (status & StatusFlags.HasBattery) 159 return _battP; 160 else 161 return ubyte.max; 162 } 163 /** 164 * Polls the device for events. 165 * Params: 166 * output = InputEvents outputted by the 167 * Returns: 1 if there's still events to be polled, 0 if no events left. Other values are error codes. 168 */ 169 public abstract int poll(ref InputEvent output) @nogc nothrow; 170 } 171 /** 172 * Defines a button (keyboard, game controller) event data. 173 */ 174 public struct ButtonEvent { 175 ubyte dir; ///Up (0) or down (1) 176 ubyte repeat; ///Used for repetition if supported by source 177 ushort aux; ///Used to identify modifier keys on keyboard, etc. 178 uint id; ///Button ID 179 float auxF; ///Placeholder for pressure-sensitive buttons, NaN otherwise 180 string toString() @safe pure const { 181 return "Direction: " ~ to!string(dir) ~" ; repeat: " ~ to!string(repeat) ~ " ; aux: " ~ to!string(aux) ~ " ; ID: " ~ 182 to!string(id) ~ " ; "; 183 } 184 } 185 /** 186 * Defines the contents of a text input data. 187 * 188 * Version label `iota_use_utf8` will make the middleware to convert text input to UTF8 on non-UTF8 systems, leaving 189 * it out will make UTF32 as the standard 190 */ 191 public struct TextInputEvent { 192 version (iota_use_utf8) { 193 char[] text; 194 } else { 195 dchar[] text; 196 } 197 bool isClipboard;///True if the text input originates from a clipboard event. 198 string toString() @safe pure const { 199 return "Text: \"" ~ to!string(text) ~ "\" isClipboard: " ~ to!string(isClipboard) ~ " ; "; 200 } 201 } 202 /** 203 * Defines text editing command events that could happen during a text input. 204 */ 205 public struct TextCommandEvent { 206 TextCommandType type; ///The type of the text editing event. 207 int amount; ///Amount of the event + direction, if applicable. 208 uint flags; ///Extra flags for text edit events. 209 } 210 /** 211 * Defines an axis event. 212 * Per-axis IDs are being used. 213 */ 214 public struct AxisEvent { 215 uint id; ///Identifier number of the axis. 216 float val; ///Current value of the axis (either -1.0 to 1.0 or 0.0 to 1.0) 217 string toString() @safe pure const { 218 return "ID: " ~ to!string(id) ~ " ; val: " ~ to!string(val) ~ " ; "; 219 } 220 } 221 /** 222 * Defines a mouse click event. 223 * Also supplies the screen coordinates of the click event. 224 */ 225 public struct MouseClickEvent { 226 ubyte dir; ///Up or down 227 ubyte repeat; ///Non-zero if multiple clicks occured. 228 ushort button; ///Button ID 229 int x; ///X coordinate 230 int y; ///Y coordinate 231 string toString() @safe pure const { 232 return "Direction: " ~ to!string(dir) ~ " ; repeat: " ~ to!string(repeat) ~ " ; button: " ~ to!string(button) ~ 233 " ; x: " ~ to!string(x) ~ " y; " ~ to!string(y) ~" ; "; 234 } 235 } 236 /** 237 * Defines a mouse motion event with the buttons that are held down. 238 */ 239 public struct MouseMotionEvent { 240 ///If a bit high, it indicates that button is being held down. 241 ///See enum MouseButtonFlags to identify each button. 242 uint buttons; 243 int x; ///X position of the cursor 244 int y; ///Y position of the cursor 245 int xD; ///X amount of the motion 246 int yD; ///Y amount of the motion 247 string toString() @safe pure const { 248 return "Buttons: " ~ to!string(buttons) ~ " ; x: " ~ to!string(x) ~ " ; y: " ~ to!string(y) ~ " ; xD: " ~ 249 to!string(xD) ~ " ; yD " ~ to!string(yD) ~ " ; "; 250 } 251 } 252 /** 253 * Defines a mouse scroll event. 254 */ 255 public struct MouseScrollEvent { 256 int xS; ///Amount of horizontal scroll 257 int yS; ///Amount of vertical scroll 258 int x; ///X position of the cursor 259 int y; ///Y position of the cursor 260 string toString() @safe pure const { 261 return "xS: " ~ to!string(xS) ~ " ; yS: " ~ to!string(yS) ~ " ; x: " ~ to!string(x) ~ " ; y: " ~ to!string(y) ~ " ; "; 262 } 263 } 264 /** 265 * Defines a pen event of a graphic tablet, screen, etc. 266 */ 267 public struct PenEvent { 268 int x; /// X position of the event 269 int y; /// Y position of the event 270 float tilt; /// The tilt amount of the pen 271 float pDir; /// The direction of the pen 272 float tDir; /// The tilt direction of the pen 273 } 274 public struct WindowEvent { 275 int x; 276 int y; 277 int width; 278 int height; 279 } 280 /** 281 * Contains data generated by input devices. 282 */ 283 public struct InputEvent { 284 InputDevice source; ///Pointer to the source input device class. 285 WindowH handle; ///Window handle for GUI applications if there's any, null otherwise. 286 Timestamp timestamp; ///Timestamp for when the event have happened. 287 InputEventType type; ///Type of the input event. 288 union { 289 ButtonEvent button; 290 TextInputEvent textIn; 291 TextCommandEvent textCmd; 292 AxisEvent axis; 293 MouseClickEvent mouseCE; 294 MouseMotionEvent mouseME; 295 MouseScrollEvent mouseSE; 296 PenEvent pen; 297 } 298 string toString() { 299 string result = "Source: " ~ source.toString ~ " ; Window handle: " ~ to!string(handle) ~ " ; Timestamp: " ~ 300 to!string(timestamp) ~ " ; Type: " ~ to!string(type) ~ " ; Rest: ["; 301 switch (type) { 302 case InputEventType.Keyboard, InputEventType.GCButton: 303 result ~= button.toString(); 304 break; 305 case InputEventType.TextInput: 306 result ~= textIn.toString(); 307 break; 308 case InputEventType.MouseClick: 309 result ~= mouseCE.toString(); 310 break; 311 case InputEventType.MouseMove: 312 result ~= mouseME.toString(); 313 break; 314 case InputEventType.MouseScroll: 315 result ~= mouseSE.toString(); 316 break; 317 default: 318 break; 319 } 320 result ~= "]"; 321 return result; 322 } 323 }