Skip to content

Commit

Permalink
iOS: Touch interface implemented, and a RMB emulation of such on PC.
Browse files Browse the repository at this point in the history
  • Loading branch information
singalen authored and jyrkive committed Oct 28, 2018
1 parent ea2e16d commit aedc081
Show file tree
Hide file tree
Showing 14 changed files with 533 additions and 39 deletions.
6 changes: 6 additions & 0 deletions data/core/hotkeys.cfg
Expand Up @@ -40,6 +40,12 @@
command="deselecthex"
mouse=0
[/hotkey]
[hotkey]
button=1
command="selectmoveaction"
# Which means "touch"
mouse=255
[/hotkey]

[hotkey]
command=aiformula
Expand Down
5 changes: 5 additions & 0 deletions src/config_cache.cpp
Expand Up @@ -27,6 +27,7 @@

#include <boost/algorithm/string/replace.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <SDL_platform.h>

static lg::log_domain log_cache("cache");
#define ERR_CACHE LOG_STREAM(err, log_cache)
Expand All @@ -45,6 +46,10 @@ void add_builtin_defines(preproc_map& target)
target["APPLE"] = preproc_define();
#endif

#if defined(MOUSE_TOUCH_EMULATION) || defined(__IPHONEOS__)
target["IPHONEOS"] = preproc_define();
#endif

target["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
}

Expand Down
34 changes: 28 additions & 6 deletions src/controller_base.cpp
Expand Up @@ -56,6 +56,8 @@ void controller_base::handle_event(const SDL_Event& event)

events::mouse_handler_base& mh_base = get_mouse_handler_base();

SDL_Event new_event = {};

