Skip to content

Commit

Permalink
Fix #24681: Use composed hotkeys where appropriate and revert help to…
Browse files Browse the repository at this point in the history
… be ':'

This enables textinput events in SDL and adds handling of them. The events
are processed for hotkeys if the length of the hotkey string is 1 (which is the
case for all straightforward hotkeys).
  • Loading branch information
aginor committed Apr 28, 2017
1 parent d0b9f43 commit 5385898
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 54 deletions.
2 changes: 1 addition & 1 deletion data/core/hotkeys.cfg
Expand Up @@ -83,7 +83,7 @@
[/hotkey]
[hotkey]
command=command
key=;
key=:
[/hotkey]
[hotkey]
command=continue
Expand Down
5 changes: 5 additions & 0 deletions src/controller_base.cpp
Expand Up @@ -55,6 +55,11 @@ void controller_base::handle_event(const SDL_Event& event)
static const hotkey::hotkey_command& quit_hotkey = hotkey::hotkey_command::get_command_by_command(hotkey::HOTKEY_QUIT_GAME);

switch(event.type) {
case SDL_TEXTINPUT:
if(have_keyboard_focus()) {
hotkey::key_event(event, get_hotkey_command_executor());
}
break;
case SDL_KEYDOWN:
// Detect key press events, unless there something that has keyboard focus
// in which case the key press events should go only to it.
Expand Down
5 changes: 4 additions & 1 deletion src/hotkey/command_executor.cpp
Expand Up @@ -546,7 +546,10 @@ static void event_execute( const SDL_Event& event, command_executor* executor)
return;
}

bool press = event.type == SDL_KEYDOWN || event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN;
bool press = event.type == SDL_KEYDOWN ||
event.type == SDL_JOYBUTTONDOWN ||
event.type == SDL_MOUSEBUTTONDOWN ||
event.type == SDL_TEXTINPUT;

