]> git.tdb.fi Git - libs/gltk.git/commitdiff
Rudimentary touchscreen support
authorMikko Rasa <tdb@tdb.fi>
Thu, 19 Nov 2015 11:22:40 +0000 (13:22 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 19 Nov 2015 11:22:40 +0000 (13:22 +0200)
There are no touch-specific interactions yet, but this allows input to
work with a touchscreen.

source/container.cpp
source/container.h
source/root.cpp
source/root.h
source/widget.cpp
source/widget.h

index b7bd2ad5dc9b06f7eb88c08db4fd90b43356c781..21d31fb0e2af7a988159a74895cfddc863e8c536 100644 (file)
@@ -16,7 +16,8 @@ Container::Container():
        click_button(0),
        pointer_focus(0),
        pointer_grabbed(false),
-       input_focus(0)
+       input_focus(0),
+       touch_focus(0)
 { }
 
 Container::~Container()
@@ -166,7 +167,7 @@ Widget *Container::get_final_input_focus() const
 
 void Container::button_press(int x, int y, unsigned btn)
 {
-       if(Widget *child = get_pointer_target(x, y))
+       if(Widget *child = get_pointer_target(x, y, false))
        {
                if(!click_focus)
                {
@@ -185,7 +186,7 @@ void Container::button_press(int x, int y, unsigned btn)
 
 void Container::button_release(int x, int y, unsigned btn)
 {
-       if(Widget *child = get_pointer_target(x, y))
+       if(Widget *child = get_pointer_target(x, y, false))
        {
                if(child==click_focus && btn==click_button)
                {
@@ -201,7 +202,7 @@ void Container::button_release(int x, int y, unsigned btn)
 
 void Container::pointer_motion(int x, int y)
 {
-       Widget *child = get_pointer_target(x, y);
+       Widget *child = get_pointer_target(x, y, false);
        if(!pointer_grabbed)
                set_pointer_focus((!click_focus || child->get_geometry().is_inside(x, y)) ? child : 0);
 
@@ -212,12 +213,14 @@ void Container::pointer_motion(int x, int y)
        }
 }
 
-Widget *Container::get_pointer_target(int x, int y) const
+Widget *Container::get_pointer_target(int x, int y, bool touch) const
 {
        if(pointer_grabbed)
                return pointer_focus;
-       else if(click_focus)
+       else if(!touch && click_focus)
                return click_focus;
+       else if(touch && touch_focus)
+               return touch_focus;
        else
        {
                Widget *child = get_child_at(x, y);
@@ -252,6 +255,41 @@ void Container::character(wchar_t ch)
                input_focus->character(ch);
 }
 
+void Container::touch_press(int x, int y, unsigned finger)
+{
+       if(Widget *child = get_pointer_target(x, y, true))
+       {
+               // TODO track focus for each finger separately
+               if(!touch_focus)
+                       touch_focus = child;
+
+               const Geometry &cgeom = child->get_geometry();
+               child->touch_press(x-cgeom.x, y-cgeom.y, finger);
+       }
+}
+
+void Container::touch_release(int x, int y, unsigned finger)
+{
+       if(Widget *child = get_pointer_target(x, y, true))
+       {
+               // TODO track focus for each finger separately
+               if(child==touch_focus)
+                       touch_focus = 0;
+
+               const Geometry &cgeom = child->get_geometry();
+               child->touch_release(x-cgeom.x, y-cgeom.y, finger);
+       }
+}
+
+void Container::touch_motion(int x, int y, unsigned finger)
+{
+       if(Widget *child = get_pointer_target(x, y, true))
+       {
+               const Geometry &cgeom = child->get_geometry();
+               child->touch_motion(x-cgeom.x, y-cgeom.y, finger);
+       }
+}
+
 void Container::focus_out()
 {
        set_input_focus(0);
index 2c29e5d881e3615d765648ab8cbf3c9bf8835f1d..89e3259e3bdbf71791ed445bb3587b1e8ec80e0d 100644 (file)
@@ -40,6 +40,7 @@ protected:
        Widget *pointer_focus;
        bool pointer_grabbed;
        Widget *input_focus;
+       Widget *touch_focus;
 
        Container();
 public:
@@ -69,11 +70,14 @@ public:
        virtual void button_release(int, int, unsigned);
        virtual void pointer_motion(int, int);
 private:
-       Widget *get_pointer_target(int, int) const;
+       Widget *get_pointer_target(int, int, bool) const;
 public:
        virtual void pointer_leave();
        virtual void key_press(unsigned, unsigned);
        virtual void key_release(unsigned, unsigned);
+       virtual void touch_press(int, int, unsigned);
+       virtual void touch_release(int, int, unsigned);
+       virtual void touch_motion(int, int, unsigned);
        virtual void character(wchar_t);
        virtual void focus_out();
 protected:
index 8b06f4788f9f4ae45b8837ed63f6c1569b8bc62a..a90ea5a23d9eec4a3b3bacc34b94fb1a912b8b4c 100644 (file)
@@ -16,15 +16,17 @@ Root::Root(const Resources &r, Graphics::Window &window):
        resources(r),
        keyboard(new Input::Keyboard(window)),
        mouse(new Input::Mouse(window)),
+       touchscreen(0),
        own_input(true)
 {
        init(&window);
 }
 
-Root::Root(const Resources &r, Graphics::Window *window, Input::Keyboard *k, Input::Mouse *m):
+Root::Root(const Resources &r, Graphics::Window *window, Input::Keyboard *k, Input::Mouse *m, Input::Touchscreen *t):
        resources(r),
        keyboard(k),
        mouse(m),
+       touchscreen(t),
        own_input(false)
 {
        init(window);
@@ -68,6 +70,13 @@ void Root::init(Graphics::Window *window)
                keyboard->signal_button_release.connect(sigc::mem_fun(this, &Root::key_release_event));
                keyboard->signal_character.connect(sigc::mem_fun(this, &Root::character_event));
        }
+
+       if(touchscreen)
+       {
+               touchscreen->signal_button_press.connect(sigc::mem_fun(this, &Root::touch_press_event));
+               touchscreen->signal_button_release.connect(sigc::mem_fun(this, &Root::touch_release_event));
+               touchscreen->signal_axis_motion.connect(sigc::mem_fun(this, &Root::touch_motion_event));
+       }
 }
 
 Root::~Root()
@@ -243,12 +252,68 @@ bool Root::character_event(StringCodec::unichar ch)
        return false;
 }
 
+bool Root::touch_press_event(unsigned finger)
+{
+       if(visible)
+       {
+               Widget *old_focus = touch_focus;
+
+               int x, y;
+               get_touch(finger, x, y);
+               touch_press(x, y, finger);
+
+               if(touch_focus || old_focus)
+                       return true;
+       }
+
+       return false;
+}
+
+bool Root::touch_release_event(unsigned finger)
+{
+       if(visible)
+       {
+               Widget *old_focus = touch_focus;
+
+               int x, y;
+               get_touch(finger, x, y);
+               touch_release(x, y, finger);
+
+               if(touch_focus || old_focus)
+                       return true;
+       }
+
+       return false;
+}
+
+bool Root::touch_motion_event(unsigned axis, float, float)
+{
+       if(visible)
+       {
+               unsigned finger = axis/2;
+               int x, y;
+               get_touch(finger, x, y);
+               touch_motion(x, y, finger);
+
+               if(touch_focus)
+                       return true;
+       }
+
+       return false;
+}
+
 void Root::get_pointer(int &x, int &y)
 {
        x = (mouse->get_axis_value(0)*0.5+0.5)*geom.w;
        y = (mouse->get_axis_value(1)*0.5+0.5)*geom.h;
 }
 
+void Root::get_touch(unsigned finger, int &x, int &y)
+{
+       x = (touchscreen->get_axis_value(finger*2)*0.5+0.5)*geom.w;
+       y = (touchscreen->get_axis_value(finger*2+1)*0.5+0.5)*geom.h;
+}
+
 void Root::update_camera()
 {
        camera.set_position(GL::Vector3(geom.w/2.0f, geom.h/2.0f, geom.h/2.0f));
index 8e1bed9247e00bd2693bd9fe904ab16995591c9a..5d721c0c2370f5e1ac68d68ef1aee8e987bdbde0 100644 (file)
@@ -7,6 +7,7 @@
 #include <msp/graphics/window.h>
 #include <msp/input/keyboard.h>
 #include <msp/input/mouse.h>
+#include <msp/input/touchscreen.h>
 #include <msp/time/timestamp.h>
 #include "panel.h"
 
@@ -28,6 +29,7 @@ private:
        const Resources &resources;
        Input::Keyboard *keyboard;
        Input::Mouse *mouse;
+       Input::Touchscreen *touchscreen;
        bool own_input;
        Label *lbl_tooltip;
        int pointer_x;
@@ -44,7 +46,7 @@ public:
 
        /** Creates a Root widget with custom input devices.  If window is not null,
        it is used to set the widget's initial geometry. */
-       Root(const Resources &, Graphics::Window *, Input::Keyboard *, Input::Mouse *);
+       Root(const Resources &, Graphics::Window *, Input::Keyboard *, Input::Mouse *, Input::Touchscreen * = 0);
 private:
        void init(Graphics::Window *);
 public:
@@ -66,8 +68,12 @@ private:
        bool key_press_event(unsigned);
        bool key_release_event(unsigned);
        bool character_event(StringCodec::unichar);
+       bool touch_press_event(unsigned);
+       bool touch_release_event(unsigned);
+       bool touch_motion_event(unsigned, float, float);
 
        void get_pointer(int &, int &);
+       void get_touch(unsigned, int &, int &);
        void update_camera();
 
        virtual void on_geometry_change();
index 76b6e615712c29c459d208abe8300671aae5bc6e..38f8e92a67d4db6b97bef640e539b5c367ebbc73 100644 (file)
@@ -240,6 +240,24 @@ void Widget::pointer_leave()
        clear_state(HOVER);
 }
 
+void Widget::touch_press(int x, int y, unsigned finger)
+{
+       if(finger==0)
+               button_press(x, y, 1);
+}
+
+void Widget::touch_release(int x, int y, unsigned finger)
+{
+       if(finger==0)
+               button_release(x, y, 1);
+}
+
+void Widget::touch_motion(int x, int y, unsigned finger)
+{
+       if(finger==0)
+               pointer_motion(x, y);
+}
+
 void Widget::focus_in()
 {
        set_state(FOCUS);
index 4550648aebd3adbfaaebc09b5f60669b05ade595..557e10153269c2290bc8c6c4e938fc95c8284874 100644 (file)
@@ -139,6 +139,9 @@ public:
        virtual void key_press(unsigned, unsigned) { }
        virtual void key_release(unsigned, unsigned) { }
        virtual void character(wchar_t) { }
+       virtual void touch_press(int, int, unsigned);
+       virtual void touch_release(int, int, unsigned);
+       virtual void touch_motion(int, int, unsigned);
        virtual void focus_in();
        virtual void focus_out();
 protected: