From 80bf5e280bf8396d62683c2cd6cfa6c01d3bc70c Mon Sep 17 00:00:00 2001 From: Cecil Date: Sat, 20 Jul 2019 19:18:34 -0600 Subject: [PATCH] for #447 - touch screen scrolling - not quite right but OK in some situations. * does not pass touch events to a 'touch' method. * some errors are other Shoes 3.3.8 bugs, some are touch related. --- Tests/touch/kiosk.rb | 2 +- Tests/touch/t1.rb | 10 ++++ Tests/touch/t2.rb | 17 ++++++ shoes/app.h | 2 + shoes/native/gtk.c | 106 ++++++++++++++++++++++++++++----- shoes/native/gtk/gtkfixedalt.c | 1 + 6 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 Tests/touch/t1.rb create mode 100644 Tests/touch/t2.rb diff --git a/Tests/touch/kiosk.rb b/Tests/touch/kiosk.rb index 87c629f4..973aec2c 100644 --- a/Tests/touch/kiosk.rb +++ b/Tests/touch/kiosk.rb @@ -8,7 +8,7 @@ { name: "Meg's Clothing", picture: "res/shop4.png", point: [485,307]} ] -Shoes.app width: 800, height: 400 do +Shoes.app width: 800, height: 400, menus: true do background lightpink # returns a layout with buttons that change the panel diff --git a/Tests/touch/t1.rb b/Tests/touch/t1.rb new file mode 100644 index 00000000..fd375152 --- /dev/null +++ b/Tests/touch/t1.rb @@ -0,0 +1,10 @@ +Shoes.app width: 600, height: 400, menus: false do + stack do + button "quit" do + Shoes.quit + end + 40.times.each do |i| + para "Line #{i}" + end + end +end diff --git a/Tests/touch/t2.rb b/Tests/touch/t2.rb new file mode 100644 index 00000000..ce251e49 --- /dev/null +++ b/Tests/touch/t2.rb @@ -0,0 +1,17 @@ +Shoes.app width: 600, height: 400, menus: false do + stack do + button "quit" do + Shoes.quit + end + 10.times.each do |i| + para "Line #{i+1}" + end + @eb = edit_box "First" + 30.times.each do |i| + @eb.append "\nline #{i+1}" + end + 30.times.each do |i| + para "Line #{i+11}" + end + end +end diff --git a/shoes/app.h b/shoes/app.h index 5f6ea0dc..ad44c353 100644 --- a/shoes/app.h +++ b/shoes/app.h @@ -56,6 +56,8 @@ typedef struct _shoes_app { VALUE menubar; int monitor; // -1 means default int id; // from global serial number + double touch_x; + double touch_y; } shoes_app; #ifdef NEW_MACRO_APP diff --git a/shoes/native/gtk.c b/shoes/native/gtk.c index 94237296..252a48e4 100644 --- a/shoes/native/gtk.c +++ b/shoes/native/gtk.c @@ -843,24 +843,62 @@ static gboolean shoes_app_gtk_keypress(GtkWidget *widget, GdkEventKey *event, gp return FALSE; } -static gboolean shoes_canvas_gtk_touch(GtkWidget *widget, GdkEvent *event, gpointer data) { - shoes_app *app = (shoes_app *)data; - char *evt_type; +// data arg is a VALUE - an App or a Canvas +static gboolean shoes_canvas_gtk_touch(GtkWidget *widget, GdkEventTouch *event, gpointer data) { + shoes_app *app; + shoes_canvas *canvas; + if (data == NULL || (VALUE)data == Qnil) { + fprintf(stderr," Touch: NIL for app/canavas\n"); + return FALSE; + } + if (rb_obj_is_kind_of((VALUE)data, cApp)) { + TypedData_Get_Struct((VALUE)data, shoes_app, &shoes_app_type, app); + TypedData_Get_Struct(app->canvas, shoes_canvas, &shoes_canvas_type, canvas); + } else if (rb_obj_is_kind_of((VALUE)data, cCanvas)) { + TypedData_Get_Struct((VALUE)data, shoes_canvas, &shoes_canvas_type, canvas); + } else { + return FALSE; + } + // Is the scrollbar showing ? + shoes_slot_gtk *slot = canvas->slot; + GtkWidget *sb = slot->vscroll; + if (sb == NULL) { + fprintf(stderr, "Touch: No scrollbar\n"); + return FALSE; + } if (event->type == GDK_TOUCH_BEGIN) { - evt_type = "Touch Begin: "; + //fprintf(stderr, "Touch Begin:\n"); + app->touch_x = event->x; + app->touch_y = event->y; } else if (event->type == GDK_TOUCH_END) { - evt_type = "Touch End: "; + app->touch_x = 0.0; + app->touch_y = 0.0; + //fprintf(stderr, "Touch End:\n"); } else if (event->type == GDK_TOUCH_UPDATE) { - evt_type == "Touch Update: "; + GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(sb)); + gdouble adjv = gtk_adjustment_get_value(adj); + //gdouble dy = (int)event->y - app->touch_y; + gdouble dy = (gdouble)app->touch_y - event->y; + gdouble newp = adjv + dy; + if (dy) + gtk_adjustment_set_value(adj, newp); + //fprintf(stderr, "Touch_Update: %f: %f %f\n", adjv, event->y, dy); } else if (event->type == GDK_TOUCH_CANCEL) { - evt_type == "Touch Cancel: "; + app->touch_x = 0.0; + app->touch_y = 0.0; + fprintf(stderr, "Touch Cancel:\n"); } else { - evt_type == "Touch UNKNOWN"; + fprintf(stderr, "Touch UNKNOWN\n"); } - fprintf(stderr, "Dispatch %s\n", evt_type); - return TRUE; // We did something with the event. + return FALSE; // false => We did not handle the event? } +static void shoes_gtk_app_drag_begin(GtkGestureDrag *gesture, + gdouble x, gdouble y, gpointer data) { + shoes_app *app = (shoes_app *)data; + fprintf(stderr, "Drag Begin, %d,%d\n", (int)x, (int)y); + } + static gboolean shoes_app_gtk_quit(GtkWidget *widget, GdkEvent *event, gpointer data) { shoes_app *app = (shoes_app *)data; if (shoes_app_remove(app)) @@ -1413,7 +1451,14 @@ shoes_code shoes_native_app_open(shoes_app *app, char *path, int dialog, shoes_s G_CALLBACK(shoes_app_gtk_quit), app); g_signal_connect(G_OBJECT(window), "configure-event", // bug #349 G_CALLBACK(shoes_app_gtk_configure_event), app); - +#if 1 + g_signal_connect(G_OBJECT(window), "touch-event", + G_CALLBACK(shoes_canvas_gtk_touch), (gpointer)app->self); +#endif +#if 0 + g_signal_connect(GTK_WIDGET(window), "drag-begin", + G_CALLBACK(shoes_gtk_app_drag_begin), app); +#endif if (app->fullscreen) shoes_native_app_fullscreen(app, 1); gtk_window_set_decorated(GTK_WINDOW(window), app->decorated); @@ -1481,8 +1526,10 @@ void shoes_native_slot_init(VALUE c, SHOES_SLOT_OS *parent, int x, int y, int wi G_CALLBACK(shoes_canvas_gtk_paint), (gpointer)c); g_signal_connect(G_OBJECT(slot->oscanvas), "size-allocate", G_CALLBACK(shoes_canvas_gtk_size), (gpointer)c); +#if 1 g_signal_connect(G_OBJECT(slot->oscanvas), "touch-event", G_CALLBACK(shoes_canvas_gtk_touch), (gpointer)c); +#endif INFO("shoes_native_slot_init(%lu)\n", c); if (toplevel) { @@ -2140,11 +2187,13 @@ void shoes_slot_init_menu(VALUE c, SHOES_SLOT_OS *parent, int x, int y, int widt #endif g_signal_connect(GTK_WIDGET(slot->oscanvas), "draw", G_CALLBACK(shoes_canvas_gtk_paint), (gpointer)c); +#if 1 + g_signal_connect(GTK_WIDGET(slot->oscanvas), "touch-event", + G_CALLBACK(shoes_canvas_gtk_touch), (gpointer)c); +#endif #ifdef GTK_CANVAS_SIZE g_signal_connect(GTK_WIDGET(slot->oscanvas), "size-allocate", G_CALLBACK(shoes_gtk_content_size), (gpointer)c); - g_signal_connect(GTK_WIDGET(slot->oscanvas), "touch-event", - G_CALLBACK(shoes_canvas_gtk_touch), (gpointer)c); #endif INFO("shoes_slot_init_menu(%lu)\n", c); @@ -2166,7 +2215,6 @@ void shoes_slot_init_menu(VALUE c, SHOES_SLOT_OS *parent, int x, int y, int widt g_signal_connect(GTK_WIDGET(slot->vscroll), "value-changed", G_CALLBACK(shoes_canvas_gtk_scroll), (gpointer)c); gtk_fixed_put(GTK_FIXED(slot->oscanvas), slot->vscroll, -100, -100); - gtk_widget_set_size_request(slot->oscanvas, width, height); if (!toplevel) @@ -2213,6 +2261,19 @@ int shoes_gtk_optbox_height(shoes_app *app, int height) { return hgt; } +static void +shoes_gtk_swipe_gesture_swept (GtkGestureSwipe *gesture, + gdouble velocity_x, + gdouble velocity_y, + gpointer *data) +{ + shoes_app *app = (shoes_app *)data; + gdouble swipe_x = velocity_x / 10; + gdouble swipe_y = velocity_y / 10; + //gtk_widget_queue_draw (widget); + fprintf(stderr, "Gesture: swipe\n"); +} + /* * All apps windows can have a menubur and then the old shoes space below. * it's optional and the default is no menu for backwards compatibilty @@ -2332,7 +2393,22 @@ shoes_code shoes_native_app_open_menu(shoes_app *app, char *path, int dialog, sh G_CALLBACK(shoes_app_gtk_quit), app); g_signal_connect(GTK_WINDOW(window), "configure-event", // bug #349 G_CALLBACK(shoes_app_gtk_configure_menu), app); - +#if 1 + g_signal_connect(GTK_WIDGET(window), "touch-event", + G_CALLBACK(shoes_canvas_gtk_touch), app); +#endif +#if 0 + g_signal_connect(GTK_WIDGET(window), "drag-begin", + G_CALLBACK(shoes_gtk_app_drag_begin), app); +#endif +#if 0 + // swipe setup + GtkGesture *gesture = gtk_gesture_swipe_new (shoes_window); + g_signal_connect (gesture, "swipe", + G_CALLBACK (shoes_gtk_swipe_gesture_swept), app); + gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), + GTK_PHASE_CAPTURE ); +#endif if (app->fullscreen) shoes_native_app_fullscreen(app, 1); gtk_window_set_decorated(GTK_WINDOW(window), app->decorated); diff --git a/shoes/native/gtk/gtkfixedalt.c b/shoes/native/gtk/gtkfixedalt.c index d2a56610..b9a44fc3 100644 --- a/shoes/native/gtk/gtkfixedalt.c +++ b/shoes/native/gtk/gtkfixedalt.c @@ -115,3 +115,4 @@ gtkfixed_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) fprintf(stderr,"fixed_pref_hgt %d, %d\n",*minimal,*natural); #endif } +