Gracefully handle multiple scrolling hotkeys.

Track whether each scroll direction is enabled separately.
This avoids odd behavior when holding multiple hotkeys for the same
scroll direction.
For example, holding two hotkeys for right and releasing both will no
longer cause the map to begin scrolling left.
This commit is contained in:
Ryan Roden-Corrent 2016-03-30 21:57:31 -04:00
parent 355b8ce1b8
commit 94e390c067
8 changed files with 88 additions and 28 deletions

View file

@ -34,8 +34,10 @@ controller_base::controller_base(
: game_config_(game_config)
, key_()
, scrolling_(false)
, scrollx_(0)
, scrolly_(0)
, scroll_up_(false)
, scroll_down_(false)
, scroll_left_(false)
, scroll_right_(false)
, joystick_manager_()
{
}
@ -145,9 +147,11 @@ bool controller_base::handle_scroll(int mousex, int mousey, int mouse_flags, dou
}
}
// scroll with keyboard
dx += scrollx_ * scroll_speed;
dy += scrolly_ * 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) {
@ -347,11 +351,22 @@ const config& controller_base::get_theme(const config& game_config, std::string
return empty;
}
void controller_base::apply_keyboard_scroll(int x, int y)
void controller_base::set_scroll_up(bool on)
{
if (have_keyboard_focus()) {
// clamp between -1 and 1 so key repeats don't accelerate scrolling
scrollx_ = std::min(1, std::max(-1, scrollx_ + x));
scrolly_ = std::min(1, std::max(-1, scrolly_ + y));
}
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

@ -66,6 +66,10 @@ public:
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; }
@ -143,8 +147,10 @@ protected:
const config& game_config_;
CKey key_;
bool scrolling_;
int scrollx_;
int scrolly_;
bool scroll_up_;
bool scroll_down_;
bool scroll_left_;
bool scroll_right_;
joystick_manager joystick_manager_;
};

View file

@ -1366,9 +1366,24 @@ hotkey::command_executor * editor_controller::get_hotkey_command_executor() {
return this;
}
void editor_controller::keyboard_scroll(int x, int y)
void editor_controller::scroll_up(bool on)
{
controller_base::apply_keyboard_scroll(x, y);
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

@ -119,7 +119,10 @@ class editor_controller : public controller_base,
void preferences();
/** Handle hotkeys to scroll map */
void keyboard_scroll(int /*x*/, int /*y*/);
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

@ -79,16 +79,16 @@ bool command_executor::execute_command(const hotkey_command& cmd, int /*index*/
switch(cmd.id) {
// release a scroll key, un-apply scrolling in the given direction
case HOTKEY_SCROLL_UP:
keyboard_scroll(0, 1);
scroll_up(false);
break;
case HOTKEY_SCROLL_DOWN:
keyboard_scroll(0, -1);
scroll_down(false);
break;
case HOTKEY_SCROLL_LEFT:
keyboard_scroll(1, 0);
scroll_left(false);
break;
case HOTKEY_SCROLL_RIGHT:
keyboard_scroll(-1, 0);
scroll_right(false);
break;
default:
return false; // nothing else handles a hotkey release
@ -100,16 +100,16 @@ bool command_executor::execute_command(const hotkey_command& cmd, int /*index*/
// hotkey press handling
switch(cmd.id) {
case HOTKEY_SCROLL_UP:
keyboard_scroll(0, -1);
scroll_up(true);
break;
case HOTKEY_SCROLL_DOWN:
keyboard_scroll(0, 1);
scroll_down(true);
break;
case HOTKEY_SCROLL_LEFT:
keyboard_scroll(-1, 0);
scroll_left(true);
break;
case HOTKEY_SCROLL_RIGHT:
keyboard_scroll(1, 0);
scroll_right(true);
break;
case HOTKEY_CYCLE_UNITS:
cycle_units();

View file

@ -108,7 +108,10 @@ public:
virtual void left_mouse_click() {}
virtual void right_mouse_click() {}
virtual void toggle_accelerated_speed() {}
virtual void keyboard_scroll(int /*x*/, int /*y*/) {}
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() {}

View file

@ -218,9 +218,24 @@ void play_controller::hotkey_handler::toggle_accelerated_speed()
}
}
void play_controller::hotkey_handler::keyboard_scroll(int x, int y)
void play_controller::hotkey_handler::scroll_up(bool on)
{
play_controller_.apply_keyboard_scroll(x, y);
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)

View file

@ -117,7 +117,10 @@ public:
virtual void toggle_grid();
virtual void search();
virtual void toggle_accelerated_speed();
virtual void keyboard_scroll(int x, int y);
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(); }