execute_command(hotkey::get_hotkey_command(hk->get_command()), executor, -1, press);
executor->set_button_state();
Expand Down
94 changes: 49 additions & 45 deletions src/hotkey/hotkey_item.cpp
@@ -1,5 +1,5 @@
/*
Copyright (C) 2003 - 2017 by David White <dave@whitevine.net>
Copyright (C) 2003 - 2016 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -128,17 +128,11 @@ bool hotkey_base::bindings_equal(hotkey_ptr other)

bool hotkey_base::matches(const SDL_Event &event) const
{
unsigned int mods = sdl_get_mods();

if (!hotkey::is_scope_active(hotkey::get_hotkey_command(get_command()).scope) ||
!active() || is_disabled()) {
return false;
}

if ((mods != mod_)) {
return false;
}

return matches_helper(event);
}

Expand All @@ -155,30 +149,31 @@ void hotkey_base::save(config& item) const
save_helper(item);
}

hotkey_ptr create_hotkey(const std::string& id, SDL_Scancode new_val)
{
hotkey_ptr base = hotkey_ptr(new hotkey_void);

hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
base = std::dynamic_pointer_cast<hotkey_base>(keyboard);

keyboard->set_scancode(new_val);

base->set_mods(sdl_get_mods());
base->set_command(id);
base->unset_default();

return base;
}

hotkey_ptr create_hotkey(const std::string& id, Uint8 new_val)
hotkey_ptr create_hotkey(const std::string &id, SDL_Event &event)
{
hotkey_ptr base = hotkey_ptr(new hotkey_void);

hotkey_mouse_ptr mouse(new hotkey_mouse());
base = std::dynamic_pointer_cast<hotkey_base>(mouse);

mouse->set_button(new_val);
switch (event.type) {
case SDL_KEYDOWN:
case SDL_KEYUP: {
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
base = std::dynamic_pointer_cast<hotkey_base>(keyboard);
SDL_Keycode code;
code = event.key.keysym.sym;
keyboard->set_keycode(code);
break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: {
hotkey_mouse_ptr mouse(new hotkey_mouse());
base = std::dynamic_pointer_cast<hotkey_base>(mouse);
mouse->set_button(event.button.button);
break;
}
default:
ERR_G<< "Trying to bind an unknown event type:" << event.type << "\n";
break;
}

base->set_mods(sdl_get_mods());
base->set_command(id);
Expand Down Expand Up @@ -220,11 +215,12 @@ hotkey_ptr load_from_config(const config& cfg)
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
base = std::dynamic_pointer_cast<hotkey_base>(keyboard);

SDL_Scancode scancode = SDL_GetScancodeFromName(key_cfg.c_str());
if (scancode == SDL_SCANCODE_UNKNOWN) {
SDL_Keycode keycode = SDL_GetKeyFromName(key_cfg.c_str());
if (keycode == SDLK_UNKNOWN) {
ERR_G<< "Unknown key: " << key_cfg << "\n";
}
keyboard->set_scancode(scancode);
keyboard->set_text(key_cfg);
keyboard->set_keycode(keycode);
}

if (base == hotkey_ptr()) {
Expand Down Expand Up @@ -256,6 +252,11 @@ bool hotkey_mouse::matches_helper(const SDL_Event &event) const
return false;
}

unsigned int mods = sdl_get_mods();
if ((mods != mod_)) {
return false;
}

if (event.button.button != button_) {
return false;
}
Expand All @@ -278,7 +279,7 @@ void hotkey_mouse::save_helper(config &item) const

const std::string hotkey_keyboard::get_name_helper() const
{
std::string ret = std::string(SDL_GetKeyName(SDL_GetKeyFromScancode(scancode_)));
std::string ret = text_;

if (ret.size() == 1) {
boost::algorithm::to_lower(ret);
Expand All @@ -289,18 +290,21 @@ const std::string hotkey_keyboard::get_name_helper() const

bool hotkey_keyboard::matches_helper(const SDL_Event &event) const
{
if (event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) {
return false;
}

SDL_Scancode code;
code = event.key.keysym.scancode;
unsigned int mods = sdl_get_mods();

if (code != scancode_) {
if (event.type == SDL_TEXTINPUT && text_.length() == 1) {
std::string text = std::string(event.text.text);
boost::algorithm::to_lower(text);
if (text == ":") {
mods = mods & ~KMOD_SHIFT;
}
return text_ == text && mods == mod_;
} else if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) &&
(text_.length() > 1 || mods & (KMOD_CTRL|KMOD_ALT|KMOD_GUI)) ) {
return event.key.keysym.sym == keycode_ && mods == mod_;
} else {
return false;
}

return true;
}

bool hotkey_mouse::bindings_equal_helper(hotkey_ptr other) const
Expand All @@ -316,8 +320,8 @@ bool hotkey_mouse::bindings_equal_helper(hotkey_ptr other) const

void hotkey_keyboard::save_helper(config &item) const
{
if (scancode_ != SDL_SCANCODE_UNKNOWN) {
item["key"] = SDL_GetScancodeName(scancode_);
if (keycode_ != SDLK_UNKNOWN) {
item["key"] = SDL_GetKeyName(keycode_);
}
}

Expand All @@ -340,7 +344,7 @@ bool hotkey_keyboard::bindings_equal_helper(hotkey_ptr other) const
return false;
}

return scancode_ == other_k->scancode_;
return keycode_ == other_k->keycode_;
}

void del_hotkey(hotkey_ptr item)
Expand Down Expand Up @@ -445,7 +449,7 @@ void save_hotkeys(config& cfg)
}
}

std::string get_names(const std::string& id)
std::string get_names(std::string id)
{
// Names are used in places like the hot-key preferences menu
std::vector<std::string> names;
Expand Down
20 changes: 13 additions & 7 deletions src/hotkey/hotkey_item.hpp
Expand Up @@ -241,16 +241,21 @@ class hotkey_keyboard: public hotkey_base
/**
* Initialise new instance of this class that has no key associated with is.
*/
hotkey_keyboard() : hotkey_base(), scancode_(SDL_SCANCODE_UNKNOWN)
hotkey_keyboard() : hotkey_base(), keycode_(SDLK_UNKNOWN), text_("")
{}

/**
* Set the scancode associated with this class.
* @param scancode The SDL_Scancode that this hotkey should be associated with
* Set the keycode associated with this class.
* @param keycode_ The SDL_Keycode that this hotkey should be associated with
*/
void set_scancode(SDL_Scancode scancode)
void set_keycode(SDL_Keycode keycode)
{
scancode_ = scancode;
keycode_ = keycode;
}

void set_text(std::string text)
{
text_ = text;
}

/**
Expand All @@ -259,11 +264,12 @@ class hotkey_keyboard: public hotkey_base
*/
virtual bool valid() const
{
return scancode_ != SDL_SCANCODE_UNKNOWN;
return keycode_ != SDLK_UNKNOWN && text_ != "";
}

protected:
SDL_Scancode scancode_;
SDL_Keycode keycode_;
std::string text_;

virtual void save_helper(config& cfg) const;
virtual const std::string get_name_helper() const;
Expand Down
2 changes: 2 additions & 0 deletions src/wesnoth.cpp
Expand Up @@ -1015,6 +1015,8 @@ int main(int argc, char** argv)
//declare this here so that it will always be at the front of the event queue.
events::event_context global_context;

SDL_StartTextInput();

try {
std::cerr << "Battle for Wesnoth v" << game_config::revision << '\n';
const time_t t = time(nullptr);
Expand Down

0 comments on commit 5385898

Please sign in to comment.