Changeset 99:5de5810e3516
- Timestamp:
- 11/14/08 07:44:32 (2 months ago)
- Files:
-
- data/conf/gui.mtt (modified) (1 diff)
- mde/gui/WidgetManager.d (modified) (6 diffs)
- mde/gui/content/Content.d (modified) (3 diffs)
- mde/gui/renderer/IRenderer.d (modified) (1 diff)
- mde/gui/renderer/SimpleRenderer.d (modified) (1 diff)
- mde/gui/widget/Floating.d (modified) (2 diffs)
- mde/gui/widget/Ifaces.d (modified) (2 diffs)
- mde/gui/widget/TextWidget.d (modified) (1 diff)
- mde/gui/widget/Widget.d (modified) (3 diffs)
- mde/gui/widget/createWidget.d (modified) (3 diffs)
- mde/gui/widget/layout.d (modified) (3 diffs)
- mde/gui/widget/miscContent.d (modified) (2 diffs)
- mde/gui/widget/textContent.d (added)
- mde/input/Input.d (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
data/conf/gui.mtt
r98 r99 15 15 <WidgetData|optVal={0:[0x6030]}> 16 16 <WidgetData|optSep={0:[0x21, 0xff],1:["="]}> 17 <WidgetData|floating={0:[0x8200,1 ,6,14],1:["text","button","blank"]}>18 <WidgetData|text={0:[0x 21,0xE0E000],1:["Floating text"]}>17 <WidgetData|floating={0:[0x8200,13,6,14],1:["text","button","blank"]}> 18 <WidgetData|text={0:[0x4032]}> 19 19 <WDims|content=[736,221,272,79]> 20 20 <WDims|root=[6,736,50,6,580,6]> mde/gui/WidgetManager.d
r97 r99 103 103 IChildWidget widg = child.getWidget (cast(wdabs)cx,cast(wdabs)cy); 104 104 //debug logger.trace ("Click on {}", widg); 105 if (widg !is null) 106 widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state); 105 if (keyFocus && keyFocus !is widg) { 106 keyFocus.keyFocusLost; 107 keyFocus = null; 108 imde.input.setLetterCallback (null); 109 } 110 if (widg !is null) { 111 if (widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state) & 1) { 112 keyFocus = widg; 113 imde.input.setLetterCallback (&widg.keyEvent); 114 } 115 } 107 116 } 108 117 … … 183 192 } 184 193 194 void preSave () { 195 if (keyFocus) { 196 keyFocus.keyFocusLost; 197 keyFocus = null; 198 imde.input.setLetterCallback (null); 199 } 200 } 201 185 202 private: 203 IRenderer rend; 204 wdim w,h; // area available to the widgets 205 wdim mw,mh; // minimal area available to the widgets 186 206 // callbacks indexed by their frame pointers: 187 207 bool delegate(wdabs cx, wdabs cy, ubyte b, bool state) [void*] clickCallbacks; 188 208 void delegate(wdabs cx, wdabs cy) [void*] motionCallbacks; 189 IRenderer rend; 190 wdim w,h; // area available to the widgets 191 wdim mw,mh; // minimal area available to the widgets 209 IChildWidget keyFocus; // widget receiving keyboard input when non-null 192 210 } 193 211 … … 287 305 */ 288 306 void loadDesign (char[] name = null) { 289 if (changes !is null) 307 if (changes !is null) // A design was previously loaded 290 308 save; // own lock 291 309 292 mutex.lock;310 mutex.lock; 293 311 scope(exit) mutex.unlock; 294 312 … … 316 334 317 335 mt.IDataSection* q = name in changesDS.sec; 318 if (q && ((changes = cast(WidgetDataChanges) *q) !is null)) {} 319 else { 336 if (!q || ((changes = cast(WidgetDataChanges) *q) is null)) { 320 337 changes = new WidgetDataChanges (curData); 321 338 changesDS.sec[name] = changes; … … 330 347 * Is run when the manager is destroyed, but could be run at other times too. */ 331 348 void save () { 349 preSave; 350 332 351 mutex.lock; 333 352 scope(exit) mutex.unlock; … … 455 474 void createRootWidget(); 456 475 457 protected: 458 final char[] fileName; 459 char[] defaultDesign; // The design specified in the file header. 460 char[] rendName; // Name of renderer; for saving and creating renderers 461 462 // Loaded data, indexed by design name. May not be loaded for all gui designs: 463 scope WidgetDataSet[char[]] data; 464 private bool allLoaded = false; // applies to data 465 WidgetDataSet curData; // Current data 466 WidgetDataChanges changes; // Changes for the current design. 467 scope mt.DataSet changesDS; // changes and sections from user file (used for saving) 468 bool loadUserFile = true; // still need to load user file for saving? 469 470 scope IChildWidget child; // The primary widget. 471 472 Mutex mutex; // lock on methods for use outside the package. 476 /** Called before saving (usually when the GUI is about to be destroyed, although not 477 * necessarily). */ 478 void preSave () {} 479 480 protected: 481 final char[] fileName; 482 char[] defaultDesign; // The design specified in the file header. 483 char[] rendName; // Name of renderer; for saving and creating renderers 484 485 // Loaded data, indexed by design name. May not be loaded for all gui designs: 486 scope WidgetDataSet[char[]] data; 487 private bool allLoaded = false; // applies to data 488 WidgetDataSet curData; // Current data 489 WidgetDataChanges changes; // Changes for the current design. 490 scope mt.DataSet changesDS; // changes and sections from user file (used for saving) 491 bool loadUserFile = true; // still need to load user file for saving? 492 493 scope IChildWidget child; // The primary widget. 494 495 Mutex mutex; // lock on methods for use outside the package. 473 496 } mde/gui/content/Content.d
r98 r99 21 21 import Int = tango.text.convert.Integer; 22 22 import Float = tango.text.convert.Float; 23 import derelict.sdl.keysym; 23 24 24 25 debug { … … 152 153 symb = symbol; 153 154 v = val; 155 pos = v.length; 154 156 } 155 157 … … 178 180 alias opCall opCast; 179 181 182 /** Acts on a keystroke and returns the new value. 183 * 184 * Supports one-line editing: left/right, home/end, backspace/delete. */ 185 char[] keyStroke (ushort sym, char[] i) { 186 debug assert (i.length, "TextContent.keyStroke: no value (??)"); // impossible? 187 char k = *i; 188 if (k > 0x20) { 189 if (k == 0x7f) { // delete 190 size_t p = pos; 191 if (p < v.length) ++p; 192 while (p < v.length && (v[p] & 0x80) && !(v[p] & 0x40)) 193 ++p; 194 v = v[0..pos] ~ v[p..$]; 195 } else { // insert character 196 char[] tail = v[pos..$]; 197 v.length = v.length + i.length; 198 size_t npos = pos+i.length; 199 if (tail) v[npos..$] = tail.dup; // cannot assign with overlapping ranges 200 v[pos..npos] = i; 201 pos = npos; 202 } 203 } else { // use sym; many keys output 0 204 if (sym == SDLK_BACKSPACE) { // backspace; k == 0x8 205 char[] tail = v[pos..$]; 206 if (pos) --pos; 207 while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40)) 208 --pos; 209 v = v[0..pos] ~ tail; 210 } else if (sym == SDLK_LEFT) { 211 if (pos) --pos; 212 while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40)) 213 --pos; 214 } else if (sym == SDLK_RIGHT) { 215 if (pos < v.length) ++pos; 216 while (pos < v.length && (v[pos] & 0x80) && !(v[pos] & 0x40)) 217 ++pos; 218 } else if (sym == SDLK_HOME || sym == SDLK_UP) { 219 pos = 0; 220 } else if (sym == SDLK_END || sym == SDLK_DOWN) { 221 pos = v.length; 222 } else 223 debug logger.trace ("Symbol: {}", sym); 224 } 225 return v; 226 } 227 228 /// Gives all callbacks the modified value 229 void endEdit () { 230 foreach (cb; cngCb) 231 cb(symb, v); 232 } 233 180 234 char[] v; 181 235 protected: 182 236 char[] symb; 237 size_t pos; // editing position; used by keyStroke 183 238 void delegate (char[],char[])[] cngCb; 184 239 } mde/gui/renderer/IRenderer.d
r97 r99 88 88 * interfaces when available to allow flexibility. */ 89 89 struct TextAdapter { 90 void set (char[] c, int col) {90 void setText (char[] c) { 91 91 content = c; 92 colour = Colour (col); 92 textCache.cacheVer = -1; // force update 93 93 } 94 95 void setColour (int col = 0xFFFFFF) { 96 colour = Colour (col); 97 } 94 98 95 99 void getDimensions (out wdsize w, out wdsize h) { mde/gui/renderer/SimpleRenderer.d
r97 r99 134 134 TextAdapter a; 135 135 a.font = defaultFont; 136 a.set (text, col); 136 a.content = text; 137 a.colour = Colour (col); 137 138 return a; 138 139 } mde/gui/widget/Floating.d
r97 r99 150 150 } 151 151 152 voidclickEvent (wdabs cx, wdabs cy, ubyte b, bool state) {153 if (event > subWidgets.length) return ;152 int clickEvent (wdabs cx, wdabs cy, ubyte b, bool state) { 153 if (event > subWidgets.length) return 0; 154 154 if (b == 1 && state == true) { 155 155 active = event; … … 181 181 } 182 182 } 183 return 0; 183 184 } 184 185 mde/gui/widget/Ifaces.d
r96 r99 103 103 * gui. */ 104 104 void addMotionCallback (void delegate (wdabs cx, wdabs cy) dg); 105 106 // FIXME: keyboard callback (letter only, for text input? Also used for setting keybindings though...)107 105 108 106 /** Remove all event callbacks on this widget (according to the delegate's .ptr). */ … … 237 235 IChildWidget getWidget (wdim x, wdim y); 238 236 239 /** Receive a mouse click event. 240 * 241 * See mde.input.input.Input.MouseClickCallback for parameters. However, cx and cy are adjusted 242 * to the Widget's local coordinates. 243 * 244 * Widget may assume coordinates are on the widget (caller must check). */ 245 void clickEvent (wdabs cx, wdabs cy, ubyte b, bool state); 237 /** Receive a mouse click event at cx,cy from button b (1-5 correspond to L,M,B, wheel up,down) 238 * which is a down-click if state is true. 239 * 240 * Widget may assume coordinates are on the widget (caller must check). 241 * 242 * The return value has the following flags: 1 to request keyboard input. */ 243 int clickEvent (wdabs cx, wdabs cy, ubyte b, bool state); 244 245 /** Receives keyboard events when requested. 246 * 247 * Params: 248 * sym SDLKey key sym, useful for keys with no character code such as arrow keys 249 * letter The character input, in UTF-8 */ 250 void keyEvent (ushort sym, char[] letter); 251 252 /** Called when keyboard input focus is lost. */ 253 void keyFocusLost (); 246 254 //END Events 247 255 mde/gui/widget/TextWidget.d
r96 r99 77 77 { 78 78 this (IWidgetManager mgr, widgetID id, WidgetData data, IContent c) { 79 debug assert (c, "content is null (code error)");80 79 WDCheck (data, 3, 0); 81 80 content = c; mde/gui/widget/Widget.d
r96 r99 124 124 125 125 /* Dummy event method (suitable for all widgets which don't respond to events). */ 126 void clickEvent (wdabs cx, wdabs cy, ubyte b, bool state) {} 126 int clickEvent (wdabs cx, wdabs cy, ubyte b, bool state) { 127 return 0; 128 } 129 130 /* Dummy functions: suitable for widgets with no text input. */ 131 void keyEvent (ushort, char[]) {} 132 void keyFocusLost () {} 127 133 //END Events 128 134 … … 222 228 223 229 /// Handles the down-click 224 voidclickEvent (wdabs, wdabs, ubyte b, bool state) {230 int clickEvent (wdabs, wdabs, ubyte b, bool state) { 225 231 if (b == 1 && state == true) { 226 232 pushed = true; … … 229 235 mgr.addMotionCallback (&motionWhilePushed); 230 236 } 237 return 0; 231 238 } 232 239 mde/gui/widget/createWidget.d
r98 r99 29 29 import mde.gui.widget.TextWidget; 30 30 import mde.gui.widget.miscContent; 31 import mde.gui.widget.textContent; 31 32 import mde.gui.widget.Floating; 32 33 import tango.util.log.Log : Log, Logger; … … 83 84 /// Widget types. 84 85 enum WIDGET_TYPE : int { 85 FUNCTION = 0x2000, // Function called instead of widget created (no "Widget" appended to fct name)86 TAKES_CONTENT = 0x4000, // Flag indicates widget's this should be passed an IContent reference.87 PARENT = 0x8000, // widget can have children; not used by code (except in data files)86 FUNCTION = 0x2000, // Function called instead of widget created (no "Widget" appended to fct name) 87 TAKES_CONTENT = 0x4000, // Flag indicates widget's this should be passed an IContent reference. 88 PARENT = 0x8000, // widget can have children; not used by code (except in data files) 88 89 89 90 // Use widget names rather than usual capitals convention 90 Unnamed = 0x0, // Only for use by widgets not created with createWidget91 Unnamed = 0x0, // Only for use by widgets not created with createWidget 91 92 92 93 // blank: 0x1 93 FixedBlank = 0x1,94 SizableBlank = 0x2,95 Debug = 0xF,94 FixedBlank = 0x1, 95 SizableBlank = 0x2, 96 Debug = 0xF, 96 97 97 98 // buttons: 0x10 98 Button = 0x10,99 Button = 0x10, 99 100 100 101 // labels: 0x20 101 ContentLabel = TAKES_CONTENT | 0x20,102 TextLabel = 0x21,102 ContentLabel = TAKES_CONTENT | 0x20, 103 TextLabel = 0x21, 103 104 104 105 // content editables: 0x30 105 editContent = FUNCTION | TAKES_CONTENT | 0x30, 106 DisplayContent = TAKES_CONTENT | 0x30, 107 BoolContent = TAKES_CONTENT | 0x31, 106 editContent = FUNCTION | TAKES_CONTENT | 0x30, 107 DisplayContent = TAKES_CONTENT | 0x30, 108 BoolContent = TAKES_CONTENT | 0x31, 109 TextContent = TAKES_CONTENT | 0x32, 108 110 109 GridLayout = TAKES_CONTENT | PARENT | 0x100,110 TrialContentLayout = PARENT | 0x110,111 GridLayout = TAKES_CONTENT | PARENT | 0x100, 112 TrialContentLayout = PARENT | 0x110, 111 113 112 FloatingArea = PARENT | 0x200,114 FloatingArea = PARENT | 0x200, 113 115 } 114 116 … … 125 127 "DisplayContent", 126 128 "BoolContent", 129 "TextContent", 127 130 "editContent", 128 131 "TrialContentLayout", mde/gui/widget/layout.d
r95 r99 248 248 249 249 // Resizing columns & rows 250 voidclickEvent (wdabs cx, wdabs cy, ubyte b, bool state) {250 int clickEvent (wdabs cx, wdabs cy, ubyte b, bool state) { 251 251 debug scope (failure) 252 252 logger.warn ("clickEvent: failure"); … … 258 258 // find col/row's resizeD & resizeU 259 259 if (col.findResizeCols (cx - x) && row.findResizeCols (cy - y)) 260 return ; // unable to resize260 return 0; // unable to resize 261 261 262 262 dragX = cx; … … 266 266 mgr.addMotionCallback (&resizeCallback); 267 267 } 268 return 0; 268 269 } 269 270 mde/gui/widget/miscContent.d
r95 r99 17 17 module mde.gui.widget.miscContent; 18 18 19 import mde.gui.widget.textContent; 19 20 import mde.gui.widget.Widget; 20 21 import mde.gui.widget.TextWidget; … … 28 29 if (cast(BoolContent) c) 29 30 return new BoolContentWidget(mgr,id,data,c); 31 else if (cast(TextContent) c) 32 return new TextContentWidget(mgr,id,data,c); 30 33 else // generic uneditable option 31 34 return new DisplayContentWidget(mgr,id,data,c); mde/input/Input.d
r89 r99 26 26 // sdl imports 27 27 import derelict.sdl.events; 28 import derelict.sdl.keyboard; 28 29 import derelict.sdl.types; // only SDL_PRESSED 29 30 import derelict.sdl.joystick; // SDL_HAT_* 30 31 32 import Utf = tango.text.convert.Utf; 31 33 import tango.util.log.Log : Log, Logger; 32 34 33 /** Class encapsulating all input functionality. 35 /************************************************************************************************** 36 * Class encapsulating all input functionality. 34 37 * 35 * The following methods are provided for Gui mouse input: 38 * This class has several modes which affect output: interaction mode (default), text input mode, 39 * mouse gui mode and axis/button binding modes. 40 * 41 * TODO: Gui mode and button capture and axis capture modes for key binding, disabling all 42 * other modes (except gui-type mouse info?). 43 * TODO: Possible revisions: remove by-index lookup, only providing callbacks? 44 * TODO: Make callbacks send the time of the event? 45 * TODO: Adjusters, e.g. double-press, hold/click differences. Axis output: via short or double? 46 * TODO: add an Axis1Callback similar to getAxis1? Or remove getAxis1 and provide a conversion function? 47 * TODO: allow callbacks to be removed. Currently not needed. 48 * TODO: modifiers in text-input mode: shortcut handling? Global shortcuts - either mode? 49 * 50 * The primary mode is the interaction mode, mapping each button and axis to a configurable index, 51 * and allowing event callback functions to be bound per index as well as allowing the state to be 52 * looked up directly. 53 * --- 54 * // For keyboard, joystick and mouse button input 55 * bool getButton (inputID id); 56 * void addButtonCallback (inputID id, ButtonCallback dg); // callback receives both up and down events 57 * 58 * // For joystick axis input 59 * short getAxis (inputID id); // range: -32767 .. 32767 60 * double getAxis1 (inputID id); // range: -1.0 .. 1.0 61 * void addAxisCallback (inputID id, AxisCallback dg); 62 * 63 * // For mouse (and joystick ball) relative motion input 64 * void getRelMotion (inputID id, out double x, out double y); 65 * void addRelMotionCallback (inputID id, RelMotionCallback dg); 66 * --- 67 * 68 * The keyboard can be put in text input mode, disabling interaction-mode keyboard access and 69 * providing a callback called on each letter press with it's UTF-8 code. Setting a LetterCallback 70 * activates text input mode and removing it disables this mode; only one may be active at once. 71 * --- 72 * void setLetterCallback (LetterCallback dg); 73 * --- 74 * 75 * Mouse input can be recieved via gui-oriented click/coordinate callbacks in both interaction 76 * mode and gui mode, however interaction-mode button and relative motion input is not received in 77 * gui mode. 36 78 * --- 37 79 * void getMouseScreenPos (out uint x, out uint y); … … 40 82 * --- 41 83 * 42 * The following methods are provided for mouse (and joystick ball) relative motion input:43 * ---44 * void getRelMotion (inputID id, out real x = 0.0, out real y = 0.0);45 * void addRelMotionCallback (inputID id, RelMotionCallback dg);46 * ---47 *48 * The following methods are provided for joystick axis input:49 * ---50 * short getAxis (inputID id);51 * real getAxis1 (inputID id);52 * void addAxisCallback (inputID id, AxisCallback dg);53 * ---54 *55 * The following methods are provided for keyboard, joystick and mouse button input:56 * ---57 * bool getButton (inputID id);58 * void addButtonCallback (inputID id, ButtonCallback dg)59 * ---60 *61 84 * The following methods are provided for setup & posting events: 62 85 * --- 63 * bool opCall (ref SDL_Event event); 64 * void frameReset (); 65 * void loadConfig (char[] profile = "Default"); 86 * bool opCall (ref SDL_Event event); // Handles an event, making all the above work 87 * void frameReset (); // Needs to be called once per frame for correct relative input 88 * void loadConfig (char[] profile = "Default"); // Configuration for interaction-mode indexes 66 89 * --- 67 90 ***************************************************/ 68 // FIXME: remove getMouseScreenPos (no use)?69 // FIXME: add an Axis1Callback similar to getAxis1? Or remove getAxis1 and provide a conversion70 // function?71 91 class Input 72 92 { … … 75 95 alias void delegate(inputID, bool) ButtonCallback; 76 96 alias void delegate(inputID, short) AxisCallback; 77 alias void delegate(inputID, real,real) RelMotionCallback; 78 alias void delegate(ushort, ushort, ubyte, bool) MouseClickCallback; 79 alias void delegate(ushort, ushort) MouseMotionCallback; 97 alias void delegate(inputID, double,double) RelMotionCallback; 98 alias void delegate(ushort, ushort, ubyte, bool) MouseClickCallback; 99 alias void delegate(ushort, ushort) MouseMotionCallback; 100 alias void delegate(ushort, char[]) LetterCallback; 80 101 81 102 /** Get key status at this ID. … … 98 119 /** Get axis status at this ID. 99 120 * 100 * Returns: value ( real; range roughly -1.0 .. 1.0) or 0 if no value at this ID. */101 realgetAxis1 (inputID id) {121 * Returns: value (double; range roughly -1.0 .. 1.0) or 0 if no value at this ID. */ 122 double getAxis1 (inputID id) { 102 123 short* retp = id in axis; 103 124 if (retp) return (*retp) * 3.0518509475997192e-05; 104 125 else return 0.0; 105 126 } 106 127 107 128 /** Get the relative motion of the mouse or a joystick ball (since last frameReset() call). 108 129 * 109 * Future: Converts to a realvia sensitivity settings (defaults may be set and overriden per item).130 * Future: Converts to a double via sensitivity settings (defaults may be set and overriden per item). 110 131 * 111 132 * To avoid confusion over the ID here, the idea is for the input-layer upward to support … … 113 134 * Also joystick balls (supported by SDL) can be used in the same way as a mouse for relative 114 135 * positions. */ 115 void getRelMotion (inputID id, out real x = 0.0, out realy = 0.0) {136 void getRelMotion (inputID id, out double x = 0.0, out double y = 0.0) { 116 137 RelPair* rp = id in relMotion; 117 138 if (rp) { … … 119 140 } 120 141 } 121 /** Get mouse pointer position in screen coordinates.122 *123 * Window managers only support one mouse, so there will only be one screen coordinate.124 * Unlike nearly everything else, this is not configurable.125 *126 * Also see addMouseMotionCallback. */127 void getMouseScreenPos (out uint x, out uint y) {128 x = mouse_x; y = mouse_y;129 }130 // /// Is this modifier on?131 //bool modifierStatus (inputID id);132 142 133 143 /** Adds a callback delegate for key events (both DOWN and UP) with this ID. … … 176 186 void addMouseMotionCallback (MouseMotionCallback dg) { 177 187 mouseMotionCallbacks ~= dg; 188 } 189 190 /** Sets a callback delegate to recieve key presses as a Utf-8 char[]. 191 * 192 * Since it is normal to type into only one location at once, setting a new LetterCallback 193 * removes the last set one (however active ButtonCallbacks will still receive events). 194 * Supplying a null delegate will turn off the slight overhead of unicode conversion. 195 * 196 * The char[] received by the delegate must be copied and not stored or edited directly. */ 197 void setLetterCallback (LetterCallback dg = null) { 198 if (dg) { 199 SDL_EnableUNICODE (1); 200 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 201 } else { 202 SDL_EnableUNICODE (0); 203 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); 204 } 205 letterCallback = dg; 178 206 } 179 207 … … 208 236 209 237 case SDL_MOUSEMOTION: 210 mouse_x = event.motion.x;211 mouse_y = event.motion.y;212 213 238 foreach (dg; mouseMotionCallbacks) { 214 239 try … … 230 255 // Keyboard events: 231 256 case SDL_KEYDOWN: 257 if (letterCallback) 258 letterCallback (event.key.keysym.sym, Utf.toString ([cast(wchar)event.key.keysym.unicode], cast(char[])utfBuf)); 232 259 case SDL_KEYUP: 260 if (letterCallback) break; // text input mode; no keyboard input from mappings 233 261 outQueue[]* p = (Config.B.SDLKEY | event.key.keysym.sym) in config.button; 234 262 if (p) foreach (outQueue q; *p) { … … 371 399 372 400 struct RelPair { // for mouse/joystick ball motion 373 realx, y;374 static RelPair opCall ( real a, realb) {401 double x, y; 402 static RelPair opCall (double a, double b) { 375 403 RelPair ret; 376 404 ret.x = a; ret.y = b; … … 383 411 static Logger logger; 384 412 385 Config config; // Configuration386 387 bool[inputID] button; // Table of button states388 short[inputID] axis; // Table of axesstates389 ushort mouse_x, mouse_y; // Current screen coords of the window manager mouse390 RelPair[inputID] relMotion; // Table of relative mouse / joystick ball motions413 Config config; // Configuration 414 char[6] utfBuf; // Buffer for Utf.toString; reallocates if less than 5. 415 416 bool[inputID] button; // Table of button states 417 short[inputID] axis; // Table of axes states 418 RelPair[inputID] relMotion; // Table of relative mouse / joystick ball motions 391 419 392 420 // NOTE: currently no means of removal … … 396 424 MouseClickCallback[] mouseClickCallbacks; 397 425 MouseMotionCallback[] mouseMotionCallbacks; 398 426 LetterCallback letterCallback; 427 399 428 //BEGIN Event stream functionality 400 429 /* This section contains functions called on an event, which may modify the event (adjuster … … 579 608 counters[3] += 1; 580 609 }); 581 ut.addRelMotionCallback (0x11F0, delegate void(inputID id, real x, realy) {610 ut.addRelMotionCallback (0x11F0, delegate void(inputID id, double x, double y) { 582 611 assert (x == 14.0); 583 612 assert (y == -1.0); … … 661 690 assert (ut.getAxis1(0x22F0) == 0.0); 662 691 663 reals,t;692 double s,t; 664 693 ut.getRelMotion(0x10F0, s,t); 665 694 assert (s == 14.0);
