From d65fbe084a91d180d17767314f4e34b7456e8436 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 3 Apr 2015 20:57:45 +0000
Subject: Defined a preferred size for views and reacted on scroll events.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@500 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                     |  11 +++
 src/glibext/gcodebuffer.c     |   2 +-
 src/gtkext/gtkbufferview.c    |  61 +++++++------
 src/gtkext/gtkgraphview.c     | 201 +++++++++---------------------------------
 src/gtkext/gtkviewpanel-int.h |  12 ++-
 src/gtkext/gtkviewpanel.c     |  67 +++++++++++++-
 6 files changed, 157 insertions(+), 197 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f5359b5..fad37ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 15-04-03  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/glibext/gcodebuffer.c:
+	Reactivate a cached version of computed widths.
+
+	* src/gtkext/gtkbufferview.c:
+	* src/gtkext/gtkgraphview.c:
+	* src/gtkext/gtkviewpanel.c:
+	* src/gtkext/gtkviewpanel-int.h:
+	Define a preferred size for views and react on scroll events.
+
+15-04-03  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/analysis/disass/output.c:
 	Set an empty size for lines showing a routine label.
 
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index b504473..1d42b35 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -1184,7 +1184,7 @@ gint g_buffer_view_get_width(GBufferView *view, const bool *display)
     gint full_width;                        /* Calcul selon les fusions    */
     BufferLineColumn i;                     /* Boucle de parcours          */
 
-    //if (!WIDTHS_CACHED(view))
+    if (!WIDTHS_CACHED(view))
         g_buffer_view_compute_required_widths(view, display);
 
     result = view->left_text;
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index be75d2f..0d74176 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -58,6 +58,9 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint
 /* Détermine la taille des bonds lors de défilements. */
 static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *);
 
+/* Réagit à un défilement chez une barre associée au composant. */
+static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *, GtkAdjustment *, GtkOrientation);
+
 /* Indique la position d'affichage d'une adresse donnée. */
 static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
 
@@ -92,28 +95,6 @@ static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *);
 G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_VIEW_PANEL)
 
 
-/*
-  void               (* get_preferred_height)           (GtkWidget       *widget,
-                                                         gint            *minimum_height,
-                                                         gint            *natural_height);
-
-  void               (* get_preferred_width_for_height) (GtkWidget       *widget,
-                                                         gint             height,
-                                                         gint            *minimum_width,
-                                                         gint            *natural_width);
-  void               (* get_preferred_width)            (GtkWidget       *widget,
-                                                         gint            *minimum_width,
-                                                         gint            *natural_width);
-*/
-
-
-void get_preferred(GtkWidget *widget, gint *minimum, gint *natural)
-{
-    if (minimum != NULL) *minimum = 500;
-    if (natural != NULL) *natural = 500;
-}
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : class = classe GTK à initialiser.                            *
@@ -139,13 +120,9 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
     widget_class->draw = gtk_buffer_view_draw;
     widget_class->key_press_event = gtk_buffer_view_key_press;
 
-
-    widget_class->get_preferred_height = get_preferred;
-    widget_class->get_preferred_width = get_preferred;
-
-
-    panel_class->compute_size = (compute_requested_size)gtk_buffer_view_compute_requested_size;
-    panel_class->compute_inc = (compute_scroll_inc)gtk_buffer_view_compute_scroll_inc;
+    panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_view_compute_requested_size;
+    panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_view_compute_scroll_inc;
+    panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value;
     panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates;
     panel_class->get_position = (get_view_position_fc)gtk_buffer_view_get_position;
 
@@ -578,6 +555,32 @@ static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, G
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : view        = panneau d'affichage concerné.                  *
+*                adj         = défilement dont une valeur a changé.           *
+*                orientation = indication sur le défilement à traiter.        *
+*                                                                             *
+*  Description : Réagit à un défilement chez une barre associée au composant. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkAdjustment *adj, GtkOrientation orientation)
+{
+    GtkWidget *widget;                      /* Autre vision du composant   */
+
+    widget = GTK_WIDGET(view);
+
+    if (gtk_widget_get_realized(widget))
+        gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, false);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : view  = composant GTK à consulter.                           *
 *                addr  = adresse à présenter à l'écran.                       *
 *                x     = position horizontale au sein du composant. [OUT]     *
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 1f8d51c..cde919c 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -69,16 +69,15 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *);
 /* Initialise une instance d'afficheur de code en graphique. */
 static void gtk_graph_view_init(GtkGraphView *);
 
