Merge pull request #631 from rcorre/wasd_scrolling

Add preference for WASD scrolling.
This commit is contained in:
Celtic Minstrel 2016-04-11 01:16:58 -04:00
commit cdf6f4a6f8
14 changed files with 223 additions and 38 deletions

View file

@ -279,6 +279,8 @@ Version 1.13.4+dev:
* Miscellaneous and bug fixes:
* Resolve translated logo images not being used (bug #24357)
* Ported the "hexometer" tool from Bash to Python 3
* Recognize hotkey release events
* Allow changing keybindings for scrolling the map.
Version 1.13.4:
* Language and i18n:

View file

@ -1357,6 +1357,10 @@
[entry]
name = "Ryan Henszey"
[/entry]
[entry]
name = "Ryan Roden-Corrent (rcorre)"
comment = "Hotkey release and scroll key rebinding"
[/entry]
[entry]
name = "Sachith Seneviratne (sachith500)"
email = "sachith500@gmail.com"

View file

@ -13,6 +13,23 @@
#endif
#enddef
[hotkey]
command=scroll-up
key=UP
[/hotkey]
[hotkey]
command=scroll-down
key=DOWN
[/hotkey]
[hotkey]
command=scroll-left
key=LEFT
[/hotkey]
[hotkey]
command=scroll-right
key=RIGHT
[/hotkey]
[hotkey]
button=1
command="selectmoveaction"

View file

@ -5,6 +5,8 @@ changelog: https://github.com/wesnoth/wesnoth/blob/master/changelog
Version 1.13.4+dev:
* Language and i18n:
* Updated translations:
* Miscellaneous and bug fixes:
* Allow changing keybindings for scrolling the map.
Version 1.13.4:
* Language and i18n:

View file

@ -34,6 +34,10 @@ controller_base::controller_base(
: game_config_(game_config)
, key_()
, scrolling_(false)
, scroll_up_(false)
, scroll_down_(false)
, scroll_left_(false)
, scroll_right_(false)
, joystick_manager_()
{
}
@ -61,13 +65,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);
@ -128,11 +133,10 @@ void controller_base::process_keyup_event(const SDL_Event& /*event*/) {
//no action by default
}
bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double x_axis, double y_axis)
bool controller_base::handle_scroll(int mousex, int mousey, int mouse_flags, double x_axis, double y_axis)
{
bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0
|| preferences::get("scroll_when_mouse_outside", true);
bool keyboard_focus = have_keyboard_focus();
int scroll_speed = preferences::scroll_speed();
int dx = 0, dy = 0;
int scroll_threshold = (preferences::mouse_scroll_enabled())
@ -142,26 +146,30 @@ bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse
scroll_threshold = 0;
}
}
if ((key[SDLK_UP] && keyboard_focus) ||
(mousey < scroll_threshold && mouse_in_window))
{
dy -= scroll_speed;
}
if ((key[SDLK_DOWN] && keyboard_focus) ||
(mousey > get_display().h() - scroll_threshold && mouse_in_window))
{
dy += scroll_speed;
}
if ((key[SDLK_LEFT] && keyboard_focus) ||
(mousex < scroll_threshold && mouse_in_window))
{
dx -= scroll_speed;
}
if ((key[SDLK_RIGHT] && keyboard_focus) ||
(mousex > get_display().w() - scroll_threshold && mouse_in_window))
{
dx += scroll_speed;
// apply keyboard scrolling
dy -= scroll_up_ * scroll_speed;
dy += scroll_down_ * scroll_speed;
dx -= scroll_left_ * scroll_speed;
dx += scroll_right_ * scroll_speed;
// scroll if mouse is placed near the edge of the screen
if (mouse_in_window) {
if (mousey < scroll_threshold) {
dy -= scroll_speed;
}
if (mousey > get_display().h() - scroll_threshold) {
dy += scroll_speed;
}
if (mousex < scroll_threshold) {
dx -= scroll_speed;
}
if (mousex > get_display().w() - scroll_threshold) {
dx += scroll_speed;
}
}
// scroll with middle-mouse if enabled
if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) {
const map_location original_loc = get_mouse_handler_base().get_scroll_start();
@ -185,6 +193,7 @@ bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse
}
}
// scroll with joystick
dx += round_double( x_axis * scroll_speed);
dy += round_double( y_axis * scroll_speed);
@ -238,7 +247,7 @@ void controller_base::play_slice(bool is_delay_enabled)
mousey += values.second * 10;
SDL_WarpMouse(mousex, mousey);
*/
scrolling_ = handle_scroll(key, mousex, mousey, mouse_flags, joystickx, joysticky);
scrolling_ = handle_scroll(mousex, mousey, mouse_flags, joystickx, joysticky);
map_location highlighted_hex = get_display().mouseover_hex();
@ -341,3 +350,23 @@ const config& controller_base::get_theme(const config& game_config, std::string
static config empty;
return empty;
}
void controller_base::set_scroll_up(bool on)
{
scroll_up_ = on;
}
void controller_base::set_scroll_down(bool on)
{
scroll_down_ = on;
}
void controller_base::set_scroll_left(bool on)
{
scroll_left_ = on;
}
void controller_base::set_scroll_right(bool on)
{
scroll_right_ = on;
}

