From bbe0b6c2d6e19eeffbcabf3ea469b63c5f33a800 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 2 May 2016 22:02:21 +0200
Subject: Scrolled the graphic view using mouse clicks and moves on the
 background.

---
 ChangeLog                 |   5 ++
 src/gtkext/gtkgraphview.c | 156 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 160 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index add1e17..91fd10f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 16-05-02  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/gtkext/gtkgraphview.c:
+	Scroll the graphic view using mouse clicks and moves on the background.
+
+16-05-02  Cyrille Bagard <nocbos@gmail.com>
+
 	* configure.ac:
 	Warn in case of missing analyzer/parser generator.
 
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 0c680fa..368792b 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -51,6 +51,12 @@ struct _GtkGraphView
 
     GGraphLayout *layout;                   /* Disposition en graphique    */
 
+    gdouble start_x;                        /* Abscisse du point de souris */
+    gdouble start_y;                        /* Ordonnée du point de souris */
+    bool big_enough;                        /* Capacités de déplacement ?  */
+    gdouble ref_h;                          /* Position horizontale de ref.*/
+    gdouble ref_v;                          /* Position verticale de ref.  */
+
 };
 
 /* Composant d'affichage sous forme graphique (classe) */
@@ -77,6 +83,15 @@ static void gtk_graph_view_adjust_scroll_value(GtkGraphView *, GtkAdjustment *,
 /*  Met à jour l'affichage de la vue sous forme graphique. */
 static gboolean gtk_graph_view_draw(GtkWidget *, cairo_t *, GtkGraphView *);
 
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_graph_view_button_press(GtkWidget *, GdkEventButton *, GtkGraphView *);
+
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_graph_view_button_release(GtkWidget *, GdkEventButton *, GtkGraphView *);
+
+/* Assure la suivi des déplacements de souris sur le composant. */
+static gboolean gtk_graph_view_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphView *);
+
 /* Actualise les besoins internes avant un redimensionnement. */
 static void gtk_graph_view_prepare_resize(GtkGraphView *);
 
@@ -178,6 +193,16 @@ static void gtk_graph_view_init(GtkGraphView *view)
     g_signal_connect(G_OBJECT(view->support), "draw",
                      G_CALLBACK(gtk_graph_view_draw), view);
 
+    g_signal_connect(G_OBJECT(view->support), "button-press-event",
+                      G_CALLBACK(gtk_graph_view_button_press), view);
+    g_signal_connect(G_OBJECT(view->support), "button-release-event",
+                      G_CALLBACK(gtk_graph_view_button_release), view);
+    g_signal_connect(G_OBJECT(view->support), "motion-notify-event",
+                      G_CALLBACK(gtk_graph_view_motion_notify), view);
+
+    gtk_widget_add_events(view->support,
+                          GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
     gtk_widget_show(view->support);
 
     gtk_fixed_put(GTK_FIXED(view), view->support, 0, 0);
@@ -262,7 +287,7 @@ static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : widget = composant GTK à redessiner.                         *
-*                cr  = contexte graphique associé à l'événement.              *
+*                cr     = contexte graphique associé à l'événement.           *
 *                view   = support maître à consulter.                         *
 *                                                                             *
 *  Description : Met à jour l'affichage de la vue sous forme graphique.       *
@@ -285,6 +310,135 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                view   = support maître à consulter.                         *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur le composant.      *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view)
+{
+    gboolean result;                        /* Poursuite à faire suivre    */
+    GtkScrolledWindow *support;             /* Support défilant associé    */
+    GtkAdjustment *hadj;                    /* Gestionnaire du défilement  */
+    GtkAdjustment *vadj;                    /* Gestionnaire du défilement  */
+    GdkCursor *cursor;                      /* Pointeur pour la surface    */
+
+    result = FALSE;
+
+    if (event->button == 1)
+    {
+        support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view)));
+
+        hadj = gtk_scrolled_window_get_hadjustment(support);
+        vadj = gtk_scrolled_window_get_vadjustment(support);
+
+        view->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj)
+                            || gtk_adjustment_get_upper(vadj) > gtk_adjustment_get_page_size(vadj));
+
+        if (view->big_enough)
+        {
+            view->start_x = event->x_root;
+            view->start_y = event->y_root;
+
+            view->ref_h = gtk_adjustment_get_value(hadj);
+            view->ref_v = gtk_adjustment_get_value(vadj);
+
+            cursor = gdk_cursor_new(GDK_FLEUR);
+            gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
+            g_object_unref(G_OBJECT(cursor));
+
+            result = TRUE;
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                view   = support maître à consulter.                         *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur le composant.      *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view)
+{
+    if (event->button == 1 && view->big_enough)
+        gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                view   = support maître à consulter.                         *
+*                                                                             *
+*  Description : Assure la suivi des déplacements de souris sur le composant. *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphView *view)
+{
+    gdouble diff_x;                         /* Evolution sur les abscisses */
+    gdouble diff_y;                         /* Evolution sur les ordonnées */
+    GtkScrolledWindow *support;             /* Support défilant associé    */
+    GtkAdjustment *hadj;                    /* Gestionnaire du défilement  */
+    GtkAdjustment *vadj;                    /* Gestionnaire du défilement  */
+    gdouble value;                          /* Nouvelle valeur bornée      */
+
+    if (event->state & GDK_BUTTON1_MASK && view->big_enough)
+    {
+        diff_x = view->start_x - event->x_root;
+        diff_y = view->start_y - event->y_root;
+
+        support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view)));
+
+        hadj = gtk_scrolled_window_get_hadjustment(support);
+        vadj = gtk_scrolled_window_get_vadjustment(support);
+
+        value = CLAMP(view->ref_h + diff_x, gtk_adjustment_get_lower(hadj),
+                      gtk_adjustment_get_upper(hadj) - gtk_adjustment_get_page_size(hadj));
+        gtk_adjustment_set_value(hadj, value);
+
+        value = CLAMP(view->ref_v + diff_y, gtk_adjustment_get_lower(vadj),
+                      gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj));
+        gtk_adjustment_set_value(vadj, value);
+
+    }
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : view = composant GTK à mettre à jour.                        *
 *                                                                             *
 *  Description : Actualise les besoins internes avant un redimensionnement.   *
-- 
cgit v0.11.2-87-g4458