-/* S'adapte à la surface concédée par le composant parent. */
-static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
+/* Indique les dimensions de travail du composant d'affichage. */
+static void gtk_graph_view_compute_requested_size(GtkGraphView *, gint *, gint *);
+
+/* Réagit à un défilement chez une barre associée au composant. */
+static void gtk_graph_view_adjust_scroll_value(GtkGraphView *, GtkAdjustment *, GtkOrientation);
 
 /*  Met à jour l'affichage de la vue sous forme graphique. */
 static gboolean gtk_graph_view_draw(GtkWidget *, cairo_t *, GtkGraphView *);
 
-
-/* Indique les dimensions de travail du composant d'affichage. */
-static void gtk_graph_view_compute_requested_size(GtkGraphView *, gint *, gint *);
-
 /* Actualise les besoins internes avant un redimensionnement. */
 static void gtk_graph_view_prepare_resize(GtkGraphView *);
 
@@ -126,9 +125,8 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class)
     widget_class = GTK_WIDGET_CLASS(class);
     panel_class = GTK_VIEW_PANEL_CLASS(class);
 
-    widget_class->size_allocate = gtk_graph_view_size_allocate;
-
-    panel_class->compute_size = (compute_requested_size)gtk_graph_view_compute_requested_size;
+    panel_class->compute_size = (compute_requested_size_fc)gtk_graph_view_compute_requested_size;
+    panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_view_adjust_scroll_value;
     panel_class->define = (define_address_fc)gtk_graph_view_define_main_address;
     panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
 
@@ -146,7 +144,7 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class)
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-#include "easygtk.h"////////////
+
 static void gtk_graph_view_init(GtkGraphView *view)
 {
     GtkViewPanel *viewpanel;                /* Instance parente #1         */
@@ -174,161 +172,14 @@ static void gtk_graph_view_init(GtkGraphView *view)
 
     gtk_widget_show(GTK_WIDGET(view->support));
 
-    /*
-    gdk_color_white(gtk_widget_get_colormap(GTK_WIDGET(view->support)), &white);
-    gtk_widget_modify_bg(GTK_WIDGET(view->support), GTK_STATE_NORMAL, &white);
-    */
-
     gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->support), 0, 0);
 
-    //gtk_widget_size_allocate(view->support, (GtkAllocation []){ { 200, 200, 500, 500 } });
-
-#if 0
-    do
-    {
-        GtkWidget *btn;
-
-        btn = qck_create_button(NULL, NULL, "caption 0", NULL, NULL);
-        gtk_fixed_put(GTK_FIXED(view), btn, 10, 10);
-
-
-        btn = qck_create_button(NULL, NULL, "caption 1", NULL, NULL);
-        gtk_fixed_put(GTK_FIXED(view->support), btn, 100, 100);
-
-
-
-    }
-    while (0);
-#endif
-
     //view->mutex = g_mutex_new();
     //view->cond = g_cond_new();
 
 }
 
 
