Skip to content

Commit

Permalink
Implement hotkey release handling.
Browse files Browse the repository at this point in the history
Hotkeys are now triggered by a key/button release as well as a press.
This information is passed along as HOTKEY_EVENT_TYPE, which may be
HOTKEY_EVENT_PRESS, HOTKEY_EVENT_RELEASE, or HOTKEY_EVENT_REPEAT (for a
held key repeat).

Currently this should preserve the previous functionality. Existing
hotkeys respond to a press or repeat as they did before and ignore a
release.
  • Loading branch information
rcorre committed Apr 6, 2016
1 parent a33414a commit fa75608
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 11 deletions.
5 changes: 3 additions & 2 deletions src/controller_base.cpp
Expand Up @@ -61,13 +61,14 @@ void controller_base::handle_event(const SDL_Event& event)

process_keydown_event(event);
hotkey::key_event(event, get_hotkey_command_executor());
process_keyup_event(event);
} else {
process_focus_keydown_event(event);
break;
}
// intentionally fall-through
break;
case SDL_KEYUP:
process_keyup_event(event);
hotkey::key_event(event, get_hotkey_command_executor());
break;
case SDL_JOYBUTTONDOWN:
process_keydown_event(event);
Expand Down
24 changes: 20 additions & 4 deletions src/hotkey/command_executor.cpp
Expand Up @@ -72,8 +72,11 @@ namespace hotkey {

static void event_execute(const SDL_Event& event, command_executor* executor);

bool command_executor::execute_command(const hotkey_command& cmd, int /*index*/)
bool command_executor::execute_command(const hotkey_command& cmd, int /*index*/, HOTKEY_EVENT_TYPE type)
{
if (type == HOTKEY_EVENT_RELEASE)
return false; // nothing responds to a release yet

switch(cmd.id) {
case HOTKEY_CYCLE_UNITS:
cycle_units();
Expand Down Expand Up @@ -460,6 +463,7 @@ void basic_handler::handle_event(const SDL_Event& event)

switch (event.type) {
case SDL_KEYDOWN:
case SDL_KEYUP:
// If we're in a dialog we only want to handle items that are explicitly
// handled by the executor.
// If we're not in a dialog we can call the regular key event handler.
Expand All @@ -470,13 +474,15 @@ void basic_handler::handle_event(const SDL_Event& event)
}
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
if (!gui::in_dialog()) {
jbutton_event(event,exec_);
} else if (exec_ != nullptr) {
event_execute(event,exec_);
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if (!gui::in_dialog()) {
mbutton_event(event,exec_);
} else if (exec_ != nullptr) {
Expand Down Expand Up @@ -515,18 +521,28 @@ static void event_execute( const SDL_Event& event, command_executor* executor)
return;
}

execute_command(hotkey::get_hotkey_command(hk->get_command()), executor);
HOTKEY_EVENT_TYPE type = HOTKEY_EVENT_PRESS;
if (event.type == SDL_KEYUP || event.type == SDL_JOYBUTTONUP || event.type == SDL_MOUSEBUTTONUP)
type = HOTKEY_EVENT_RELEASE;
else if (event.type == SDL_KEYDOWN && event.key.repeat > 0)
type = HOTKEY_EVENT_REPEAT;

execute_command(hotkey::get_hotkey_command(hk->get_command()), executor, -1, type);
executor->set_button_state();
}

void execute_command(const hotkey_command& command, command_executor* executor, int index)
void execute_command(const hotkey_command& command, command_executor* executor, int index, HOTKEY_EVENT_TYPE type)
{
if (executor != nullptr) {
if (!executor->can_execute_command(command, index)
|| executor->execute_command(command, index)) {
|| executor->execute_command(command, index, type)) {
return;
}
}

if (type == HOTKEY_EVENT_RELEASE)
return; // none of the commands here respond to a key release

switch (command.id) {

case HOTKEY_MINIMAP_DRAW_TERRAIN:
Expand Down
4 changes: 2 additions & 2 deletions src/hotkey/command_executor.hpp
Expand Up @@ -132,7 +132,7 @@ class command_executor
void execute_action(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui);

virtual bool can_execute_command(const hotkey_command& command, int index=-1) const = 0;
virtual bool execute_command(const hotkey_command& command, int index=-1);
virtual bool execute_command(const hotkey_command& command, int index=-1, HOTKEY_EVENT_TYPE type = HOTKEY_EVENT_PRESS);
};
class command_executor_default : public command_executor
{
Expand Down Expand Up @@ -162,7 +162,7 @@ void mbutton_event(const SDL_Event& event, command_executor* executor);


//TODO
void execute_command(const hotkey_command& command, command_executor* executor, int index=-1);
void execute_command(const hotkey_command& command, command_executor* executor, int index=-1, HOTKEY_EVENT_TYPE type = HOTKEY_EVENT_PRESS);

// Object which will ensure that basic keyboard events like escape
// are handled properly for the duration of its lifetime.
Expand Down
2 changes: 2 additions & 0 deletions src/hotkey/hotkey_command.hpp
Expand Up @@ -35,6 +35,8 @@ enum scope {
SCOPE_COUNT,
};

enum HOTKEY_EVENT_TYPE { HOTKEY_EVENT_PRESS, HOTKEY_EVENT_RELEASE, HOTKEY_EVENT_REPEAT };

enum HOTKEY_COMMAND {
HOTKEY_CYCLE_UNITS, HOTKEY_CYCLE_BACK_UNITS,
HOTKEY_UNIT_HOLD_POSITION,
Expand Down
4 changes: 2 additions & 2 deletions src/hotkey/hotkey_handler.cpp
Expand Up @@ -218,7 +218,7 @@ void play_controller::hotkey_handler::toggle_accelerated_speed()
}
}

bool play_controller::hotkey_handler::execute_command(const hotkey::hotkey_command& cmd, int index)
bool play_controller::hotkey_handler::execute_command(const hotkey::hotkey_command& cmd, int index, hotkey::HOTKEY_EVENT_TYPE type)
{
hotkey::HOTKEY_COMMAND command = cmd.id;
if(index >= 0) {
Expand All @@ -245,7 +245,7 @@ bool play_controller::hotkey_handler::execute_command(const hotkey::hotkey_comma
gamestate().get_wml_menu_items().fire_item(name, hex, gamestate().gamedata_, gamestate(), gamestate().board_.units_);
/// @todo Shouldn't the function return at this point?
}
return command_executor::execute_command(cmd, index);
return command_executor::execute_command(cmd, index, type);
}

bool play_controller::hotkey_handler::can_execute_command(const hotkey::hotkey_command& cmd, int index) const
Expand Down
2 changes: 1 addition & 1 deletion src/hotkey/hotkey_handler.hpp
Expand Up @@ -125,7 +125,7 @@ class play_controller::hotkey_handler : public hotkey::command_executor_default
virtual hotkey::ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND command, int index) const;
/** Check if a command can be executed. */
virtual bool can_execute_command(const hotkey::hotkey_command& command, int index=-1) const;
virtual bool execute_command(const hotkey::hotkey_command& command, int index=-1);
virtual bool execute_command(const hotkey::hotkey_command& command, int index=-1, hotkey::HOTKEY_EVENT_TYPE type = hotkey::HOTKEY_EVENT_PRESS);
void show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& disp);

/**
Expand Down

0 comments on commit fa75608

Please sign in to comment.