Fix #24681: Use composed hotkeys where appropriate and revert help to 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).
This commit is contained in:
Andreas Löf 2017-03-10 23:46:19 +13:00
parent 0828c2bdf8
commit 92ca7fdb5e
6 changed files with 75 additions and 55 deletions

View file

@ -83,7 +83,7 @@
[/hotkey]
[hotkey]
command=command
key=;
key=:
[/hotkey]
[hotkey]
command=continue

View file

@ -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.

View file

@ -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();

View file

@ -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
@ -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);
}
@ -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 create_hotkey(const std::string &id, SDL_Event &event)
{
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 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);
@ -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()) {
@ -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;
}
@ -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);
@ -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) {
unsigned int mods = sdl_get_mods();
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;
}
SDL_Scancode code;
code = event.key.keysym.scancode;
if (code != scancode_) {
return false;
}
return true;
}
bool hotkey_mouse::bindings_equal_helper(hotkey_ptr other) const
@ -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_);
}
}
@ -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)
@ -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;

View file

@ -241,16 +241,21 @@ public:
/**
* 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;
}
/**
@ -259,11 +264,12 @@ public:
*/
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;

View file

@ -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);