Mercurial > projects > mde
diff mde/input/Input.d @ 99:5de5810e3516
Implemented an editable TextContent widget; it's now possible to edit text options using the GUI.
The widget supports moving the text entry-point using arrows and home/end, but there's no visual indicator or edit-point setting using the mouse.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 14 Nov 2008 12:44:32 +0000 |
parents | 97e6dce08037 |
children | 20f7d813bb0f |
line wrap: on
line diff
--- a/mde/input/Input.d Wed Nov 12 13:18:51 2008 +0000 +++ b/mde/input/Input.d Fri Nov 14 12:44:32 2008 +0000 @@ -25,58 +25,79 @@ // sdl imports import derelict.sdl.events; +import derelict.sdl.keyboard; import derelict.sdl.types; // only SDL_PRESSED import derelict.sdl.joystick; // SDL_HAT_* +import Utf = tango.text.convert.Utf; import tango.util.log.Log : Log, Logger; -/** Class encapsulating all input functionality. +/************************************************************************************************** + * Class encapsulating all input functionality. + * + * This class has several modes which affect output: interaction mode (default), text input mode, + * mouse gui mode and axis/button binding modes. + * + * TODO: Gui mode and button capture and axis capture modes for key binding, disabling all + * other modes (except gui-type mouse info?). + * TODO: Possible revisions: remove by-index lookup, only providing callbacks? + * TODO: Make callbacks send the time of the event? + * TODO: Adjusters, e.g. double-press, hold/click differences. Axis output: via short or double? + * TODO: add an Axis1Callback similar to getAxis1? Or remove getAxis1 and provide a conversion function? + * TODO: allow callbacks to be removed. Currently not needed. + * TODO: modifiers in text-input mode: shortcut handling? Global shortcuts - either mode? * - * The following methods are provided for Gui mouse input: + * The primary mode is the interaction mode, mapping each button and axis to a configurable index, + * and allowing event callback functions to be bound per index as well as allowing the state to be + * looked up directly. + * --- + * // For keyboard, joystick and mouse button input + * bool getButton (inputID id); + * void addButtonCallback (inputID id, ButtonCallback dg); // callback receives both up and down events + * + * // For joystick axis input + * short getAxis (inputID id); // range: -32767 .. 32767 + * double getAxis1 (inputID id); // range: -1.0 .. 1.0 + * void addAxisCallback (inputID id, AxisCallback dg); + * + * // For mouse (and joystick ball) relative motion input + * void getRelMotion (inputID id, out double x, out double y); + * void addRelMotionCallback (inputID id, RelMotionCallback dg); + * --- + * + * The keyboard can be put in text input mode, disabling interaction-mode keyboard access and + * providing a callback called on each letter press with it's UTF-8 code. Setting a LetterCallback + * activates text input mode and removing it disables this mode; only one may be active at once. + * --- + * void setLetterCallback (LetterCallback dg); + * --- + * + * Mouse input can be recieved via gui-oriented click/coordinate callbacks in both interaction + * mode and gui mode, however interaction-mode button and relative motion input is not received in + * gui mode. * --- * void getMouseScreenPos (out uint x, out uint y); * void addMouseClickCallback (MouseClickCallback dg); * void addMouseMotionCallback (MouseMotionCallback dg); * --- * - * The following methods are provided for mouse (and joystick ball) relative motion input: - * --- - * void getRelMotion (inputID id, out real x = 0.0, out real y = 0.0); - * void addRelMotionCallback (inputID id, RelMotionCallback dg); - * --- - * - * The following methods are provided for joystick axis input: - * --- - * short getAxis (inputID id); - * real getAxis1 (inputID id); - * void addAxisCallback (inputID id, AxisCallback dg); - * --- - * - * The following methods are provided for keyboard, joystick and mouse button input: - * --- - * bool getButton (inputID id); - * void addButtonCallback (inputID id, ButtonCallback dg) - * --- - * * The following methods are provided for setup & posting events: * --- - * bool opCall (ref SDL_Event event); - * void frameReset (); - * void loadConfig (char[] profile = "Default"); + * bool opCall (ref SDL_Event event); // Handles an event, making all the above work + * void frameReset (); // Needs to be called once per frame for correct relative input + * void loadConfig (char[] profile = "Default"); // Configuration for interaction-mode indexes * --- ***************************************************/ -// FIXME: remove getMouseScreenPos (no use)? -// FIXME: add an Axis1Callback similar to getAxis1? Or remove getAxis1 and provide a conversion -// function? class Input { /// Typedef for all indexes (type is uint). typedef uint inputID; alias void delegate(inputID, bool) ButtonCallback; alias void delegate(inputID, short) AxisCallback; - alias void delegate(inputID, real,real) RelMotionCallback; - alias void delegate(ushort, ushort, ubyte, bool) MouseClickCallback; - alias void delegate(ushort, ushort) MouseMotionCallback; + alias void delegate(inputID, double,double) RelMotionCallback; + alias void delegate(ushort, ushort, ubyte, bool) MouseClickCallback; + alias void delegate(ushort, ushort) MouseMotionCallback; + alias void delegate(ushort, char[]) LetterCallback; /** Get key status at this ID. * @@ -97,38 +118,27 @@ } /** Get axis status at this ID. * - * Returns: value (real; range roughly -1.0 .. 1.0) or 0 if no value at this ID. */ - real getAxis1 (inputID id) { + * Returns: value (double; range roughly -1.0 .. 1.0) or 0 if no value at this ID. */ + double getAxis1 (inputID id) { short* retp = id in axis; if (retp) return (*retp) * 3.0518509475997192e-05; else return 0.0; } - + /** Get the relative motion of the mouse or a joystick ball (since last frameReset() call). * - * Future: Converts to a real via sensitivity settings (defaults may be set and overriden per item). + * Future: Converts to a double via sensitivity settings (defaults may be set and overriden per item). * * To avoid confusion over the ID here, the idea is for the input-layer upward to support * multiple mice, in case future platforms do. * Also joystick balls (supported by SDL) can be used in the same way as a mouse for relative * positions. */ - void getRelMotion (inputID id, out real x = 0.0, out real y = 0.0) { + void getRelMotion (inputID id, out double x = 0.0, out double y = 0.0) { RelPair* rp = id in relMotion; if (rp) { x = rp.x; y = rp.y; } } - /** Get mouse pointer position in screen coordinates. - * - * Window managers only support one mouse, so there will only be one screen coordinate. - * Unlike nearly everything else, this is not configurable. - * - * Also see addMouseMotionCallback. */ - void getMouseScreenPos (out uint x, out uint y) { - x = mouse_x; y = mouse_y; - } - // /// Is this modifier on? - //bool modifierStatus (inputID id); /** Adds a callback delegate for key events (both DOWN and UP) with this ID. * @@ -176,6 +186,24 @@ void addMouseMotionCallback (MouseMotionCallback dg) { mouseMotionCallbacks ~= dg; } + + /** Sets a callback delegate to recieve key presses as a Utf-8 char[]. + * + * Since it is normal to type into only one location at once, setting a new LetterCallback + * removes the last set one (however active ButtonCallbacks will still receive events). + * Supplying a null delegate will turn off the slight overhead of unicode conversion. + * + * The char[] received by the delegate must be copied and not stored or edited directly. */ + void setLetterCallback (LetterCallback dg = null) { + if (dg) { + SDL_EnableUNICODE (1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + } else { + SDL_EnableUNICODE (0); + SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); + } + letterCallback = dg; + } /** Feed an SDL_Event struct (only uses if it's a key, mouse or joystick event). * @@ -207,9 +235,6 @@ break; case SDL_MOUSEMOTION: - mouse_x = event.motion.x; - mouse_y = event.motion.y; - foreach (dg; mouseMotionCallbacks) { try dg (event.motion.x, event.motion.y); @@ -229,7 +254,10 @@ switch (event.type) { // Keyboard events: case SDL_KEYDOWN: + if (letterCallback) + letterCallback (event.key.keysym.sym, Utf.toString ([cast(wchar)event.key.keysym.unicode], cast(char[])utfBuf)); case SDL_KEYUP: + if (letterCallback) break; // text input mode; no keyboard input from mappings outQueue[]* p = (Config.B.SDLKEY | event.key.keysym.sym) in config.button; if (p) foreach (outQueue q; *p) { bEvent (this, event.key.state == SDL_PRESSED, readOutQueue(q)); @@ -370,8 +398,8 @@ } struct RelPair { // for mouse/joystick ball motion - real x, y; - static RelPair opCall (real a, real b) { + double x, y; + static RelPair opCall (double a, double b) { RelPair ret; ret.x = a; ret.y = b; return ret; @@ -382,12 +410,12 @@ static Logger logger; - Config config; // Configuration + Config config; // Configuration + char[6] utfBuf; // Buffer for Utf.toString; reallocates if less than 5. - bool[inputID] button; // Table of button states - short[inputID] axis; // Table of axes states - ushort mouse_x, mouse_y; // Current screen coords of the window manager mouse - RelPair[inputID] relMotion; // Table of relative mouse / joystick ball motions + bool[inputID] button; // Table of button states + short[inputID] axis; // Table of axes states + RelPair[inputID] relMotion; // Table of relative mouse / joystick ball motions // NOTE: currently no means of removal ButtonCallback[][inputID] buttonCallbacks; @@ -395,7 +423,8 @@ RelMotionCallback[][inputID] relMotionCallbacks; MouseClickCallback[] mouseClickCallbacks; MouseMotionCallback[] mouseMotionCallbacks; - + LetterCallback letterCallback; + //BEGIN Event stream functionality /* This section contains functions called on an event, which may modify the event (adjuster * functions), and finally output to one (or more) of the state tables (the event stream). @@ -578,7 +607,7 @@ assert (x == (counters[3] ? 0 : 32767)); counters[3] += 1; }); - ut.addRelMotionCallback (0x11F0, delegate void(inputID id, real x, real y) { + ut.addRelMotionCallback (0x11F0, delegate void(inputID id, double x, double y) { assert (x == 14.0); assert (y == -1.0); counters[4] += 1; @@ -660,7 +689,7 @@ assert (ut.getAxis(0x21F0) == -32767); assert (ut.getAxis1(0x22F0) == 0.0); - real s,t; + double s,t; ut.getRelMotion(0x10F0, s,t); assert (s == 14.0); assert (t == -1.0);