1 // Written in the D programming language. 2 3 /** 4 DLANGUI library. 5 6 This module contains dlangui event types declarations. 7 8 9 Synopsis: 10 11 ---- 12 import dlangui.core.events; 13 14 ---- 15 16 Copyright: Vadim Lopatin, 2014 17 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 18 Authors: $(WEB coolreader.org, Vadim Lopatin) 19 */ 20 module dlangui.core.events; 21 22 import dlangui.core.i18n; 23 private import dlangui.widgets.widget; 24 25 import std.conv; 26 27 /// UI action 28 class Action { 29 protected int _id; 30 protected UIString _label; 31 protected string _iconId; 32 this(int id, string labelResourceId, string iconResourceId = null) { 33 _id = id; 34 _label = labelResourceId; 35 _iconId = iconResourceId; 36 } 37 this(int id, dstring label, string iconResourceId = null) { 38 _id = id; 39 _label = label; 40 _iconId = iconResourceId; 41 } 42 @property int id() const { 43 return _id; 44 } 45 @property Action id(int newId) { 46 _id = newId; 47 return this; 48 } 49 @property Action label(string resourceId) { 50 _label = resourceId; 51 return this; 52 } 53 @property Action label(dstring text) { 54 _label = text; 55 return this; 56 } 57 @property dstring label() const { 58 return _label.value; 59 } 60 @property ref const (UIString) labelValue() const { 61 return _label; 62 } 63 @property string iconId() const { 64 return _iconId; 65 } 66 @property Action iconId(string id) { 67 _iconId = id; 68 return this; 69 } 70 } 71 72 73 enum MouseAction : ubyte { 74 Cancel, // button down handling is cancelled 75 ButtonDown, // button is down 76 ButtonUp, // button is up 77 Move, // mouse pointer is moving 78 FocusIn, // pointer is back inside widget while button is down after FocusOut 79 FocusOut, // pointer moved outside of widget while button was down (if handler returns true, Move events will be sent even while pointer is outside widget) 80 Wheel, // scroll wheel movement 81 //Hover, // pointer entered widget which while button was not down (return true to track Hover state) 82 Leave // pointer left widget which has before processed Move message, while button was not down 83 } 84 85 enum MouseFlag : ushort { 86 Control = 0x0008, 87 LButton = 0x0001, 88 MButton = 0x0010, 89 RButton = 0x0002, 90 Shift = 0x0004, 91 XButton1= 0x0020, 92 XButton2= 0x0040, 93 Alt = 0x0080 94 } 95 96 /// mouse button state details 97 struct ButtonDetails { 98 /// Clock.currStdTime() for down event of this button (0 if button is up). 99 long _downTs; 100 /// Clock.currStdTime() for up event of this button (0 if button is still down). 101 long _upTs; 102 /// x coordinates of down event 103 short _downX; 104 /// y coordinates of down event 105 short _downY; 106 /// mouse button flags when down event occured 107 ushort _downFlags; 108 /// update for button down 109 void down(short x, short y, ushort flags) { 110 _downX = x; 111 _downY = y; 112 _downFlags = flags; 113 _upTs = 0; 114 _downTs = std.datetime.Clock.currStdTime; 115 } 116 /// update for button up 117 void up(short x, short y, ushort flags) { 118 _upTs = std.datetime.Clock.currStdTime; 119 } 120 @property bool isDown() { return _downTs != 0 && _upTs == 0; } 121 /// returns button down state duration in hnsecs (1/10000 of second). 122 @property int downDuration() { 123 if (_downTs == 0) 124 return 0; 125 if (_downTs != 0 && _upTs != 0) 126 return cast(int)(_upTs - _downTs); 127 long ts = std.datetime.Clock.currStdTime; 128 return cast(int)(ts - _downTs); 129 } 130 @property short downX() { return _downX; } 131 @property short downY() { return _downY; } 132 @property ushort downFlags() { return _downFlags; } 133 } 134 135 enum MouseButton : ubyte { 136 None, 137 Left, 138 Right, 139 Middle 140 //XButton1, // additional button 141 //XButton2, // additional button 142 } 143 144 class MouseEvent { 145 protected long _eventTimestamp; 146 protected MouseAction _action; 147 protected MouseButton _button; 148 protected short _x; 149 protected short _y; 150 protected ushort _flags; 151 protected short _wheelDelta; 152 protected Widget _trackingWidget; 153 protected ButtonDetails _lbutton; 154 protected ButtonDetails _mbutton; 155 protected ButtonDetails _rbutton; 156 protected bool _doNotTrackButtonDown; 157 @property ref ButtonDetails lbutton() { return _lbutton; } 158 @property ref ButtonDetails rbutton() { return _rbutton; } 159 @property ref ButtonDetails mbutton() { return _mbutton; } 160 @property MouseButton button() { return _button; } 161 @property MouseAction action() { return _action; } 162 void changeAction(MouseAction a) { _action = a; } 163 @property ushort flags() { return _flags; } 164 @property short wheelDelta() { return _wheelDelta; } 165 @property short x() { return _x; } 166 @property short y() { return _y; } 167 /// get event tracking widget to override 168 @property Widget trackingWidget() { return _trackingWidget; } 169 @property bool doNotTrackButtonDown() { return _doNotTrackButtonDown; } 170 @property void doNotTrackButtonDown(bool flg) { _doNotTrackButtonDown = flg; } 171 /// override mouse tracking widget 172 void track(Widget w) { 173 _trackingWidget = w; 174 } 175 this (MouseEvent e) { 176 _eventTimestamp = e._eventTimestamp; 177 _action = e._action; 178 _button = e._button; 179 _flags = e._flags; 180 _x = e._x; 181 _y = e._y; 182 _lbutton = e._lbutton; 183 _rbutton = e._rbutton; 184 _mbutton = e._mbutton; 185 _wheelDelta = e._wheelDelta; 186 } 187 this (MouseAction a, MouseButton b, ushort f, short x, short y, short wheelDelta = 0) { 188 _eventTimestamp = std.datetime.Clock.currStdTime; 189 _action = a; 190 _button = b; 191 _flags = f; 192 _x = x; 193 _y = y; 194 _wheelDelta = wheelDelta; 195 } 196 } 197 198 199 enum KeyAction : uint { 200 KeyDown, 201 KeyUp, 202 Text, 203 Repeat, 204 } 205 206 enum KeyFlag : uint { 207 Control = 0x0008, 208 Shift = 0x0004, 209 Alt = 0x0080, 210 RControl = 0x0108, 211 RShift = 0x0104, 212 RAlt = 0x0180 213 } 214 215 enum KeyCode : uint { 216 BACK = 8, 217 TAB = 9, 218 RETURN = 0x0D, 219 SHIFT = 0x10, 220 CONTROL = 0x11, 221 ALT = 0x12, // VK_MENU 222 PAUSE = 0x13, 223 CAPS = 0x14, // VK_CAPITAL, caps lock 224 ESCAPE = 0x1B, // esc 225 SPACE = 0x20, 226 PAGEUP = 0x21, // VK_PRIOR 227 PAGEDOWN = 0x22, // VK_NEXT 228 END = 0x23, // VK_END 229 HOME = 0x24, // VK_HOME 230 LEFT = 0x25, 231 UP = 0x26, 232 RIGHT = 0x27, 233 DOWN = 0x28, 234 INS = 0x2D, 235 DEL = 0x2E, 236 KEY_0 = 0x30, 237 KEY_1 = 0x31, 238 KEY_2 = 0x32, 239 KEY_3 = 0x33, 240 KEY_4 = 0x34, 241 KEY_5 = 0x35, 242 KEY_6 = 0x36, 243 KEY_7 = 0x37, 244 KEY_8 = 0x38, 245 KEY_9 = 0x39, 246 KEY_A = 0x41, 247 KEY_B = 0x42, 248 KEY_C = 0x43, 249 KEY_D = 0x44, 250 KEY_E = 0x45, 251 KEY_F = 0x46, 252 KEY_G = 0x47, 253 KEY_H = 0x48, 254 KEY_I = 0x49, 255 KEY_J = 0x4a, 256 KEY_K = 0x4b, 257 KEY_L = 0x4c, 258 KEY_M = 0x4d, 259 KEY_N = 0x4e, 260 KEY_O = 0x4f, 261 KEY_P = 0x50, 262 KEY_Q = 0x51, 263 KEY_R = 0x52, 264 KEY_S = 0x53, 265 KEY_T = 0x54, 266 KEY_U = 0x55, 267 KEY_V = 0x56, 268 KEY_W = 0x57, 269 KEY_X = 0x58, 270 KEY_Y = 0x59, 271 KEY_Z = 0x5a, 272 LWIN = 0x5b, 273 RWIN = 0x5c, 274 NUM_0 = 0x60, 275 NUM_1 = 0x61, 276 NUM_2 = 0x62, 277 NUM_3 = 0x63, 278 NUM_4 = 0x64, 279 NUM_5 = 0x65, 280 NUM_6 = 0x66, 281 NUM_7 = 0x67, 282 NUM_8 = 0x68, 283 NUM_9 = 0x69, 284 MUL = 0x6A, 285 ADD = 0x6B, 286 DIV = 0x6F, 287 SUB = 0x6D, 288 DECIMAL = 0x6E, 289 F1 = 0x70, 290 F2 = 0x71, 291 F3 = 0x72, 292 F4 = 0x73, 293 F5 = 0x74, 294 F6 = 0x75, 295 F7 = 0x76, 296 F8 = 0x77, 297 F9 = 0x78, 298 F10 = 0x79, 299 F11 = 0x7a, 300 F12 = 0x7b, 301 F13 = 0x7c, 302 F14 = 0x7d, 303 F15 = 0x7e, 304 F16 = 0x7f, 305 F17 = 0x80, 306 F18 = 0x81, 307 F19 = 0x82, 308 F20 = 0x83, 309 F21 = 0x84, 310 F22 = 0x85, 311 F23 = 0x86, 312 F24 = 0x87, 313 NUMLOCK = 0x90, 314 SCROLL = 0x91, // scroll lock 315 LSHIFT = 0xA0, 316 RSHIFT = 0xA1, 317 LCONTROL = 0xA2, 318 RCONTROL = 0xA3, 319 LALT = 0xA4, 320 RALT = 0xA5, 321 } 322 323 /// keyboard event 324 class KeyEvent { 325 protected KeyAction _action; 326 protected uint _keyCode; 327 protected uint _flags; 328 protected dstring _text; 329 /// key action (KeyDown, KeyUp, Text, Repeat) 330 @property KeyAction action() { return _action; } 331 /// key code 332 @property uint keyCode() { return _keyCode; } 333 /// flags (shift, ctrl, alt...) 334 @property uint flags() { return _flags; } 335 /// entered text, for Text action 336 @property dstring text() { return _text; } 337 /// create key event 338 this(KeyAction action, uint keyCode, uint flags, dstring text = null) { 339 _action = action; 340 _keyCode = keyCode; 341 _flags = flags; 342 _text = text; 343 } 344 } 345 346 enum ScrollAction : ubyte { 347 /// space above indicator pressed 348 PageUp, 349 /// space below indicator pressed 350 PageDown, 351 /// up/left button pressed 352 LineUp, 353 /// down/right button pressed 354 LineDown, 355 /// slider pressed 356 SliderPressed, 357 /// dragging in progress 358 SliderMoved, 359 /// dragging finished 360 SliderReleased 361 } 362 363 /// slider/scrollbar event 364 class ScrollEvent { 365 private ScrollAction _action; 366 private int _minValue; 367 private int _maxValue; 368 private int _pageSize; 369 private int _position; 370 private bool _positionChanged; 371 @property ScrollAction action() { return _action; } 372 @property int minValue() { return _minValue; } 373 @property int maxValue() { return _maxValue; } 374 @property int pageSize() { return _pageSize; } 375 @property int position() { return _position; } 376 @property bool positionChanged() { return _positionChanged; } 377 /// change position in event handler to update slider position 378 @property void position(int newPosition) { _position = newPosition; _positionChanged = true; } 379 this(ScrollAction action, int minValue, int maxValue, int pageSize, int position) { 380 _action = action; 381 _minValue = minValue; 382 _maxValue = maxValue; 383 _pageSize = pageSize; 384 _position = position; 385 } 386 /// default update position for actions like PageUp/PageDown, LineUp/LineDown 387 int defaultUpdatePosition() { 388 int delta = 0; 389 switch (_action) { 390 case ScrollAction.LineUp: 391 delta = _pageSize / 20; 392 if (delta < 1) 393 delta = 1; 394 delta = -delta; 395 break; 396 case ScrollAction.LineDown: 397 delta = _pageSize / 20; 398 if (delta < 1) 399 delta = 1; 400 break; 401 case ScrollAction.PageUp: 402 delta = _pageSize * 3 / 4; 403 if (delta < 1) 404 delta = 1; 405 delta = -delta; 406 break; 407 case ScrollAction.PageDown: 408 delta = _pageSize * 3 / 4; 409 if (delta < 1) 410 delta = 1; 411 break; 412 default: 413 return position; 414 } 415 int newPosition = _position + delta; 416 if (newPosition > _maxValue - _pageSize) 417 newPosition = _maxValue - _pageSize; 418 if (newPosition < _minValue) 419 newPosition = _minValue; 420 if (_position != newPosition) 421 position = newPosition; 422 return position; 423 } 424 }