-
-
-
-
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view       = composant GTK à mettre à jour.                  *
-*                allocation = étendue accordée à la vue.                      *
-*                                                                             *
-*  Description : S'adapte à la surface concédée par le composant parent.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
-    gpointer fixed_class;                   /* Classe parente              */
-    GtkViewPanel *panel;                    /* Autre version du composant  */
-    GtkAllocation valloc;                   /* Surface utilisable          */
-    GtkRequisition req;                     /* Taille demandée             */
-    GtkGraphView *view;                     /* Autre vision du composant   */
-    GdkWindow *window;                      /* Fenêtre associée au support */
-    gboolean changed;                       /* Changement de valeur ?      */
-
-
-    printf("GRAPH SIZE ALLOC :: (%d ; %d) - (%d ; %d)\n",
-           allocation->x, allocation->y,
-           allocation->width, allocation->height);
-
-
-    GTK_WIDGET_CLASS(gtk_graph_view_parent_class)->size_allocate(widget, allocation);
-
-
-    /* Mise à jour GTK */
-
-    /*
-    fixed_class = g_type_class_peek_parent(GTK_GRAPH_VIEW_GET_CLASS(widget));
-    fixed_class = g_type_class_peek_parent(fixed_class);
-
-    GTK_WIDGET_CLASS(fixed_class)->size_allocate(widget, allocation);
-    */
-
-
-
-    panel = GTK_VIEW_PANEL(widget);
-
-    /*
-    if (panel->hadjustment == NULL || panel->vadjustment == NULL)
-        return;
-    */
-
-    // !!!! moved !!! gtk_view_panel_compute_allocation(panel, &valloc);
-
-    gtk_widget_get_preferred_size(widget, NULL, &req);
-
-    /* Correction de la taille du support */
-
-    view = GTK_GRAPH_VIEW(widget);
-    window = gtk_widget_get_window(GTK_WIDGET(view->support));
-
-
-
-    gtk_widget_size_allocate(view->support, (GtkAllocation []){ { 0, 0, 1500, 1500 } });
-
-    //gdk_window_resize(window, 500, 500);
-
-    /*
-    printf(" --> cmp :: (%d ; %d) vs (%d ; %d)\n",
-           gdk_window_get_width(window), gdk_window_get_height(window),
-           req.width, req.height);
-    */
-    /*
-    if (gdk_window_get_width(window) != req.width || gdk_window_get_height(window) != req.height)
-        gdk_window_resize(window, req.width, req.height);
-    */
-
-    return;
-
-
-    /* Défilement horizontal */
-
-    gtk_adjustment_set_page_size(panel->hadjustment, valloc.width);
-    gtk_adjustment_set_step_increment(panel->hadjustment, valloc.width * 0.1);
-    gtk_adjustment_set_page_increment(panel->hadjustment, valloc.width * 0.9);
-
-    gtk_adjustment_set_upper(panel->hadjustment, MAX(req.width, valloc.width));
-
-    // !!!! moved !!! gtk_view_panel_reclamp_adjustment(panel->hadjustment, &changed);
-
-    gtk_adjustment_changed(panel->hadjustment);
-
-    if (changed)
-        gtk_adjustment_value_changed(panel->hadjustment);
-
-    /* Défilement vertical */
-
-    gtk_adjustment_set_page_size(panel->vadjustment, valloc.width);
-    gtk_adjustment_set_step_increment(panel->vadjustment, valloc.width * 0.1);
-    gtk_adjustment_set_page_increment(panel->vadjustment, valloc.width * 0.9);
-
-    gtk_adjustment_set_upper(panel->vadjustment, MAX(req.height, valloc.height));
-
-    // !!!! moved !!! gtk_view_panel_reclamp_adjustment(panel->vadjustment, &changed);
-
-    gtk_adjustment_changed(panel->vadjustment);
-
-    if (changed)
-        gtk_adjustment_value_changed(panel->vadjustment);
-
-}
-
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : view   = composant GTK à consulter.                          *
@@ -362,6 +213,34 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view        = panneau d'affichage concerné.                  *
+*                adj         = défilement dont une valeur a changé.           *
+*                orientation = indication sur le défilement à traiter.        *
+*                                                                             *
+*  Description : Réagit à un défilement chez une barre associée au composant. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment *adj, GtkOrientation orientation)
+{
+    gint fake_x;                            /* Abscisse virtuelle          */
+    gint fake_y;                            /* Ordonnée virtuelle          */
+
+    fake_x = 0;
+    fake_y = 0;
+    gtk_buffer_view_compute_fake_coord(view, &fake_x, &fake_y);
+
+    printf("fake :: (%d ; %d)\n", fake_x, fake_y);
+
+    gtk_fixed_move(GTK_FIXED(view), GTK_WIDGET(view->support), fake_x, -fake_y);
+
+}
 
 
 /******************************************************************************
@@ -445,6 +324,8 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
     GBinRoutine **routines;                 /* Liste des routines trouvées */
     size_t routines_count;                  /* Nombre de ces routines      */
     size_t i;                               /* Boucle de parcours          */
+    gint width;                             /* Largeur idéale du composant */
+    gint height;                            /* Hauteur idéale du composant */
 
     if (view->routine == NULL)
         need_update = true;
@@ -493,6 +374,9 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
 
         }
 
+        gtk_graph_view_compute_requested_size(view, &width, &height);
+        gtk_widget_size_allocate(view->support, (GtkAllocation []){ { 0, 0, width, height } });
+
         change_editor_items_current_view_content(GTK_VIEW_PANEL(view));
 
     }
@@ -619,8 +503,7 @@ void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocati
         gtk_container_remove(GTK_CONTAINER(parent), widget);
     }
 
-    //gtk_fixed_put(view->support, widget, alloc->x, alloc->y);
-    gtk_fixed_put(view->support, widget, i * 200, i * 150);
+    gtk_fixed_put(view->support, widget, alloc->x, alloc->y);
 
     if (parent != NULL)
         g_object_unref(G_OBJECT(widget));
diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h
index d51c637..07ce6e9 100644
--- a/src/gtkext/gtkviewpanel-int.h
+++ b/src/gtkext/gtkviewpanel-int.h
@@ -34,10 +34,13 @@
 
 
 /* Indique les dimensions de travail du composant d'affichage. */