View file

@ -64,6 +64,12 @@ public:
void play_slice(bool is_delay_enabled = true);
static const config &get_theme(const config& game_config, std::string theme_name);
void apply_keyboard_scroll(int x, int y);
void set_scroll_up(bool on);
void set_scroll_down(bool on);
void set_scroll_left(bool on);
void set_scroll_right(bool on);
protected:
virtual bool is_browsing() const
{ return false; }
@ -102,10 +108,10 @@ protected:
/**
* Handle scrolling by keyboard, joystick and moving mouse near map edges
* @see is_keyboard_scroll_active
* @see scrolling_, which is set if the display is being scrolled
* @return true when there was any scrolling, false otherwise
*/
bool handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double joystickx, double joysticky);
bool handle_scroll(int mousex, int mousey, int mouse_flags, double joystickx, double joysticky);
/**
* Process mouse- and keypress-events from SDL.
@ -141,6 +147,10 @@ protected:
const config& game_config_;
CKey key_;
bool scrolling_;
bool scroll_up_;
bool scroll_down_;
bool scroll_left_;
bool scroll_right_;
joystick_manager joystick_manager_;
};

View file

@ -286,6 +286,10 @@ bool editor_controller::can_execute_command(const hotkey::hotkey_command& cmd, i
case HOTKEY_PREFERENCES:
case HOTKEY_HELP:
case HOTKEY_QUIT_GAME:
case HOTKEY_SCROLL_UP:
case HOTKEY_SCROLL_DOWN:
case HOTKEY_SCROLL_LEFT:
case HOTKEY_SCROLL_RIGHT:
return true; //general hotkeys we can always do
case hotkey::HOTKEY_UNIT_LIST:
@ -584,12 +588,18 @@ hotkey::ACTION_STATE editor_controller::get_action_state(hotkey::HOTKEY_COMMAND
}
}
bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int index)
bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int index, bool press)
{
const int zoom_amount = 4;
hotkey::HOTKEY_COMMAND command = cmd.id;
SCOPE_ED;
using namespace hotkey;
// nothing here handles release; fall through to base implementation
if (!press) {
return hotkey::command_executor::execute_command(cmd, index, press);
}
switch (command) {
case HOTKEY_NULL:
switch (active_menu_) {
@ -972,7 +982,7 @@ bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int i
gui().invalidate_all();
return true;
default:
return hotkey::command_executor::execute_command(cmd, index);
return hotkey::command_executor::execute_command(cmd, index, press);
}
}
@ -1356,4 +1366,24 @@ hotkey::command_executor * editor_controller::get_hotkey_command_executor() {
return this;
}
void editor_controller::scroll_up(bool on)
{
controller_base::set_scroll_up(on);
}
void editor_controller::scroll_down(bool on)
{
controller_base::set_scroll_down(on);
}
void editor_controller::scroll_left(bool on)
{
controller_base::set_scroll_left(on);
}
void editor_controller::scroll_right(bool on)
{
controller_base::set_scroll_right(on);
}
} //end namespace editor

View file

@ -107,7 +107,7 @@ class editor_controller : public controller_base,
hotkey::ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND command, int index) const;
/** command_executor override */
bool execute_command(const hotkey::hotkey_command& command, int index = -1);
bool execute_command(const hotkey::hotkey_command& command, int index = -1, bool press=true);
/** controller_base override */
void show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& disp);
@ -118,6 +118,12 @@ class editor_controller : public controller_base,
/** Show the preferences dialog */
void preferences();
/** Handle hotkeys to scroll map */
void scroll_up(bool on);
void scroll_down(bool on);
void scroll_left(bool on);
void scroll_right(bool on);
/** Grid toggle */
void toggle_grid();

