summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorL. Krause <eska@eska.me>2017-04-24 21:41:39 +0200
committerL. Krause <eska@eska.me>2017-04-26 16:30:22 +0200
commit86f5ac3d749a6d46d029a7f48e4fb190d51643c4 (patch)
tree5faa48b716ee36309c138a83a546feeb311fb8a8
parenta99b6b2063c9259ef09bd1cc1289087460575d68 (diff)
Implement HTML5 touch events
-rw-r--r--platform/javascript/os_javascript.cpp306
-rw-r--r--platform/javascript/os_javascript.h11
2 files changed, 110 insertions, 207 deletions
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 45e77bc288..7d073654ce 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -41,9 +41,9 @@
#include <emscripten.h>
#include <stdlib.h>
-#define DOM_BUTTON_LEFT 0
-#define DOM_BUTTON_MIDDLE 1
-#define DOM_BUTTON_RIGHT 2
+#define DOM_BUTTON_LEFT 0
+#define DOM_BUTTON_MIDDLE 1
+#define DOM_BUTTON_RIGHT 2
template <typename T>
static InputModifierState dom2godot_mod(T emscripten_event_ptr) {
@@ -145,7 +145,7 @@ static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFulls
return false;
}
-static InputDefault* _input;
+static InputDefault *_input;
static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) {
@@ -159,9 +159,9 @@ static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent
ev.mouse_button.mod = dom2godot_mod(mouse_event);
switch (mouse_event->button) {
- case DOM_BUTTON_LEFT: ev.mouse_button.button_index = BUTTON_LEFT; break;
+ case DOM_BUTTON_LEFT: ev.mouse_button.button_index = BUTTON_LEFT; break;
case DOM_BUTTON_MIDDLE: ev.mouse_button.button_index = BUTTON_MIDDLE; break;
- case DOM_BUTTON_RIGHT: ev.mouse_button.button_index = BUTTON_RIGHT; break;
+ case DOM_BUTTON_RIGHT: ev.mouse_button.button_index = BUTTON_RIGHT; break;
default: return false;
}
@@ -233,6 +233,94 @@ static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel
return true;
}
+static Point2 _prev_touches[32];
+
+static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) {
+
+ ERR_FAIL_COND_V(
+ event_type != EMSCRIPTEN_EVENT_TOUCHSTART &&
+ event_type != EMSCRIPTEN_EVENT_TOUCHEND &&
+ event_type != EMSCRIPTEN_EVENT_TOUCHCANCEL,
+ false);
+
+ InputEvent ev;
+ ev.type = InputEvent::SCREEN_TOUCH;
+ int lowest_id_index = -1;
+ for (int i = 0; i < touch_event->numTouches; ++i) {
+
+ const EmscriptenTouchPoint &touch = touch_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < touch_event->touches[lowest_id_index].identifier)
+ lowest_id_index = i;
+ if (!touch.isChanged)
+ continue;
+ ev.screen_touch.index = touch.identifier;
+ _prev_touches[i].x = ev.screen_touch.x = touch.canvasX;
+ _prev_touches[i].y = ev.screen_touch.y = touch.canvasY;
+ ev.screen_touch.pressed = event_type == EMSCRIPTEN_EVENT_TOUCHSTART;
+
+ _input->parse_input_event(ev);
+ }
+
+ if (touch_event->touches[lowest_id_index].isChanged) {
+
+ ev.type = InputEvent::MOUSE_BUTTON;
+ ev.mouse_button.mod = dom2godot_mod(touch_event);
+ ev.mouse_button.button_mask = _input->get_mouse_button_mask() >> 1;
+ ev.mouse_button.global_x = ev.mouse_button.x = touch_event->touches[lowest_id_index].canvasX;
+ ev.mouse_button.global_y = ev.mouse_button.y = touch_event->touches[lowest_id_index].canvasY;
+ ev.mouse_button.button_index = BUTTON_LEFT;
+ ev.mouse_button.pressed = event_type == EMSCRIPTEN_EVENT_TOUCHSTART;
+
+ _input->parse_input_event(ev);
+ }
+ return true;
+}
+
+static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) {
+
+ ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_TOUCHMOVE, false);
+
+ InputEvent ev;
+ ev.type = InputEvent::SCREEN_DRAG;
+ int lowest_id_index = -1;
+ for (int i = 0; i < touch_event->numTouches; ++i) {
+
+ const EmscriptenTouchPoint &touch = touch_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < touch_event->touches[lowest_id_index].identifier)
+ lowest_id_index = i;
+ if (!touch.isChanged)
+ continue;
+ ev.screen_drag.index = touch.identifier;
+ ev.screen_drag.x = touch.canvasX;
+ ev.screen_drag.y = touch.canvasY;
+ Point2 &prev = _prev_touches[i];
+ ev.screen_drag.relative_x = touch.canvasX - prev.x;
+ ev.screen_drag.relative_y = touch.canvasY - prev.y;
+ prev.x = ev.screen_drag.x;
+ prev.y = ev.screen_drag.y;
+
+ _input->parse_input_event(ev);
+ }
+
+ if (touch_event->touches[lowest_id_index].isChanged) {
+
+ ev.type = InputEvent::MOUSE_MOTION;
+ ev.mouse_motion.mod = dom2godot_mod(touch_event);
+ ev.mouse_motion.button_mask = _input->get_mouse_button_mask() >> 1;
+ ev.mouse_motion.global_x = ev.mouse_motion.x = touch_event->touches[lowest_id_index].canvasX;
+ ev.mouse_motion.global_y = ev.mouse_motion.y = touch_event->touches[lowest_id_index].canvasY;
+ ev.mouse_motion.relative_x = _input->get_mouse_position().x - ev.mouse_motion.x;
+ ev.mouse_motion.relative_y = _input->get_mouse_position().y - ev.mouse_motion.y;
+
+ _input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
+ ev.mouse_motion.speed_x = _input->get_last_mouse_speed().x;
+ ev.mouse_motion.speed_y = _input->get_last_mouse_speed().y;
+
+ _input->parse_input_event(ev);
+ }
+ return true;
+}
+
static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
InputEvent ev;
@@ -364,23 +452,27 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result))
-#define SET_EM_CALLBACK(ev, cb) \
- result = emscripten_set_##ev##_callback(NULL, this, true, &cb); \
+#define SET_EM_CALLBACK(target, ev, cb) \
+ result = emscripten_set_##ev##_callback(target, this, true, &cb); \
EM_CHECK(ev)
#define SET_EM_CALLBACK_NODATA(ev, cb) \
result = emscripten_set_##ev##_callback(NULL, true, &cb); \
EM_CHECK(ev)
EMSCRIPTEN_RESULT result;
- SET_EM_CALLBACK(mousemove, _mousemove_callback)
- SET_EM_CALLBACK(mousedown, _mousebutton_callback)
- SET_EM_CALLBACK(mouseup, _mousebutton_callback)
- SET_EM_CALLBACK(wheel, _wheel_callback)
- SET_EM_CALLBACK(keydown, _keydown_callback)
- SET_EM_CALLBACK(keypress, _keypress_callback)
- SET_EM_CALLBACK(keyup, _keyup_callback)
- SET_EM_CALLBACK(resize, _browser_resize_callback)
- SET_EM_CALLBACK(fullscreenchange, _fullscreen_change_callback)
+ SET_EM_CALLBACK("#canvas", mousemove, _mousemove_callback)
+ SET_EM_CALLBACK("#canvas", mousedown, _mousebutton_callback)
+ SET_EM_CALLBACK("#canvas", mouseup, _mousebutton_callback)
+ SET_EM_CALLBACK("#canvas", wheel, _wheel_callback)
+ SET_EM_CALLBACK("#canvas", touchstart, _touchpress_callback)
+ SET_EM_CALLBACK("#canvas", touchmove, _touchmove_callback)
+ SET_EM_CALLBACK("#canvas", touchend, _touchpress_callback)
+ SET_EM_CALLBACK("#canvas", touchcancel, _touchpress_callback)
+ SET_EM_CALLBACK("#canvas", keydown, _keydown_callback)
+ SET_EM_CALLBACK("#canvas", keypress, _keypress_callback)
+ SET_EM_CALLBACK("#canvas", keyup, _keyup_callback)
+ SET_EM_CALLBACK(NULL, resize, _browser_resize_callback)
+ SET_EM_CALLBACK(NULL, fullscreenchange, _fullscreen_change_callback)
SET_EM_CALLBACK_NODATA(gamepadconnected, joy_callback_func)
SET_EM_CALLBACK_NODATA(gamepaddisconnected, joy_callback_func)
@@ -623,186 +715,6 @@ void OS_JavaScript::main_loop_focusin() {
//audio_driver_javascript.set_pause(false);
}
-void OS_JavaScript::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
-
- //print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
-
- switch (p_what) {
- case 0: { //gesture begin
-
- if (touch.size()) {
- //end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->parse_input_event(ev);
-
- for (int i = 0; i < touch.size(); i++) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- }
- }
-
- touch.resize(p_points.size());
- for (int i = 0; i < p_points.size(); i++) {
- touch[i].id = p_points[i].id;
- touch[i].pos = p_points[i].pos;
- }
-
- {
- //send mouse
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- last_mouse = touch[0].pos;
- input->parse_input_event(ev);
- }
-
- //send touch
- for (int i = 0; i < touch.size(); i++) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- }
-
- } break;
- case 1: { //motion
-
- if (p_points.size()) {
- //send mouse, should look for point 0?
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.mouse_motion.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_motion.x = p_points[0].pos.x;
- ev.mouse_motion.y = p_points[0].pos.y;
- input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ev.mouse_motion.relative_x = p_points[0].pos.x - last_mouse.x;
- ev.mouse_motion.relative_y = p_points[0].pos.y - last_mouse.y;
- last_mouse = p_points[0].pos;
- input->parse_input_event(ev);
- }
-
- ERR_FAIL_COND(touch.size() != p_points.size());
-
- for (int i = 0; i < touch.size(); i++) {
-
- int idx = -1;
- for (int j = 0; j < p_points.size(); j++) {
-
- if (touch[i].id == p_points[j].id) {
- idx = j;
- break;
- }
- }
-
- ERR_CONTINUE(idx == -1);
-
- if (touch[i].pos == p_points[idx].pos)
- continue; //no move unncesearily
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.screen_drag.index = touch[i].id;
- ev.screen_drag.x = p_points[idx].pos.x;
- ev.screen_drag.y = p_points[idx].pos.y;
- ev.screen_drag.relative_x = p_points[idx].pos.x - touch[i].pos.x;
- ev.screen_drag.relative_y = p_points[idx].pos.y - touch[i].pos.y;
- input->parse_input_event(ev);
- touch[i].pos = p_points[idx].pos;
- }
-
- } break;
- case 2: { //release
-
- if (touch.size()) {
- //end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->parse_input_event(ev);
-
- for (int i = 0; i < touch.size(); i++) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- }
- touch.clear();
- }
-
- } break;
- case 3: { // add tuchi
-
- ERR_FAIL_INDEX(p_pointer, p_points.size());
-
- TouchPos tp = p_points[p_pointer];
- touch.push_back(tp);
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = tp.id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = tp.pos.x;
- ev.screen_touch.y = tp.pos.y;
- input->parse_input_event(ev);
-
- } break;
- case 4: {
-
- for (int i = 0; i < touch.size(); i++) {
- if (touch[i].id == p_pointer) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- touch.remove(i);
- i--;
- }
- }
-
- } break;
- }
-}
-
void OS_JavaScript::process_accelerometer(const Vector3 &p_accelerometer) {
input->set_accelerometer(p_accelerometer);
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 5d86640d95..0c956ecba6 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -49,15 +49,7 @@ typedef void (*GFXInitFunc)(void *ud, bool gl2, int w, int h, bool fs);
typedef String (*GetDataDirFunc)();
class OS_JavaScript : public OS_Unix {
-public:
- struct TouchPos {
- int id;
- Point2 pos;
- };
-
-private:
- Vector<TouchPos> touch;
- Point2 last_mouse;
+
GFXInitFunc gfx_init_func;
void *gfx_init_ud;
@@ -165,7 +157,6 @@ public:
virtual String get_resource_dir() const;
void process_accelerometer(const Vector3 &p_accelerometer);
- void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
void push_input(const InputEvent &p_ev);
virtual bool is_joy_known(int p_device);