34 #define ERR_DP LOG_STREAM(err, log_display)
36 using namespace std::chrono_literals;
46 , scroll_right_(false)
48 , scroll_carry_x_(0.0)
49 , scroll_carry_y_(0.0)
50 , key_release_listener_(*this)
51 , last_mouse_is_touch_(false)
52 , long_touch_timer_(0)
71 #ifdef MOUSE_TOUCH_EMULATION
72 if(mouse_state & SDL_BUTTON(SDL_BUTTON_RIGHT)) {
74 mouse_state = SDL_BUTTON(SDL_BUTTON_LEFT);
82 bool yes_actually_dragging = dx * dx + dy * dy >= threshold * threshold;
84 if(!yes_actually_dragging
85 && (mouse_state & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0
106 SDL_Event new_event = {};
115 case SDL_TEXTEDITING:
117 SDL_Event evt = event;
118 evt.type = SDL_TEXTINPUT;
121 SDL_StartTextInput();
129 if(event.key.keysym.sym == SDLK_ESCAPE) {
147 case SDL_JOYBUTTONDOWN:
151 case SDL_JOYHATMOTION:
155 case SDL_MOUSEMOTION:
157 if(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) {
158 while(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) {
160 if(new_event.motion.which != SDL_TOUCH_MOUSEID) {
164 if(new_event.motion.which != SDL_TOUCH_MOUSEID) {
170 case SDL_FINGERMOTION:
171 if(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) {
172 while(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) {
180 case SDL_MOUSEBUTTONDOWN:
197 case SDL_MOUSEBUTTONUP:
207 show_menu(
get_display().get_theme().context_menu()->items(), event.button.x, event.button.y,
true,
213 int x =
static_cast<int>(
reinterpret_cast<std::intptr_t
>(
event.user.data1));
214 int y =
static_cast<int>(
reinterpret_cast<std::intptr_t
>(
event.user.data2));
215 if(event.user.code ==
static_cast<int>(SDL_TOUCH_MOUSEID)
237 #if defined(_WIN32) || defined(__APPLE__)
250 const char* video_driver = SDL_GetCurrentVideoDriver();
252 SDL_GetVersion(&ver);
253 if(video_driver !=
nullptr && ver.major <= 2 && ver.minor <= 0) {
254 if(std::strcmp(video_driver,
"x11") == 0 && ver.patch < 18) {
256 }
else if(std::strcmp(video_driver,
"wayland") == 0 && ver.patch < 20) {
271 case SDL_MULTIGESTURE:
288 if(event.type == SDL_KEYUP) {
300 const bool mouse_in_window =
305 double dx = 0.0, dy = 0.0;
307 int scroll_threshold =
prefs::get().mouse_scrolling()
312 if(m.get_location().contains(mousex, mousey)) {
313 scroll_threshold = 0;
318 auto tick_now = std::chrono::steady_clock::now();
323 dt = std::chrono::duration_cast<std::chrono::milliseconds>(tick_now -
last_scroll_tick_);
329 double scroll_amount = dt.count() * 0.036 * double(scroll_speed);
339 if(mouse_in_window) {
340 if(mousey < scroll_threshold) {
348 if(mousex < scroll_threshold) {
360 if((mouse_flags & SDL_BUTTON_MMASK) != 0 &&
prefs::get().middle_click_scrolls()) {
369 const double speed = 0.01 * scroll_amount;
370 const double snap_dist = 16;
371 const double x_diff = (mousex - original_loc.x);
372 const double y_diff = (mousey - original_loc.y);
374 if(std::fabs(x_diff) > snap_dist || std::fabs(y_diff) <= snap_dist) {
375 dx += speed * x_diff;
378 if(std::fabs(y_diff) > snap_dist || std::fabs(x_diff) <= snap_dist) {
379 dy += speed * y_diff;
397 point dist{int(dx), int(dy)};
443 if(!str_vec.empty()) {
464 const std::vector<config>& items_arg,
int xloc,
int yloc,
bool context_menu,
display& disp)
471 std::vector<config> items;
472 for(
const config&
c : items_arg) {
473 const std::string&
id =
c[
"id"];
477 items.emplace_back(
c);
485 cmd_exec->
show_menu(items, xloc, yloc, context_menu, disp);
495 std::vector<std::string> items;
496 for(
const std::string& item : items_arg) {
499 items.push_back(item);
Class that keeps track of all the keys on the keyboard.
A config object defines a single node in a WML file, with access to child nodes.
controller_base & controller_
void handle_event(const SDL_Event &event) override
bool handle_scroll(int mousex, int mousey, int mouse_flags)
Handle scrolling by keyboard, joystick and moving mouse near map edges.
virtual events::mouse_handler_base & get_mouse_handler_base()=0
Get a reference to a mouse handler member a derived class uses.
virtual ~controller_base()
virtual plugins_context * get_plugins_context()
Get (optionally) a plugins context a derived class uses.
size_t long_touch_timer_
Context menu timer.
virtual soundsource::manager * get_soundsource_man()
Get (optionally) a soundsources manager a derived class uses.
virtual bool in_context_menu(const hotkey::ui_command &cmd) const
void handle_event(const SDL_Event &event) override
Process mouse- and keypress-events from SDL.
virtual void process_keyup_event(const SDL_Event &)
Process keyup (always).
virtual void process() override
virtual void process_focus_keydown_event(const SDL_Event &)
Process keydown (only when the general map display does not have focus).
virtual bool have_keyboard_focus()
Derived classes should override this to return false when arrow keys should not scroll the map,...
bool last_mouse_is_touch_
virtual void process_keydown_event(const SDL_Event &)
Process keydown (always).
virtual display & get_display()=0
Get a reference to a display member a derived class uses.
void long_touch_callback(int x, int y)
virtual std::vector< std::string > additional_actions_pressed()
virtual hotkey::command_executor * get_hotkey_command_executor()
Optionally get a command executor to handle context menu events.
virtual void play_slice()
std::chrono::steady_clock::time_point last_scroll_tick_
virtual void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu, display &disp)
virtual bool is_browsing() const
virtual void execute_action(const std::vector< std::string > &items_arg, int xloc, int yloc, bool context_menu)
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
const theme::action * action_pressed()
const theme::menu * menu_pressed()
rect map_area() const
Returns the area used for the map.
const map_location & mouseover_hex() const
bool scroll(const point &amount, bool force=false)
Scrolls the display by amount pixels.
virtual int drag_threshold() const
Minimum dragging distance to fire the drag&drop.
void touch_motion_event(const SDL_TouchFingerEvent &event, const bool browse)
virtual void mouse_press(const SDL_MouseButtonEvent &event, const bool browse)
void mouse_update(const bool browse, map_location loc)
Update the mouse with a fake mouse motion.
virtual display & gui()=0
Reference to the used display objects.
void mouse_motion_event(const SDL_MouseMotionEvent &event, const bool browse)
bool scroll_started() const
const SDL_Point get_scroll_start() const
bool get_show_menu() const
virtual void mouse_wheel(int xscroll, int yscroll, bool browse)
Called when scrolling with the mouse wheel.
void set_scroll_start(int x, int y)
Called when the middle click scrolling.
void execute_quit_command()
void execute_action(const std::vector< std::string > &items_arg, int xloc, int yloc, bool context_menu, display &gui)
virtual void show_menu(const std::vector< config > &items_arg, int xloc, int yloc, bool context_menu, display &gui)
virtual bool can_execute_command(const hotkey::ui_command &command) const =0
bool get_scroll_when_mouse_outside(bool def)
int mouse_scroll_threshold()
Gets the threshold for when to scroll.
virtual rect & location(const SDL_Rect &screen) const
const std::vector< std::string > & items() const
const menu * context_menu() const
static lg::log_domain log_display("display")
static constexpr auto long_touch_duration
controller_base framework: controller_base is roughly analogous to a "dialog" class in a GUI toolkit ...
map_display and display: classes which take care of displaying the map and game-data on the screen.
#define DOUBLE_CLICK_EVENT
Standard logging facilities (interface).
void draw()
Trigger a draw cycle.
void raise_process_event()
void pump()
Process all events currently in the queue.
Game configuration data as global variables.
bool is_in_dialog()
Is a dialog open?
std::size_t add_timer(const std::chrono::milliseconds &interval, const std::function< void(std::size_t id)> &callback, const bool repeat)
Adds a new timer.
bool remove_timer(const std::size_t id)
Removes a timer.
bool execute_timer(const std::size_t id)
Executes a timer.
void jhat_event(const SDL_Event &event, command_executor *executor)
void key_event(const SDL_Event &event, command_executor *executor)
void mbutton_event(const SDL_Event &event, command_executor *executor)
void run_events(command_executor *executor)
void jbutton_event(const SDL_Event &event, command_executor *executor)
void keyup_event(const SDL_Event &, command_executor *executor)
uint32_t get_mouse_state(int *x, int *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
bool window_has_mouse_focus()
True iff the window has mouse focus.
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
rect game_canvas()
The game canvas area, in drawing coordinates.
Used as the main paramneter for can_execute_command/do_execute_command These functions are used to ex...
Encapsulates the map of the game.
An abstract description of a rectangle with integer coordinates.
bool contains(int x, int y) const
Whether the given point lies within the rectangle.
Contains the gui2 timer routines.