Merge pull request #1003 from wesnoth/composed_hotkeys
Composed hotkeys
This commit is contained in:
commit
af1326d19b
15 changed files with 308 additions and 111 deletions
|
@ -83,7 +83,7 @@
|
|||
[/hotkey]
|
||||
[hotkey]
|
||||
command=command
|
||||
key=;
|
||||
key=:
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=continue
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -96,7 +96,10 @@ bool dispatcher::has_event(const ui_event event, const event_queue_type event_ty
|
|||
*this))
|
||||
|| find<set_event_message>(event,
|
||||
dispatcher_implementation::has_handler(
|
||||
event_type, *this));
|
||||
event_type, *this))
|
||||
|| find<set_event_raw_event>(event,
|
||||
dispatcher_implementation::has_handler(
|
||||
event_type, *this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,6 +253,39 @@ bool dispatcher::fire(const ui_event event,
|
|||
trigger_keyboard(key, modifier, unicode));
|
||||
}
|
||||
|
||||
/** Helper struct to wrap the functor call. */
|
||||
class trigger_raw_event
|
||||
{
|
||||
public:
|
||||
trigger_raw_event(const SDL_Event& sdlevent) : sdl_event_(sdlevent)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(signal_raw_event_function functor,
|
||||
dispatcher& dispatcher,
|
||||
const ui_event event,
|
||||
bool& handled,
|
||||
bool& halt)
|
||||
{
|
||||
functor(dispatcher, event, handled, halt, sdl_event_);
|
||||
}
|
||||
|
||||
private:
|
||||
const SDL_Event& sdl_event_;
|
||||
};
|
||||
|
||||
bool dispatcher::fire(const ui_event event,
|
||||
widget& target,
|
||||
const SDL_Event& sdlevent)
|
||||
{
|
||||
assert(find<set_event_raw_event>(event, event_in_set()));
|
||||
return fire_event<signal_raw_event_function>(
|
||||
event,
|
||||
dynamic_cast<widget*>(this),
|
||||
&target,
|
||||
trigger_raw_event(sdlevent));
|
||||
}
|
||||
|
||||
/** Helper struct to wrap the functor call. */
|
||||
class trigger_touch
|
||||
{
|
||||
|
|
|
@ -49,9 +49,9 @@ struct message;
|
|||
*
|
||||
* This function is used for the callbacks in set_event.
|
||||
*/
|
||||
typedef std::function<void(
|
||||
dispatcher& dispatcher, const ui_event event, bool& handled, bool& halt)>
|
||||
signal_function;
|
||||
typedef std::function<void(dispatcher& dispatcher,
|
||||
const ui_event event,
|
||||
bool& handled, bool& halt)> signal_function;
|
||||
|
||||
/**
|
||||
* Callback function signature.
|
||||
|
@ -75,8 +75,7 @@ typedef std::function<void(dispatcher& dispatcher,
|
|||
bool& halt,
|
||||
const SDL_Keycode key,
|
||||
const SDL_Keymod modifier,
|
||||
const utf8::string& unicode)>
|
||||
signal_keyboard_function;
|
||||
const utf8::string& unicode)> signal_keyboard_function;
|
||||
|
||||
/**
|
||||
* Callback function signature.
|
||||
|
@ -88,8 +87,7 @@ typedef std::function<void(dispatcher& dispatcher,
|
|||
bool& handled,
|
||||
bool& halt,
|
||||
const point& pos,
|
||||
const point& distance)>
|
||||
signal_touch_function;
|
||||
const point& distance)> signal_touch_function;
|
||||
|
||||
/**
|
||||
* Callback function signature.
|
||||
|
@ -115,6 +113,17 @@ typedef std::function<void(dispatcher& dispatcher,
|
|||
bool& halt,
|
||||
message& message)> signal_message_function;
|
||||
|
||||
/**
|
||||
* Callback function signature.
|
||||
*
|
||||
* This function is used for the callbacks in set_event_message.
|
||||
*/
|
||||
typedef std::function<void(dispatcher& dispatcher,
|
||||
const ui_event event,
|
||||
bool& handled,
|
||||
bool& halt,
|
||||
const SDL_Event& sdlevent)> signal_raw_event_function;
|
||||
|
||||
/** Hotkey function handler signature. */
|
||||
typedef std::function<bool(dispatcher& dispatcher,
|
||||
hotkey::HOTKEY_COMMAND id)> thotkey_function;
|
||||
|
@ -185,7 +194,9 @@ public:
|
|||
* @param target The widget that should receive the event.
|
||||
* @param coordinate The mouse position for the event.
|
||||
*/
|
||||
bool fire(const ui_event event, widget& target, const point& coordinate);
|
||||
bool fire(const ui_event event,
|
||||
widget& target,
|
||||
const point& coordinate);
|
||||
|
||||
/**
|
||||
* Fires an event which takes keyboard parameters.
|
||||
|
@ -223,7 +234,9 @@ public:
|
|||
* @param event The event to fire.
|
||||
* @param target The widget that should receive the event.
|
||||
*/
|
||||
bool fire(const ui_event event, widget& target, void*);
|
||||
bool fire(const ui_event event,
|
||||
widget& target,
|
||||
void*);
|
||||
|
||||
/**
|
||||
* Fires an event which takes message parameters.
|
||||
|
@ -236,7 +249,21 @@ public:
|
|||
* (or another widget in the chain) to handle
|
||||
* the message.
|
||||
*/
|
||||
bool fire(const ui_event event, widget& target, message& msg);
|
||||
bool fire(const ui_event event,
|
||||
widget& target,
|
||||
message& msg);
|
||||
|
||||
/**
|
||||
* Fires an event that's a raw SDL event
|
||||
* @param event The event to fire.
|
||||
* @param target The widget that should receive the event.
|
||||
* Normally this is the window holding the
|
||||
* widget.
|
||||
* @param sdlevent The raw SDL event
|
||||
*/
|
||||
bool fire(const ui_event event,
|
||||
widget& target,
|
||||
const SDL_Event& sdlevent);
|
||||
|
||||
/**
|
||||
* The position where to add a new callback in the signal handler.
|
||||
|
@ -507,6 +534,39 @@ public:
|
|||
signal_message_queue_.disconnect_signal(E, position, signal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect a signal for callback in set_raw_event.
|
||||
*
|
||||
* @tparam E The event the callback needs to react to.
|
||||
* @param signal The callback function.
|
||||
* @param position The position to place the callback.
|
||||
*/
|
||||
template <ui_event E>
|
||||
typename std::enable_if<has_key<set_event_raw_event, E>::value>::type
|
||||
connect_signal(const signal_raw_event_function& signal,
|
||||
const queue_position position = back_child)
|
||||
{
|
||||
signal_raw_event_queue_.connect_signal(E, position, signal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a signal for callback in set_raw_event.
|
||||
*
|
||||
* @tparam E The event the callback was used for.
|
||||
* @param signal The callback function.
|
||||
* @param position The place where the function was added.
|
||||
* Needed remove the event from the right
|
||||
* place. (The function doesn't care whether
|
||||
* was added in front or back.)
|
||||
*/
|
||||
template <ui_event E>
|
||||
typename std::enable_if<has_key<set_event_raw_event, E>::value>::type
|
||||
disconnect_signal(const signal_raw_event_function& signal,
|
||||
const queue_position position = back_child)
|
||||
{
|
||||
signal_raw_event_queue_.disconnect_signal(E, position, signal);
|
||||
}
|
||||
|
||||
/**
|
||||
* The behavior of the mouse events.
|
||||
*
|
||||
|
@ -733,6 +793,9 @@ private:
|
|||
/** Signal queue for callbacks in set_event_message. */
|
||||
signal_queue<signal_message_function> signal_message_queue_;
|
||||
|
||||
/** Signal queue for callbacks in set_raw_event. */
|
||||
signal_queue<signal_raw_event_function> signal_raw_event_queue_;
|
||||
|
||||
/** Are we connected to the event handler. */
|
||||
bool connected_;
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ struct dispatcher_implementation
|
|||
IMPLEMENT_EVENT_SIGNAL_WRAPPER(touch)
|
||||
IMPLEMENT_EVENT_SIGNAL_WRAPPER(notification)
|
||||
IMPLEMENT_EVENT_SIGNAL_WRAPPER(message)
|
||||
IMPLEMENT_EVENT_SIGNAL_WRAPPER(raw_event)
|
||||
|
||||
#undef IMPLEMENT_EVENT_SIGNAL_WRAPPER
|
||||
#undef IMPLEMENT_EVENT_SIGNAL
|
||||
|
|
|
@ -164,6 +164,9 @@ private:
|
|||
|
||||
/***** Handlers *****/
|
||||
|
||||
/** Fires a raw SDL event. */
|
||||
void raw_event(const SDL_Event &event);
|
||||
|
||||
/** Fires a draw event. */
|
||||
using events::sdl_handler::draw;
|
||||
void draw(const bool force);
|
||||
|
@ -445,6 +448,8 @@ void sdl_event_handler::handle_event(const SDL_Event& event)
|
|||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
raw_event(event);
|
||||
}
|
||||
|
||||
void sdl_event_handler::handle_window_event(const SDL_Event& event)
|
||||
|
@ -559,6 +564,15 @@ void sdl_event_handler::video_resize(const point& new_size)
|
|||
}
|
||||
}
|
||||
|
||||
void sdl_event_handler::raw_event(const SDL_Event& event) {
|
||||
DBG_GUI_E << "Firing raw event\n";
|
||||
|
||||
for(auto dispatcher : dispatchers_)
|
||||
{
|
||||
dispatcher->fire(SDL_RAW_EVENT, dynamic_cast<widget&>(*dispatcher), event);
|
||||
}
|
||||
}
|
||||
|
||||
void sdl_event_handler::mouse(const ui_event event, const point& position)
|
||||
{
|
||||
DBG_GUI_E << "Firing: " << event << ".\n";
|
||||
|
@ -961,6 +975,9 @@ std::ostream& operator<<(std::ostream& stream, const ui_event event)
|
|||
case SDL_TOUCH_DOWN:
|
||||
stream << "SDL touch down";
|
||||
break;
|
||||
case SDL_RAW_EVENT:
|
||||
stream << "SDL raw event";
|
||||
break;
|
||||
}
|
||||
|
||||
return stream;
|
||||
|
|
|
@ -113,7 +113,9 @@ enum ui_event {
|
|||
|
||||
SDL_TOUCH_MOTION,
|
||||
SDL_TOUCH_UP,
|
||||
SDL_TOUCH_DOWN
|
||||
SDL_TOUCH_DOWN,
|
||||
|
||||
SDL_RAW_EVENT /**< Raw SDL event. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -213,6 +215,13 @@ typedef boost::mpl::set<boost::mpl::int_<MESSAGE_SHOW_TOOLTIP>,
|
|||
boost::mpl::int_<REQUEST_PLACEMENT> >
|
||||
set_event_message;
|
||||
|
||||
/**
|
||||
* Helper for catching use error of dispatcher::connect_signal.
|
||||
*
|
||||
* This version is for callbacks of raw events.
|
||||
*/
|
||||
typedef boost::mpl::set<boost::mpl::int_<SDL_RAW_EVENT> > set_event_raw_event;
|
||||
|
||||
/**
|
||||
* Connects a dispatcher to the event handler.
|
||||
*
|
||||
|
|
|
@ -36,37 +36,20 @@ hotkey_bind::hotkey_bind(const std::string& hotkey_id)
|
|||
|
||||
void hotkey_bind::pre_show(window& window)
|
||||
{
|
||||
connect_signal_pre_key_press(window, std::bind(&hotkey_bind::key_press_callback, this, std::ref(window), _5));
|
||||
window.connect_signal<event::SDL_RAW_EVENT>(
|
||||
std::bind(&hotkey_bind::sdl_event_callback, this, std::ref(window), _5),
|
||||
event::dispatcher::front_child);
|
||||
|
||||
window.connect_signal<event::SDL_LEFT_BUTTON_DOWN>(
|
||||
std::bind(&hotkey_bind::mouse_button_callback, this, std::ref(window), SDL_BUTTON_LEFT), event::dispatcher::front_child);
|
||||
window.connect_signal<event::SDL_MIDDLE_BUTTON_DOWN>(
|
||||
std::bind(&hotkey_bind::mouse_button_callback, this, std::ref(window), SDL_BUTTON_MIDDLE), event::dispatcher::front_child);
|
||||
window.connect_signal<event::SDL_RIGHT_BUTTON_DOWN>(
|
||||
std::bind(&hotkey_bind::mouse_button_callback, this, std::ref(window), SDL_BUTTON_RIGHT), event::dispatcher::front_child);
|
||||
}
|
||||
|
||||
void hotkey_bind::key_press_callback(window& window, const SDL_Keycode key)
|
||||
void hotkey_bind::sdl_event_callback(window& win, const SDL_Event &event)
|
||||
{
|
||||
/* HACK: SDL_KEYDOWN and SDL_TEXTINPUT events forward to the same GUI2 event (SDL_KEY_DOWN), meaning
|
||||
* this even gets fired twice, causing problems since 'key' will be 0 in the latter case. SDLK_UNKNOWN
|
||||
* is the key value used by SDL_TEXTINPUT handling, so exit here if that's detected.
|
||||
*/
|
||||
if(key == SDLK_UNKNOWN) {
|
||||
return;
|
||||
if (hotkey::is_hotkeyable_event(event)) {
|
||||
new_binding_ = hotkey::create_hotkey(hotkey_id_, event);
|
||||
win.set_retval(window::OK);
|
||||
}
|
||||
|
||||
new_binding_ = hotkey::create_hotkey(hotkey_id_, SDL_GetScancodeFromKey(key));
|
||||
|
||||
window.set_retval(window::OK);
|
||||
}
|
||||
|
||||
void hotkey_bind::mouse_button_callback(window& window, Uint8 button)
|
||||
{
|
||||
new_binding_ = hotkey::create_hotkey(hotkey_id_, button);
|
||||
|
||||
window.set_retval(window::OK);
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
} // namespace gui2
|
||||
|
|
|
@ -41,9 +41,7 @@ private:
|
|||
|
||||
hotkey::hotkey_ptr new_binding_;
|
||||
|
||||
void key_press_callback(window& window, const SDL_Keycode key);
|
||||
|
||||
void mouse_button_callback(window& window, Uint8 button);
|
||||
void sdl_event_callback(window& win, const SDL_Event &event);
|
||||
|
||||
/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
|
||||
virtual const std::string& window_id() const override;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -20,18 +20,12 @@
|
|||
|
||||
#define GETTEXT_DOMAIN "wesnoth-lib"
|
||||
|
||||
#include "gettext.hpp"
|
||||
#include "serialization/unicode.hpp"
|
||||
#include "sdl/surface.hpp"
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "utils/functional.hpp"
|
||||
|
||||
#include "key.hpp"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <key.hpp>
|
||||
|
||||
|
||||
static lg::log_domain log_config("config");
|
||||
|
@ -128,17 +122,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 +143,41 @@ 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, const SDL_Event &event)
|
||||
{
|
||||
hotkey_ptr base = hotkey_ptr(new hotkey_void);
|
||||
unsigned mods = sdl_get_mods();
|
||||
|
||||
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: {
|
||||
if (mods & KMOD_CTRL || mods & KMOD_ALT || mods & KMOD_GUI || CKey::is_uncomposable(event.key)) {
|
||||
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);
|
||||
keyboard->set_text(SDL_GetKeyName(event.key.keysym.sym));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_TEXTINPUT: {
|
||||
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
|
||||
base = std::dynamic_pointer_cast<hotkey_base>(keyboard);
|
||||
keyboard->set_text(std::string(event.text.text));
|
||||
}
|
||||
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 +219,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 +256,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,29 +283,29 @@ 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_)));
|
||||
|
||||
if (ret.size() == 1) {
|
||||
boost::algorithm::to_lower(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return text_;
|
||||
}
|
||||
|
||||
bool hotkey_keyboard::matches_helper(const SDL_Event &event) const
|
||||
{
|
||||
if (event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) {
|
||||
return false;
|
||||
unsigned int mods = sdl_get_mods();
|
||||
|
||||
if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) &&
|
||||
(mods & KMOD_CTRL || mods & KMOD_ALT || mods & KMOD_GUI ||
|
||||
CKey::is_uncomposable(event.key))) {
|
||||
return event.key.keysym.sym == keycode_ && mods == mod_;
|
||||
}
|
||||
|
||||
SDL_Scancode code;
|
||||
code = event.key.keysym.scancode;
|
||||
|
||||
if (code != scancode_) {
|
||||
return false;
|
||||
if (event.type == SDL_TEXTINPUT) {
|
||||
std::string text = std::string(event.text.text);
|
||||
boost::algorithm::to_lower(text);
|
||||
if (text == ":") {
|
||||
mods = mods & ~KMOD_SHIFT;
|
||||
}
|
||||
return text_ == text && mods == mod_;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hotkey_mouse::bindings_equal_helper(hotkey_ptr other) const
|
||||
|
@ -316,8 +321,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 +345,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)
|
||||
|
@ -470,4 +475,22 @@ std::string get_names(const std::string& id)
|
|||
return boost::algorithm::join(names, ", ");
|
||||
}
|
||||
|
||||
bool is_hotkeyable_event(const SDL_Event &event) {
|
||||
|
||||
if (event.type == SDL_JOYBUTTONUP ||
|
||||
event.type == SDL_JOYHATMOTION ||
|
||||
event.type == SDL_MOUSEBUTTONUP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned mods = sdl_get_mods();
|
||||
|
||||
if (mods & KMOD_CTRL || mods & KMOD_ALT || mods & KMOD_GUI) {
|
||||
return event.type == SDL_KEYUP;
|
||||
} else {
|
||||
return event.type == SDL_TEXTINPUT ||
|
||||
(event.type == SDL_KEYUP && CKey::is_uncomposable(event.key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
class config;
|
||||
class CVideo;
|
||||
|
@ -241,16 +242,22 @@ 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;
|
||||
boost::algorithm::to_lower(text_);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,11 +266,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;
|
||||
|
@ -371,11 +379,12 @@ void add_hotkey(const hotkey_ptr item);
|
|||
*/
|
||||
void del_hotkey(const hotkey_ptr item);
|
||||
|
||||
/** Create a new hotkey item bound to a keyboard key. */
|
||||
hotkey_ptr create_hotkey(const std::string& id, SDL_Scancode new_val);
|
||||
|
||||
/** Create a new hotkey item bound to a mouse button. */
|
||||
hotkey_ptr create_hotkey(const std::string& id, Uint8 new_val);
|
||||
/**
|
||||
* Create a new hotkey item for a command from an SDL_Event.
|
||||
* @param id The command to bind to.
|
||||
* @param event The SDL_Event to base the creation on.
|
||||
*/
|
||||
hotkey_ptr create_hotkey(const std::string &id, const SDL_Event &event);
|
||||
|
||||
/**
|
||||
* Iterate through the list of hotkeys and return a hotkey that matches
|
||||
|
@ -429,7 +438,7 @@ std::string get_names(const std::string& id);
|
|||
*/
|
||||
void save_hotkeys(config& cfg);
|
||||
|
||||
hotkey_ptr show_binding_dialog(CVideo& video, const std::string& id);
|
||||
bool is_hotkeyable_event(const SDL_Event &event);
|
||||
|
||||
}
|
||||
|
||||
|
|
50
src/key.cpp
50
src/key.cpp
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "key.hpp"
|
||||
|
||||
#include <SDL_keyboard.h>
|
||||
|
||||
CKey::CKey() :
|
||||
key_list(SDL_GetKeyboardState(nullptr))
|
||||
{
|
||||
|
@ -25,3 +23,51 @@ bool CKey::operator[](int k) const
|
|||
{
|
||||
return key_list[SDL_GetScancodeFromKey(k)] > 0;
|
||||
}
|
||||
|
||||
bool CKey::is_uncomposable(const SDL_KeyboardEvent &event) {
|
||||
|
||||
switch (event.keysym.sym) {
|
||||
case SDLK_RETURN:
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_BACKSPACE:
|
||||
case SDLK_TAB:
|
||||
case SDLK_F1:
|
||||
case SDLK_F2:
|
||||
case SDLK_F3:
|
||||
case SDLK_F4:
|
||||
case SDLK_F5:
|
||||
case SDLK_F6:
|
||||
case SDLK_F7:
|
||||
case SDLK_F8:
|
||||
case SDLK_F9:
|
||||
case SDLK_F10:
|
||||
case SDLK_F11:
|
||||
case SDLK_F12:
|
||||
case SDLK_F13:
|
||||
case SDLK_F14:
|
||||
case SDLK_F15:
|
||||
case SDLK_F16:
|
||||
case SDLK_F17:
|
||||
case SDLK_F18:
|
||||
case SDLK_F19:
|
||||
case SDLK_F20:
|
||||
case SDLK_F21:
|
||||
case SDLK_F22:
|
||||
case SDLK_F23:
|
||||
case SDLK_F24:
|
||||
case SDLK_INSERT:
|
||||
case SDLK_HOME:
|
||||
case SDLK_PAGEUP:
|
||||
case SDLK_PAGEDOWN:
|
||||
case SDLK_DELETE:
|
||||
case SDLK_END:
|
||||
case SDLK_UP:
|
||||
case SDLK_DOWN:
|
||||
case SDLK_LEFT:
|
||||
case SDLK_RIGHT:
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
#define KEY_HPP_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <SDL.h>
|
||||
|
||||
/**
|
||||
* Class that keeps track of all the keys on the keyboard.
|
||||
|
@ -31,6 +32,7 @@ class CKey
|
|||
public:
|
||||
CKey();
|
||||
bool operator[](int k) const;
|
||||
static bool is_uncomposable(const SDL_KeyboardEvent &event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue