diff options
Diffstat (limited to 'src/ui/keys.c')
-rw-r--r-- | src/ui/keys.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/src/ui/keys.c b/src/ui/keys.c index 5b88bfcf..ea874343 100644 --- a/src/ui/keys.c +++ b/src/ui/keys.c | |||
@@ -56,25 +56,46 @@ static void clear_Keys_(iKeys *d) { | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | enum iBindFlag { | ||
60 | argRepeat_BindFlag = iBit(1), | ||
61 | }; | ||
62 | |||
59 | /* TODO: This indirection could be used for localization, although all UI strings | 63 | /* TODO: This indirection could be used for localization, although all UI strings |
60 | would need to be similarly handled. */ | 64 | would need to be similarly handled. */ |
61 | static const struct { int id; iMenuItem bind; } defaultBindings_[] = { | 65 | static const struct { int id; iMenuItem bind; int flags; } defaultBindings_[] = { |
62 | { 1, { "Jump to top", SDLK_HOME, 0, "scroll.top" } }, | 66 | { 1, { "Jump to top", SDLK_HOME, 0, "scroll.top" }, 0 }, |
63 | { 2, { "Jump to bottom", SDLK_END, 0, "scroll.bottom" } }, | 67 | { 2, { "Jump to bottom", SDLK_END, 0, "scroll.bottom" }, 0 }, |
64 | { 10, { "Scroll up", SDLK_UP, 0, "scroll.step arg:-1" } }, | 68 | { 10, { "Scroll up", SDLK_UP, 0, "scroll.step arg:-1" }, argRepeat_BindFlag }, |
65 | { 11, { "Scroll down", SDLK_DOWN, 0, "scroll.step arg:1" } }, | 69 | { 11, { "Scroll down", SDLK_DOWN, 0, "scroll.step arg:1" }, argRepeat_BindFlag }, |
66 | { 20, { "Scroll up half a page", SDLK_PAGEUP, 0, "scroll.page arg:-1" } }, | 70 | { 20, { "Scroll up half a page", SDLK_PAGEUP, 0, "scroll.page arg:-1" }, argRepeat_BindFlag }, |
67 | { 21, { "Scroll down half a page", SDLK_PAGEDOWN, 0, "scroll.page arg:1" } }, | 71 | { 21, { "Scroll down half a page", SDLK_PAGEDOWN, 0, "scroll.page arg:1" }, argRepeat_BindFlag }, |
68 | { 30, { "Go back", navigateBack_KeyShortcut, "navigate.back" } }, | 72 | { 30, { "Go back", navigateBack_KeyShortcut, "navigate.back" }, 0 }, |
69 | { 31, { "Go forward", navigateForward_KeyShortcut, "navigate.forward" } }, | 73 | { 31, { "Go forward", navigateForward_KeyShortcut, "navigate.forward" }, 0 }, |
70 | { 32, { "Go to parent directory", navigateParent_KeyShortcut, "navigate.parent" } }, | 74 | { 32, { "Go to parent directory", navigateParent_KeyShortcut, "navigate.parent" }, 0 }, |
71 | { 33, { "Go to site root", navigateRoot_KeyShortcut, "navigate.root" } }, | 75 | { 33, { "Go to site root", navigateRoot_KeyShortcut, "navigate.root" }, 0 }, |
72 | { 40, { "Open link via keyboard", 'f', 0, "document.linkkeys"} }, | 76 | { 40, { "Open link via keyboard", 'f', 0, "document.linkkeys" }, 0 }, |
73 | /* The following cannot currently be changed (built-in duplicates). */ | 77 | /* The following cannot currently be changed (built-in duplicates). */ |
74 | { 1000, { NULL, SDLK_SPACE, KMOD_SHIFT, "scroll.page arg:-1" } }, | 78 | { 1000, { NULL, SDLK_SPACE, KMOD_SHIFT, "scroll.page arg:-1" }, argRepeat_BindFlag }, |
75 | { 1001, { NULL, SDLK_SPACE, 0, "scroll.page arg:1" } }, | 79 | { 1001, { NULL, SDLK_SPACE, 0, "scroll.page arg:1" }, argRepeat_BindFlag }, |
76 | }; | 80 | }; |
77 | 81 | ||
82 | static iBinding *findId_Keys_(iKeys *d, int id) { | ||
83 | iForEach(Array, i, &d->bindings) { | ||
84 | iBinding *bind = i.value; | ||
85 | if (bind->id == id) { | ||
86 | return bind; | ||
87 | } | ||
88 | } | ||
89 | return NULL; | ||
90 | } | ||
91 | |||
92 | static void setFlags_Keys_(int id, int bindFlags) { | ||
93 | iBinding *bind = findId_Keys_(&keys_, id); | ||
94 | if (bind) { | ||
95 | bind->flags = bindFlags; | ||
96 | } | ||
97 | } | ||
98 | |||
78 | static void bindDefaults_(void) { | 99 | static void bindDefaults_(void) { |
79 | iForIndices(i, defaultBindings_) { | 100 | iForIndices(i, defaultBindings_) { |
80 | const int id = defaultBindings_[i].id; | 101 | const int id = defaultBindings_[i].id; |
@@ -83,6 +104,7 @@ static void bindDefaults_(void) { | |||
83 | if (bind.label) { | 104 | if (bind.label) { |
84 | setLabel_Keys(id, bind.label); | 105 | setLabel_Keys(id, bind.label); |
85 | } | 106 | } |
107 | setFlags_Keys_(id, defaultBindings_[i].flags); | ||
86 | } | 108 | } |
87 | } | 109 | } |
88 | 110 | ||
@@ -95,16 +117,6 @@ static iBinding *find_Keys_(iKeys *d, int key, int mods) { | |||
95 | return NULL; | 117 | return NULL; |
96 | } | 118 | } |
97 | 119 | ||
98 | static iBinding *findId_Keys_(iKeys *d, int id) { | ||
99 | iForEach(Array, i, &d->bindings) { | ||
100 | iBinding *bind = i.value; | ||
101 | if (bind->id == id) { | ||
102 | return bind; | ||
103 | } | ||
104 | } | ||
105 | return NULL; | ||
106 | } | ||
107 | |||
108 | static iBinding *findCommand_Keys_(iKeys *d, const char *command) { | 120 | static iBinding *findCommand_Keys_(iKeys *d, const char *command) { |
109 | /* Note: O(n) */ | 121 | /* Note: O(n) */ |
110 | iForEach(Array, i, &d->bindings) { | 122 | iForEach(Array, i, &d->bindings) { |
@@ -259,7 +271,12 @@ iBool processEvent_Keys(const SDL_Event *ev) { | |||
259 | if (ev->type == SDL_KEYDOWN) { | 271 | if (ev->type == SDL_KEYDOWN) { |
260 | const iBinding *bind = find_Keys_(d, ev->key.keysym.sym, keyMods_Sym(ev->key.keysym.mod)); | 272 | const iBinding *bind = find_Keys_(d, ev->key.keysym.sym, keyMods_Sym(ev->key.keysym.mod)); |
261 | if (bind) { | 273 | if (bind) { |
262 | postCommandString_App(&bind->command); | 274 | if (ev->key.repeat && (bind->flags & argRepeat_BindFlag)) { |
275 | postCommandf_App("%s repeat:1", cstr_String(&bind->command)); | ||
276 | } | ||
277 | else { | ||
278 | postCommandString_App(&bind->command); | ||
279 | } | ||
263 | return iTrue; | 280 | return iTrue; |
264 | } | 281 | } |
265 | } | 282 | } |