View file

@ -72,9 +72,45 @@ 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*/, bool press)
{
// hotkey release handling
if (!press) {
switch(cmd.id) {
// release a scroll key, un-apply scrolling in the given direction
case HOTKEY_SCROLL_UP:
scroll_up(false);
break;
case HOTKEY_SCROLL_DOWN:
scroll_down(false);
break;
case HOTKEY_SCROLL_LEFT:
scroll_left(false);
break;
case HOTKEY_SCROLL_RIGHT:
scroll_right(false);
break;
default:
return false; // nothing else handles a hotkey release
}
return true;
}
// hotkey press handling
switch(cmd.id) {
case HOTKEY_SCROLL_UP:
scroll_up(true);
break;
case HOTKEY_SCROLL_DOWN:
scroll_down(true);
break;
case HOTKEY_SCROLL_LEFT:
scroll_left(true);
break;
case HOTKEY_SCROLL_RIGHT:
scroll_right(true);
break;
case HOTKEY_CYCLE_UNITS:
cycle_units();
break;
@ -460,6 +496,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.
@ -470,6 +507,7 @@ 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) {
@ -477,6 +515,7 @@ void basic_handler::handle_event(const SDL_Event& event)
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if (!gui::in_dialog()) {
mbutton_event(event,exec_);
} else if (exec_ != nullptr) {
@ -515,18 +554,25 @@ static void event_execute( const SDL_Event& event, command_executor* executor)
return;
}
execute_command(hotkey::get_hotkey_command(hk->get_command()), executor);
bool press = event.type == SDL_KEYDOWN || event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN;
execute_command(hotkey::get_hotkey_command(hk->get_command()), executor, -1, press);
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, bool press)
{
if (executor != nullptr) {
if (!executor->can_execute_command(command, index)
|| executor->execute_command(command, index)) {
|| executor->execute_command(command, index, press)) {
return;
}
}
if (!press) {
return; // none of the commands here respond to a key release
}
switch (command.id) {
case HOTKEY_MINIMAP_DRAW_TERRAIN:

View file

@ -108,6 +108,10 @@ public:
virtual void left_mouse_click() {}
virtual void right_mouse_click() {}
virtual void toggle_accelerated_speed() {}
virtual void scroll_up(bool /*on*/) {}
virtual void scroll_down(bool /*on*/) {}
virtual void scroll_left(bool /*on*/) {}
virtual void scroll_right(bool /*on*/) {}
virtual void lua_console();
virtual void zoom_in() {}
virtual void zoom_out() {}
@ -132,7 +136,7 @@ public:
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, bool press=true);
};
class command_executor_default : public command_executor
{
@ -162,7 +166,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, bool press=true);
// Object which will ensure that basic keyboard events like escape
// are handled properly for the duration of its lifetime.

View file

@ -35,6 +35,10 @@ namespace {
hotkey::hk_scopes scope_main(1 << hotkey::SCOPE_MAIN_MENU);
// this contains all static hotkeys
hotkey::hotkey_command_temp hotkey_list_[] = {
{ hotkey::HOTKEY_SCROLL_UP, "scroll-up", N_("Scroll Up"), false, scope_game | scope_editor, "" },
{ hotkey::HOTKEY_SCROLL_DOWN, "scroll-down", N_("Scroll Down"), false, scope_game | scope_editor, "" },
{ hotkey::HOTKEY_SCROLL_LEFT, "scroll-left", N_("Scroll Left"), false, scope_game | scope_editor, "" },
{ hotkey::HOTKEY_SCROLL_RIGHT, "scroll-right", N_("Scroll Right"), false, scope_game | scope_editor, "" },
{ hotkey::HOTKEY_CANCEL, N_("cancel"), N_("Cancel"), false, scope_game | scope_editor | scope_main, "" },
{ hotkey::HOTKEY_SELECT_HEX, "selecthex", N_("Select Hex"), false, scope_game, "" },

View file

@ -65,6 +65,9 @@ enum HOTKEY_COMMAND {
HOTKEY_SELECT_HEX, HOTKEY_DESELECT_HEX,
HOTKEY_MOVE_ACTION, HOTKEY_SELECT_AND_ACTION,
// Camera movement
HOTKEY_SCROLL_UP, HOTKEY_SCROLL_DOWN, HOTKEY_SCROLL_LEFT, HOTKEY_SCROLL_RIGHT,
// Dialog control
HOTKEY_CANCEL, HOTKEY_OKAY,

View file

@ -218,7 +218,27 @@ void play_controller::hotkey_handler::toggle_accelerated_speed()
}
}
bool play_controller::hotkey_handler::execute_command(const hotkey::hotkey_command& cmd, int index)
void play_controller::hotkey_handler::scroll_up(bool on)
{
play_controller_.set_scroll_up(on);
}
void play_controller::hotkey_handler::scroll_down(bool on)
{
play_controller_.set_scroll_down(on);
}
void play_controller::hotkey_handler::scroll_left(bool on)
{
play_controller_.set_scroll_left(on);
}
void play_controller::hotkey_handler::scroll_right(bool on)
{
play_controller_.set_scroll_right(on);
}
bool play_controller::hotkey_handler::execute_command(const hotkey::hotkey_command& cmd, int index, bool press)
{
hotkey::HOTKEY_COMMAND command = cmd.id;
if(index >= 0) {
@ -245,7 +265,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, press);
}
bool play_controller::hotkey_handler::can_execute_command(const hotkey::hotkey_command& cmd, int index) const
@ -302,6 +322,10 @@ bool play_controller::hotkey_handler::can_execute_command(const hotkey::hotkey_c
case hotkey::HOTKEY_SAVE_REPLAY:
case hotkey::HOTKEY_LABEL_SETTINGS:
case hotkey::LUA_CONSOLE:
case hotkey::HOTKEY_SCROLL_UP:
case hotkey::HOTKEY_SCROLL_DOWN:
case hotkey::HOTKEY_SCROLL_LEFT:
case hotkey::HOTKEY_SCROLL_RIGHT:
return true;
// Commands that have some preconditions:

View file

@ -117,6 +117,10 @@ public:
virtual void toggle_grid();
virtual void search();
virtual void toggle_accelerated_speed();
virtual void scroll_up(bool on);
virtual void scroll_down(bool on);
virtual void scroll_left(bool on);
virtual void scroll_right(bool on);
virtual void replay_skip_animation() override
{ return play_controller_.toggle_skipping_replay(); }
@ -125,7 +129,7 @@ public:
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, bool press=true);
void show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& disp);
/**