#!/usr/bin/env python
# [SNIPPET_NAME: gtk3 touch example]
# [SNIPPET_CATEGORIES: opengl]
# [SNIPPET_TAGS: touch, gtk3]
# [SNIPPET_DESCRIPTION: handling touch events with GTK3]
# [SNIPPET_AUTHOR: Oliver Marks ]
# [SNIPPET_LICENSE: GPL]

import sys
from gi.repository import Gtk, GdkX11, Gdk


class gui():

    def __init__(self):
        self.touch_count = 0
        self.window = Gtk.Window()
        self.window.realize()
        self.window.resize(300, 300)
        self.window.set_resizable(True)
        self.window.set_reallocate_redraws(True)
        self.window.set_title("GTK3 touch events")
        self.window.connect('delete_event', Gtk.main_quit)
        self.window.connect('destroy', lambda quit: Gtk.main_quit())

        self.drawing_area = Gtk.DrawingArea()
        #add the type of events we are interested in retrieving, skip this step and your events will never fire
        self.drawing_area.add_events(Gdk.EventMask.TOUCH_MASK)
        self.drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
        self.drawing_area.connect('button_press_event', self.touched)
        self.drawing_area.connect('touch-event', self.touched)
        self.drawing_area.set_double_buffered(False)

        self.window.add(self.drawing_area)
        self.window.show_all()

    def touched(self, widget, ev):
        # detect the type of device we can filter events using this
        # if we dont a touch event and mouse event can be triggered from one touch for example
        if ev.get_source_device().get_source() == Gdk.InputSource.TOUCHPAD:
            print('touchpad device')
        if ev.get_source_device().get_source() == Gdk.InputSource.MOUSE:
            print('mouse device')
        if ev.get_source_device().get_source() == Gdk.InputSource.TOUCHSCREEN:
            print('touchscreen device')
            
            #from what i can tell there is no support for gestures so you would need another library
            #or to handle this yourself
            if ev.touch.type == Gdk.EventType.TOUCH_BEGIN:
                self.touch_count += 1
                print('start %d %s %s' % (self.touch_count, ev.touch.x,ev.touch.y))
            if ev.touch.type == Gdk.EventType.TOUCH_UPDATE:
                print('UPDATE %d %s %s' % (self.touch_count, ev.touch.x,ev.touch.y))
            if ev.touch.type == Gdk.EventType.TOUCH_END:
                self.touch_count -= 1
                print('end %d %s %s' % (self.touch_count, ev.touch.x,ev.touch.y))
            if ev.touch.type == Gdk.EventType.TOUCH_CANCEL:
                self.touch_count -= 1
                print('cancelled')

def main():
    g = gui()
    Gtk.main()

if __name__ == '__main__':
    main()