switch(event.type) {
case SDL_TEXTINPUT:
if(have_keyboard_focus()) {
Expand Down Expand Up @@ -96,33 +98,47 @@ void controller_base::handle_event(const SDL_Event& event)
break;

case SDL_JOYBUTTONDOWN:
process_keydown_event(event);
hotkey::jbutton_event(event, get_hotkey_command_executor());
break;

case SDL_JOYHATMOTION:
process_keydown_event(event);
hotkey::jhat_event(event, get_hotkey_command_executor());
break;

case SDL_MOUSEMOTION:
// Ignore old mouse motion events in the event queue
SDL_Event new_event;
if(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) {
while(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) {
};
mh_base.mouse_motion_event(new_event.motion, is_browsing());
if(new_event.motion.which != SDL_TOUCH_MOUSEID) {
mh_base.mouse_motion_event(new_event.motion, is_browsing());
}
} else {
if(new_event.motion.which != SDL_TOUCH_MOUSEID) {
mh_base.mouse_motion_event(event.motion, is_browsing());
}
}
break;

case SDL_FINGERMOTION:
if(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) {
while(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) {
};
mh_base.touch_motion_event(new_event.tfinger, is_browsing());
} else {
mh_base.mouse_motion_event(event.motion, is_browsing());
mh_base.touch_motion_event(event.tfinger, is_browsing());
}
break;

case SDL_MOUSEBUTTONDOWN:
process_keydown_event(event);
mh_base.mouse_press(event.button, is_browsing());
hotkey::mbutton_event(event, get_hotkey_command_executor());
break;

case SDL_FINGERDOWN:
// handled by mouse case
break;

case SDL_MOUSEBUTTONUP:
mh_base.mouse_press(event.button, is_browsing());
if(mh_base.get_show_menu()) {
Expand All @@ -131,6 +147,10 @@ void controller_base::handle_event(const SDL_Event& event)
}
break;

case SDL_FINGERUP:
// handled by mouse case
break;

case SDL_MOUSEWHEEL:
#if defined(_WIN32) || defined(__APPLE__)
mh_base.mouse_wheel(-event.wheel.x, event.wheel.y, is_browsing());
Expand All @@ -139,6 +159,8 @@ void controller_base::handle_event(const SDL_Event& event)
#endif
break;

// TODO: Support finger specifically, like pan the map. For now, SDL's "shadow mouse" events will do.
case SDL_MULTIGESTURE:
default:
break;
}
Expand Down
5 changes: 5 additions & 0 deletions src/editor/controller/editor_controller.cpp
Expand Up @@ -1290,6 +1290,11 @@ void editor_controller::mouse_motion(int x, int y, const bool /*browse*/,
gui().highlight_hex(hex_clicked);
}

void editor_controller::touch_motion(int /* x */, int /* y */, const bool /* browse */, bool /* update */, map_location /* new_loc */)
{
// Not implemented at all. Sorry, it's a very low priority for iOS port.
}

bool editor_controller::allow_mouse_wheel_scroll(int x, int y)
{
return get_current_map_context().map().on_board_with_border(gui().hex_clicked_on(x,y));
Expand Down
1 change: 1 addition & 0 deletions src/editor/controller/editor_controller.hpp
Expand Up @@ -154,6 +154,7 @@ class editor_controller : public controller_base,

/* mouse_handler_base overrides */
void mouse_motion(int x, int y, const bool browse, bool update, map_location new_loc = map_location::null_location()) override;
void touch_motion(int x, int y, const bool browse, bool update=false, map_location new_loc = map_location::null_location()) override;
editor_display& gui() override { return *gui_; }
const editor_display& gui() const override { return *gui_; }
bool allow_mouse_wheel_scroll(int x, int y) override;
Expand Down
60 changes: 59 additions & 1 deletion src/events.cpp
Expand Up @@ -504,11 +504,69 @@ void pump()
events.erase(first_draw_event + 1, events.end());
}

for(const SDL_Event& event : events) {
for(SDL_Event& event : events) {
for(context& c : event_contexts) {
c.add_staging_handlers();
}

#ifdef MOUSE_TOUCH_EMULATION
switch (event.type) {
// TODO: Implement SDL_MULTIGESTURE. Some day.
case SDL_MOUSEMOTION:
if(event.motion.which != SDL_TOUCH_MOUSEID && event.motion.state == 0) {
return;
}

if(event.motion.state & SDL_BUTTON(SDL_BUTTON_RIGHT))
{
SDL_Rect r = CVideo::get_singleton().screen_area();

// TODO: Check if SDL_FINGERMOTION is actually signaled for COMPLETE motions (I doubt, but tbs)
SDL_Event touch_event;
touch_event.type = SDL_FINGERMOTION;
touch_event.tfinger.type = SDL_FINGERMOTION;
touch_event.tfinger.timestamp = event.motion.timestamp;
touch_event.tfinger.touchId = 1;
touch_event.tfinger.fingerId = 1;
touch_event.tfinger.dx = static_cast<float>(event.motion.xrel) / r.w;
touch_event.tfinger.dy = static_cast<float>(event.motion.yrel) / r.h;
touch_event.tfinger.x = static_cast<float>(event.motion.x) / r.w;
touch_event.tfinger.y = static_cast<float>(event.motion.y) / r.h;
touch_event.tfinger.pressure = 1;
::SDL_PushEvent(&touch_event);

event.motion.state = SDL_BUTTON(SDL_BUTTON_LEFT);
event.motion.which = SDL_TOUCH_MOUSEID;
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if(event.button.button == SDL_BUTTON_RIGHT)
{
event.button.button = SDL_BUTTON_LEFT;
event.button.which = SDL_TOUCH_MOUSEID;

SDL_Rect r = CVideo::get_singleton().screen_area();
SDL_Event touch_event;
touch_event.type = (event.type == SDL_MOUSEBUTTONDOWN) ? SDL_FINGERDOWN : SDL_FINGERUP;
touch_event.tfinger.type = touch_event.type;
touch_event.tfinger.timestamp = event.button.timestamp;
touch_event.tfinger.touchId = 1;
touch_event.tfinger.fingerId = 1;
touch_event.tfinger.dx = 0;
touch_event.tfinger.dy = 0;
touch_event.tfinger.x = static_cast<float>(event.button.x) / r.w;
touch_event.tfinger.y = static_cast<float>(event.button.y) / r.h;
touch_event.tfinger.pressure = 1;
::SDL_PushEvent(&touch_event);

}
break;
default:
break;
}
#endif

switch(event.type) {
case SDL_WINDOWEVENT:
switch(event.window.event) {
Expand Down
42 changes: 34 additions & 8 deletions src/gui/core/event/handler.cpp
Expand Up @@ -379,17 +379,30 @@ void sdl_event_handler::handle_event(const SDL_Event& event)
return;
}

Uint8 button = event.button.button;
CVideo& video = dynamic_cast<window&>(*dispatchers_.back()).video();

switch(event.type) {
case SDL_MOUSEMOTION:
mouse(SDL_MOUSE_MOTION, {event.motion.x, event.motion.y});
#ifdef MOUSE_TOUCH_EMULATION
// There's no finger motion when it's not down.
if (event.motion.state != 0)
#endif
{
mouse(SDL_MOUSE_MOTION, {event.motion.x, event.motion.y});
}
break;

case SDL_MOUSEBUTTONDOWN:
mouse_button_down({event.button.x, event.button.y}, event.button.button);
{
mouse_button_down({event.button.x, event.button.y}, button);
}
break;

case SDL_MOUSEBUTTONUP:
mouse_button_up({event.button.x, event.button.y}, event.button.button);
{
mouse_button_up({event.button.x, event.button.y}, button);
}
break;

case SDL_MOUSEWHEEL:
Expand Down Expand Up @@ -465,20 +478,33 @@ void sdl_event_handler::handle_event(const SDL_Event& event)
break;

case SDL_FINGERMOTION:
touch_motion(point(event.tfinger.x, event.tfinger.y), point(event.tfinger.dx, event.tfinger.dy));
{
SDL_Rect r = video.screen_area();
touch_motion(point(event.tfinger.x * r.w, event.tfinger.y * r.h),
point(event.tfinger.dx * r.w, event.tfinger.dy * r.h));
}
break;

case SDL_FINGERUP:
touch_up(point(event.tfinger.x, event.tfinger.y));
{
SDL_Rect r = video.screen_area();
touch_up(point(event.tfinger.x * r.w, event.tfinger.y * r.h));
}
break;

case SDL_FINGERDOWN:
touch_down(point(event.tfinger.x, event.tfinger.y));
{
SDL_Rect r = video.screen_area();
touch_down(point(event.tfinger.x * r.w, event.tfinger.y * r.h));
}
break;

case SDL_MULTIGESTURE:
touch_multi_gesture(point(event.mgesture.x, event.mgesture.y),
event.mgesture.dTheta, event.mgesture.dDist, event.mgesture.numFingers);
{
SDL_Rect r = video.screen_area();
touch_multi_gesture(point(event.mgesture.x * r.w, event.mgesture.y * r.h),
event.mgesture.dTheta, event.mgesture.dDist, event.mgesture.numFingers);
}
break;

#if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32)
Expand Down
1 change: 0 additions & 1 deletion src/gui/dialogs/hotkey_bind.cpp
Expand Up @@ -39,7 +39,6 @@ void hotkey_bind::pre_show(window& window)
window.connect_signal<event::SDL_RAW_EVENT>(
std::bind(&hotkey_bind::sdl_event_callback, this, std::ref(window), _5),
event::dispatcher::front_child);

}

void hotkey_bind::sdl_event_callback(window& win, const SDL_Event &event)
Expand Down
2 changes: 1 addition & 1 deletion src/hotkey/command_executor.cpp
Expand Up @@ -593,7 +593,7 @@ void command_executor::queue_command(const SDL_Event& event, int index)
bool keypress = (event.type == SDL_KEYDOWN || event.type == SDL_TEXTINPUT) &&
!press_event_sent_;
bool press = keypress ||
(event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN);
(event.type == SDL_JOYBUTTONDOWN || event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_FINGERDOWN);
bool release = event.type == SDL_KEYUP;
if(press) {
LOG_HK << "sending press event (keypress = " <<
Expand Down
22 changes: 17 additions & 5 deletions src/hotkey/hotkey_item.cpp
Expand Up @@ -40,6 +40,11 @@ namespace hotkey {
hotkey_list hotkeys_;
config default_hotkey_cfg_;

namespace {
const int TOUCH_MOUSE_INDEX = 255;
const char TOUCH_MOUSE_STRING[] = "255";
};

static unsigned int sdl_get_mods()
{
unsigned int mods;
Expand Down Expand Up @@ -196,7 +201,11 @@ hotkey_ptr load_from_config(const config& cfg)
if (!mouse_cfg.empty()) {
auto mouse = std::make_shared<hotkey_mouse>();
base = std::dynamic_pointer_cast<hotkey_base>(mouse);
mouse->set_button(cfg["button"].to_int());
if (mouse_cfg == TOUCH_MOUSE_STRING) {
mouse->set_button(TOUCH_MOUSE_INDEX);
} else {
mouse->set_button(cfg["button"].to_int());
}
}
// TODO: add joystick support back
#if 0
Expand Down Expand Up @@ -254,7 +263,10 @@ hotkey_ptr load_from_config(const config& cfg)

bool hotkey_mouse::matches_helper(const SDL_Event &event) const
{
if (event.type != SDL_MOUSEBUTTONUP && event.type != SDL_MOUSEBUTTONDOWN) {
if (event.type != SDL_MOUSEBUTTONUP
&& event.type != SDL_MOUSEBUTTONDOWN
&& event.type != SDL_FINGERDOWN
&& event.type != SDL_FINGERUP) {
return false;
}

Expand All @@ -263,11 +275,11 @@ bool hotkey_mouse::matches_helper(const SDL_Event &event) const
return false;
}

if (event.button.button != button_) {
return false;
if (event.button.which == SDL_TOUCH_MOUSEID) {
return button_ == TOUCH_MOUSE_INDEX;
}

return true;
return event.button.button == button_;
}

const std::string hotkey_mouse::get_name_helper() const
Expand Down

0 comments on commit aedc081

Please sign in to comment.