-typedef void (* compute_requested_size) (GtkViewPanel *, gint *, gint *);
+typedef void (* compute_requested_size_fc) (GtkViewPanel *, gint *, gint *);
 
 /* Détermine la taille des bonds lors de défilements. */
-typedef void (* compute_scroll_inc) (GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *);
+typedef void (* compute_scroll_inc_fc) (GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *);
+
+/* Réagit à un défilement chez une barre associée au composant. */
+typedef void (* adjust_scroll_value_fc) (GtkViewPanel *, GtkAdjustment *, GtkOrientation);
 
 /* Prend acte de l'association d'un binaire chargé. */
 typedef void (* attach_binary_fc) (GtkViewPanel *, GLoadedBinary *);
@@ -87,8 +90,9 @@ struct _GtkViewPanelClass
 {
     GtkFixedClass parent;                   /* A laisser en premier        */
 
-    compute_requested_size compute_size;    /* Calcul de la taille requise */
-    compute_scroll_inc compute_inc;         /* Calcul des bonds            */
+    compute_requested_size_fc compute_size; /* Calcul de la taille requise */
+    compute_scroll_inc_fc compute_inc;      /* Calcul des bonds            */
+    adjust_scroll_value_fc adjust;          /* Réaction à un défilement    */
     define_address_fc define;               /* Centrage sur une partie     */
     get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */
     get_view_position_fc get_position;      /* Indications sur la position */
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 3c8febd..1496056 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -53,6 +53,12 @@ static void gtk_view_panel_size_allocate(GtkWidget *, GtkAllocation *);
 /* Met à jour l'affichage du composant d'affichage. */
 static gboolean gtk_view_panel_draw(GtkWidget *, cairo_t *);
 
+/* Fournit la hauteur idéale pour le composant d'affichage. */
+static void gtk_view_panel_get_preferred_height(GtkWidget *, gint *, gint *);
+
+/* Fournit la largeur idéale pour le composant d'affichage. */
+static void gtk_view_panel_get_preferred_width(GtkWidget *, gint *, gint *);
+
 /* Détermine la taille des bonds lors de défilements. */
 static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *);
 
@@ -116,6 +122,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)
     widget_class->realize = gtk_view_panel_realize;
     widget_class->size_allocate = gtk_view_panel_size_allocate;
     widget_class->draw = gtk_view_panel_draw;
+    widget_class->get_preferred_height = gtk_view_panel_get_preferred_height;
+    widget_class->get_preferred_width = gtk_view_panel_get_preferred_width;
 
     panel_class->compute_inc = gtk_view_panel_compute_scroll_inc;
 
@@ -379,6 +387,58 @@ static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : widget  = composant GTK à examiner.                          *
+*                minimum = hauteur minimale à préciser ou NULL. [OUT]         *
+*                natural = hauteur idéale à préciser ou NULL. [OUT]           *
+*                                                                             *
+*  Description : Fournit la hauteur idéale pour le composant d'affichage.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_view_panel_get_preferred_height(GtkWidget *widget, gint *minimum, gint *natural)
+{
+    gint req;                               /* Dimension requise           */
+
+    GTK_VIEW_PANEL_GET_CLASS(widget)->compute_size(GTK_VIEW_PANEL(widget), NULL, &req);
+
+    if (minimum != NULL) *minimum = req;
+    if (natural != NULL) *natural = req;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget  = composant GTK à examiner.                          *
+*                minimum = largeur minimale à préciser ou NULL. [OUT]         *
+*                natural = largeur idéale à préciser ou NULL. [OUT]           *
+*                                                                             *
+*  Description : Fournit la largeur idéale pour le composant d'affichage.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_view_panel_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural)
+{
+    gint req;                               /* Dimension requise           */
+
+    GTK_VIEW_PANEL_GET_CLASS(widget)->compute_size(GTK_VIEW_PANEL(widget), &req, NULL);
+
+    if (minimum != NULL) *minimum = req;
+    if (natural != NULL) *natural = req;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     *
 *                size        = taille de l'espace dans la direction donnée.   *
 *                orientation = indication sur le défilement à traiter.        *
@@ -607,12 +667,11 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation
 
 static void gtk_view_panel_adjustment_value_changed(GtkAdjustment *adj, GtkViewPanel *panel)
 {
-    GtkWidget *widget;                      /* Autre vision du composant   */
+    GtkOrientation orientation;             /* Indification de la barre    */
 
-    widget = GTK_WIDGET(panel);
+    orientation = (adj == panel->hadjustment ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
 
-    if (gtk_widget_get_realized(widget))
-        gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, false);
+    GTK_VIEW_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation);
 
 }
 
-- 
cgit v0.11.2-87-g4458