Skip to content

Commit

Permalink
support mouse buttons 4 though 15 for keybindings
Browse files Browse the repository at this point in the history
  • Loading branch information
myk002 committed Apr 2, 2024
1 parent 55bfcce commit 16067af
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
31 changes: 21 additions & 10 deletions docs/builtins/keybinding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ bindings are not remembered between runs of the game unless re-created in
:file:`dfhack-config/init/dfhack.init`.

Hotkeys can be any combinations of Ctrl/Alt/Shift with A-Z, 0-9, F1-F12, or `
(the key below the :kbd:`Esc` key on most keyboards).
(the key below the :kbd:`Esc` key on most keyboards). You can also represent
mouse buttons beyond the first three with ``MOUSE4`` through ``MOUSE15``.

Usage
-----
Expand Down Expand Up @@ -61,12 +62,22 @@ require the console for interactive input.
Examples
--------

``keybinding add Ctrl-Shift-C hotkeys``
Bind Ctrl-Shift-C to run the `hotkeys` command on any screen at any time.
``keybinding add Alt-F@dwarfmode gui/quickfort``
Bind Alt-F to run `gui/quickfort`, but only when on a screen that shows the
main map.
``keybinding add Ctrl-Shift-Z@dwarfmode/Default "stocks show"``
Bind Ctrl-Shift-Z to run `stocks show <stocks>`, but only when on the main
map in the default mode (that is, no special mode, like cursor look, is
enabled).
Bind Ctrl-Shift-C to run the `hotkeys` command on any screen at any time::

keybinding add Ctrl-Shift-C hotkeys

Bind Ctrl-M to run `gui/mass-remove`, but only when on the main map with
nothing else selected::

keybinding add Ctrl-M@dwarfmode/Default gui/mass-remove

Bind the fourth mouse button to launch `gui/teleport` when a unit is selected
or `gui/autodump` when an item is selected::

keybinding add MOUSE4@dwarfmode/ViewSheets/UNIT gui/teleport
keybinding add MOUSE4@dwarfmode/ViewSheets/ITEM gui/autodump

Bind Shift + the fifth mouse button to toggle the keyboard cursor in fort or
adventure mode::

keybinding add Shift-MOUSE5@dwarfmode|dungeonmode toggle-kbd-cursor
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Template for new versions:
- `tailor`: allow turning off automatic confiscation of tattered clothing
- aquifer tap blueprint: now designates in damp dig mode for uninterrupted digging in a light aquifer
- pump stack blueprint: now designates in warm and damp dig mode for uninterrupted digging through warm and damp tiles
- `keybinding`: you can now assign keybindings to mouse buttons (if your mouse has more than the three buttons already used by DF)

## Documentation
- ``Lua API.rst``: added previously undocumented ``next_item(index)`` function for enum types
Expand Down
21 changes: 17 additions & 4 deletions library/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2390,8 +2390,7 @@ bool Core::DFH_SDL_Event(SDL_Event* ev)
{
// the check against hotkey_states[sym] ensures we only process keybindings once per keypress
DEBUG(keybinding).print("key down: sym=%d (%c)\n", sym, sym);
bool handled = SelectHotkey(sym, modstate);
if (handled) {
if (SelectHotkey(sym, modstate)) {
hotkey_states[sym] = true;
if (modstate & (DFH_MOD_CTRL | DFH_MOD_ALT)) {
DEBUG(keybinding).print("modifier key detected; not inhibiting SDL key down event\n");
Expand All @@ -2407,8 +2406,16 @@ bool Core::DFH_SDL_Event(SDL_Event* ev)
DEBUG(keybinding).print("key up: sym=%d (%c)\n", sym, sym);
hotkey_states[sym] = false;
}
}
else if (ev->type == SDL_TEXTINPUT) {
} else if (ev->type == SDL_MOUSEBUTTONDOWN) {
auto &but = ev->button;
DEBUG(keybinding).print("mouse button down: button=%d\n", but.button);
// don't mess with the first three buttons, which are critical elements of DF's control scheme
if (but.button > 3) {
SDL_Keycode sym = SDLK_F13 + but.button - 4;
if (sym <= SDLK_F24 && SelectHotkey(sym, modstate))
return suppress_duplicate_keyboard_events;
}
} else if (ev->type == SDL_TEXTINPUT) {
auto &te = ev->text;
DEBUG(keybinding).print("text input: '%s' (modifiers: %s%s%s)\n",
te.text,
Expand Down Expand Up @@ -2549,6 +2556,12 @@ static bool parseKeySpec(std::string keyspec, int *psym, int *pmod, std::string
} else if (keyspec.size() == 3 && keyspec.substr(0, 2) == "F1" && keyspec[2] >= '0' && keyspec[2] <= '2') {
*psym = SDLK_F10 + (keyspec[2]-'0');
return true;
} else if (keyspec.size() == 6 && keyspec.substr(0, 5) == "MOUSE" && keyspec[5] >= '4' && keyspec[5] <= '9') {
*psym = SDLK_F13 + (keyspec[5]-'4');
return true;
} else if (keyspec.size() == 7 && keyspec.substr(0, 6) == "MOUSE1" && keyspec[5] >= '0' && keyspec[5] <= '5') {
*psym = SDLK_F19 + (keyspec[5]-'0');
return true;
} else if (keyspec == "Enter") {
*psym = SDLK_RETURN;
return true;
Expand Down

0 comments on commit 16067af

Please sign in to comment.