summaryrefslogtreecommitdiff
path: root/src/gtkext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-09-10 21:02:04 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-09-10 21:02:04 (GMT)
commitbe1f2f147e8ce15f20ec4de439088714ffa50e8a (patch)
treeeab8ad76fa6f39781568fae13fb7967cdedbd45a /src/gtkext
parentc03635088f26a18cdbd42c2528f00b9ccd8591d9 (diff)
Fixed and improved the rendering of view panels.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@401 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext')
-rw-r--r--src/gtkext/gtkbufferview.c227
-rw-r--r--src/gtkext/gtkgraphview.c159
-rw-r--r--src/gtkext/gtkviewpanel-int.h21
-rw-r--r--src/gtkext/gtkviewpanel.c399
4 files changed, 491 insertions, 315 deletions
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index 032fcf9..8e1a9c7 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -46,21 +46,15 @@ static gboolean gtk_buffer_view_focus(GtkWidget *, GtkDirectionType);
/* Assure la gestion des clics de souris sur le composant. */
static gboolean gtk_buffer_view_button_press(GtkWidget *, GdkEventButton *);
-/* Fournit la hauteur de composant requise pour un plein rendu. */
-static void gtk_buffer_view_get_preferred_height(GtkWidget *, gint *, gint *);
-
-/* Fournit la largeur de composant requise pour un plein rendu. */
-static void gtk_buffer_view_get_preferred_width(GtkWidget *, gint *, gint *);
-
-/* S'adapte à la surface concédée par le composant parent. */
-static void gtk_buffer_view_size_allocate(GtkWidget *, GtkAllocation *);
-
/* Met à jour l'affichage de la visualisation de code buffer. */
static gboolean gtk_buffer_view_draw(GtkWidget *, cairo_t *);
/* Prend en compte une frappe de touche sur le composant. */
static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *);
+/* Indique les dimensions de travail du composant d'affichage. */
+static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *);
+
/* Indique la position d'affichage d'une adresse donnée. */
static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *);
@@ -104,17 +98,18 @@ G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_VIEW_PANEL)
static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
{
GtkWidgetClass *widget_class; /* Classe version Widget */
+ GtkViewPanelClass *panel_class; /* Classe parente */
widget_class = GTK_WIDGET_CLASS(class);
+ panel_class = GTK_VIEW_PANEL_CLASS(class);
widget_class->focus = gtk_buffer_view_focus;
widget_class->button_press_event = gtk_buffer_view_button_press;
- widget_class->get_preferred_height = gtk_buffer_view_get_preferred_height;
- widget_class->get_preferred_width = gtk_buffer_view_get_preferred_width;
- widget_class->size_allocate = gtk_buffer_view_size_allocate;
widget_class->draw = gtk_buffer_view_draw;
widget_class->key_press_event = gtk_buffer_view_key_press;
+ panel_class->compute_size = (compute_requested_size)gtk_buffer_view_compute_requested_size;
+
g_signal_new("caret-moved",
GTK_TYPE_BUFFER_VIEW,
G_SIGNAL_RUN_LAST,
@@ -325,145 +320,6 @@ void gtk_buffer_view_compute_real_coord(GtkBufferView *view, gint *x, gint *y)
/******************************************************************************
* *
-* Paramètres : widget = composant GTK à consulter. *
-* minimal = taille minimale. [OUT] *
-* natural = taille idéale. [OUT] *
-* *
-* Description : Fournit la hauteur de composant requise pour un plein rendu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void gtk_buffer_view_get_preferred_height(GtkWidget *widget, gint *minimal, gint *natural)
-{
- GtkBufferView *view; /* Autre version du composant */
-
- view = GTK_BUFFER_VIEW(widget);
-
- if (view->buffer_view != NULL)
- *minimal = g_buffer_view_get_height(view->buffer_view);
- else
- *minimal = 0;
-
- *natural = *minimal;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : widget = composant GTK à consulter. *
-* minimal = taille minimale. [OUT] *
-* natural = taille idéale. [OUT] *
-* *
-* Description : Fournit la largeur de composant requise pour un plein rendu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void gtk_buffer_view_get_preferred_width(GtkWidget *widget, gint *minimal, gint *natural)
-{
- GtkBufferView *view; /* Autre version du composant */
-
- view = GTK_BUFFER_VIEW(widget);
-
- if (view->buffer_view != NULL)
- *minimal = g_buffer_view_get_width(view->buffer_view,
- *GTK_VIEW_PANEL(view)->display_phys,
- *GTK_VIEW_PANEL(view)->display_addr,
- *GTK_VIEW_PANEL(view)->display_code);
- else
- *minimal = 0;
-
- *natural = *minimal;
-
-}
-
-
-/******************************************************************************
-* *
-* 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_buffer_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- GtkViewPanel *panel; /* Autre version du composant */
- GtkBufferView *view; /* Encore une autre version */
- gint width; /* Largeur de l'objet actuelle */
- gint height; /* Hauteur de l'objet actuelle */
- GtkAllocation valloc; /* Surface utilisable */
- gboolean changed; /* Changement de valeur ? */
-
- /* Mise à jour GTK */
-
- gtk_widget_set_allocation(widget, allocation);
-
- if (gtk_widget_get_realized(widget))
- gdk_window_move_resize(gtk_widget_get_window(widget),
- allocation->x, allocation->y,
- allocation->width, allocation->height);
-
- panel = GTK_VIEW_PANEL(widget);
-
- if (panel->hadjustment == NULL || panel->vadjustment == NULL)
- return;
-
- view = GTK_BUFFER_VIEW(widget);
-
- width = g_buffer_view_get_width(view->buffer_view, *panel->display_phys, *panel->display_addr, *panel->display_code);
- height = g_buffer_view_get_height(view->buffer_view);
-
- gtk_view_panel_compute_allocation(panel, &valloc);
-
- /* 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(width, valloc.width));
-
- 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.height);
- gtk_adjustment_set_step_increment(panel->vadjustment, view->line_height);
- gtk_adjustment_set_page_increment(panel->vadjustment, view->line_height * 10.0);
-
- gtk_adjustment_set_upper(panel->vadjustment, MAX(height, valloc.height));
-
- gtk_view_panel_reclamp_adjustment(panel->vadjustment, &changed);
-
- gtk_adjustment_changed(panel->vadjustment);
-
- if (changed)
- gtk_adjustment_value_changed(panel->vadjustment);
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : widget = composant GTK à redessiner. *
* cr = contexte graphique associé à l'événement. *
* *
@@ -479,38 +335,38 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
{
GtkBufferView *view; /* Autre version du composant */
GtkViewPanel *pview; /* Autre version du composant */
+ GdkWindow *window; /* Fenêtre à redessiner */
cairo_region_t *region; /* Région visible à redessiner */
cairo_rectangle_int_t area; /* Surface correspondante */
+ GtkStyleContext *context; /* Contexte du thème actuel */
gint fake_x; /* Abscisse virtuelle */
gint fake_y; /* Ordonnée virtuelle */
- GtkStyleContext *context; /* Contexte du thème actuel */
- GdkRGBA color; /* Couleur du curseur */
view = GTK_BUFFER_VIEW(widget);
widget = GTK_WIDGET(view);
pview = GTK_VIEW_PANEL(widget);
- region = gdk_window_get_visible_region(gtk_widget_get_window(widget));
+ window = gtk_widget_get_window(widget);
+
+ cairo_save(cr);
+ gtk_cairo_transform_to_window(cr, widget, window);
+
+ region = gdk_window_get_clip_region(window);
cairo_region_get_extents(region, &area);
cairo_region_destroy(region);
- fake_x = 0;
- fake_y = 0;
- gtk_buffer_view_compute_fake_coord(view, &fake_x, &fake_y);
-
/* Dessin de la marge gauche */
context = gtk_widget_get_style_context(widget);
gtk_style_context_save(context);
+
gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH);
- gtk_style_context_get_color(context, GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_DIR_LTR, &color);
- gtk_style_context_restore(context);
- cairo_set_source_rgb(cr, color.red, color.green, color.blue);
+ gtk_render_background (context, cr, 0, area.y, view->left_margin, 300000);
+ gtk_render_frame (context, cr, 0, area.y - 10, view->left_margin, area.height + 20);
- cairo_rectangle(cr, fake_x, area.y, view->left_margin, area.y + area.height);
- cairo_fill(cr);
+ gtk_style_context_restore(context);
/* Eventuelle bordure globale */
@@ -519,9 +375,18 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
/* Impression du désassemblage */
if (view->buffer_view != NULL)
+ {
+ fake_x = 0;
+ fake_y = 0;
+ gtk_buffer_view_compute_fake_coord(view, &fake_x, &fake_y);
+
g_buffer_view_draw(view->buffer_view, cr, fake_x, fake_y, &area,
*pview->display_phys, *pview->display_addr, *pview->display_code);
+ }
+
+ cairo_restore(cr);
+
return TRUE;
}
@@ -574,6 +439,42 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à consulter. *
+* width = largeur requise à renseigner ou NULL. [OUT] *
+* height = hauteur requise à renseigner ou NULL. [OUT] *
+* *
+* Description : Indique les dimensions de travail du composant d'affichage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *width, gint *height)
+{
+ if (width != NULL && view->buffer_view != NULL)
+ *width = g_buffer_view_get_width(view->buffer_view,
+ *GTK_VIEW_PANEL(view)->display_phys,
+ *GTK_VIEW_PANEL(view)->display_addr,
+ *GTK_VIEW_PANEL(view)->display_code);
+
+ if (height != NULL && view->buffer_view != NULL)
+ *height = g_buffer_view_get_height(view->buffer_view);
+
+}
+
+
+
+
+
+
+
/******************************************************************************
* *
* Paramètres : view = composant GTK à consulter. *
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index f34cf21..7919b32 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -69,18 +69,17 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *);
/* Initialise une instance d'afficheur de code en graphique. */
static void gtk_graph_view_init(GtkGraphView *);
-/* Fournit la hauteur de composant requise pour un plein rendu. */
-static void gtk_graph_view_get_preferred_height(GtkWidget *, gint *, gint *);
-
-/* Fournit la largeur de composant requise pour un plein rendu. */
-static void gtk_graph_view_get_preferred_width(GtkWidget *, gint *, gint *);
-
/* S'adapte à la surface concédée par le composant parent. */
static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
/* 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 *);
+
+
/* Réagit à la sélection externe d'une adresse. */
static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t);
@@ -109,7 +108,7 @@ G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_VIEW_PANEL)
/******************************************************************************
* *
-* Paramètres : klass = classe GTK à initialiser. *
+* Paramètres : class = classe GTK à initialiser. *
* *
* Description : Initialise la classe générique des graphiques de code. *
* *
@@ -119,16 +118,18 @@ G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_VIEW_PANEL)
* *
******************************************************************************/
-static void gtk_graph_view_class_init(GtkGraphViewClass *klass)
+static void gtk_graph_view_class_init(GtkGraphViewClass *class)
{
GtkWidgetClass *widget_class; /* Classe version Widget */
+ GtkViewPanelClass *panel_class; /* Classe parente */
- widget_class = (GtkWidgetClass *)klass;
+ widget_class = GTK_WIDGET_CLASS(class);
+ panel_class = GTK_VIEW_PANEL_CLASS(class);
- widget_class->get_preferred_height = gtk_graph_view_get_preferred_height;
- widget_class->get_preferred_width = gtk_graph_view_get_preferred_width;
widget_class->size_allocate = gtk_graph_view_size_allocate;
+ panel_class->compute_size = (compute_requested_size)gtk_graph_view_compute_requested_size;
+
}
@@ -191,95 +192,6 @@ static void gtk_graph_view_init(GtkGraphView *view)
-
-
-
-/******************************************************************************
-* *
-* Paramètres : widget = composant GTK à consulter. *
-* minimal = taille minimale. [OUT] *
-* natural = taille idéale. [OUT] *
-* *
-* Description : Fournit la hauteur de composant requise pour un plein rendu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void gtk_graph_view_get_preferred_height(GtkWidget *widget, gint *minimal, gint *natural)
-{
- GtkGraphView *view; /* Autre vision du composant */
- GtkRequisition requisition; /* Taille requise */
- gpointer fixed_class; /* Classe parente */
-
- view = GTK_GRAPH_VIEW(widget);
-
- if (view->layout != NULL)
- {
- g_graph_layout_size_request(view->layout, &requisition);
-
- *minimal = requisition.height;
- *natural = *minimal;
-
- }
-
- else
- {
- 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)->get_preferred_height(widget, minimal, natural);
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : widget = composant GTK à consulter. *
-* minimal = taille minimale. [OUT] *
-* natural = taille idéale. [OUT] *
-* *
-* Description : Fournit la largeur de composant requise pour un plein rendu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void gtk_graph_view_get_preferred_width(GtkWidget *widget, gint *minimal, gint *natural)
-{
- GtkGraphView *view; /* Autre vision du composant */
- GtkRequisition requisition; /* Taille requise */
- gpointer fixed_class; /* Classe parente */
-
- view = GTK_GRAPH_VIEW(widget);
-
- if (view->layout != NULL)
- {
- g_graph_layout_size_request(view->layout, &requisition);
-
- *minimal = requisition.width;
- *natural = *minimal;
-
- }
-
- else
- {
- 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)->get_preferred_width(widget, minimal, natural);
-
- }
-
-}
-
-
/******************************************************************************
* *
* Paramètres : view = composant GTK à mettre à jour. *
@@ -303,6 +215,8 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
GdkWindow *window; /* Fenêtre associée au support */
gboolean changed; /* Changement de valeur ? */
+ return;
+
/* Mise à jour GTK */
fixed_class = g_type_class_peek_parent(GTK_GRAPH_VIEW_GET_CLASS(widget));
@@ -315,7 +229,7 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
if (panel->hadjustment == NULL || panel->vadjustment == NULL)
return;
- gtk_view_panel_compute_allocation(panel, &valloc);
+ // !!!! moved !!! gtk_view_panel_compute_allocation(panel, &valloc);
gtk_widget_get_preferred_size(widget, NULL, &req);
@@ -335,7 +249,7 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
gtk_adjustment_set_upper(panel->hadjustment, MAX(req.width, valloc.width));
- gtk_view_panel_reclamp_adjustment(panel->hadjustment, &changed);
+ // !!!! moved !!! gtk_view_panel_reclamp_adjustment(panel->hadjustment, &changed);
gtk_adjustment_changed(panel->hadjustment);
@@ -350,7 +264,7 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
gtk_adjustment_set_upper(panel->vadjustment, MAX(req.height, valloc.height));
- gtk_view_panel_reclamp_adjustment(panel->vadjustment, &changed);
+ // !!!! moved !!! gtk_view_panel_reclamp_adjustment(panel->vadjustment, &changed);
gtk_adjustment_changed(panel->vadjustment);
@@ -360,6 +274,45 @@ static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *alloc
}
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à consulter. *
+* width = largeur requise à renseigner ou NULL. [OUT] *
+* height = hauteur requise à renseigner ou NULL. [OUT] *
+* *
+* Description : Indique les dimensions de travail du composant d'affichage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *width, gint *height)
+{
+ GtkRequisition requisition; /* Taille requise */
+
+ if (width != NULL && view->layout != NULL)
+ {
+ g_graph_layout_size_request(view->layout, &requisition);
+ *width = requisition.height;
+ }
+
+ if (height != NULL && view->layout != NULL)
+ {
+ g_graph_layout_size_request(view->layout, &requisition);
+ *height = requisition.height;
+ }
+
+}
+
+
+
+
/******************************************************************************
* *
* Paramètres : widget = composant GTK à redessiner. *
diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h
index 1970402..1d55bf2 100644
--- a/src/gtkext/gtkviewpanel-int.h
+++ b/src/gtkext/gtkviewpanel-int.h
@@ -33,6 +33,9 @@
+/* Indique les dimensions de travail du composant d'affichage. */
+typedef void (* compute_requested_size) (GtkViewPanel *, gint *, gint *);
+
/* Prend acte de l'association d'un binaire chargé. */
typedef void (* attach_binary_fc) (GtkViewPanel *, GLoadedBinary *, bool *, bool *);
@@ -57,6 +60,8 @@ struct _GtkViewPanel
GtkAdjustment *hadjustment; /* Barre de défilement horiz. */
GtkAdjustment *vadjustment; /* Barre de défilement vert. */
+ GtkScrollablePolicy hscroll_policy; /* Politique horizontale */
+ GtkScrollablePolicy vscroll_policy; /* Politique verticale */
bool show_border; /* Affichage d'une bordure ? */
@@ -79,14 +84,20 @@ struct _GtkViewPanelClass
{
GtkFixedClass parent; /* A laisser en premier */
-};
+ compute_requested_size compute_size; /* Calcul de la taille requise */
+};
-/* S'assure que la valeur de défilement actuelle est valable. */
-void gtk_view_panel_reclamp_adjustment(GtkAdjustment *, gboolean *);
+/* Propriétés propres au composant d'affichage */
+typedef enum _ViewPanelProps
+{
+ VPP_0,
+ VPP_HADJUSTMENT,
+ VPP_VADJUSTMENT,
+ VPP_HSCROLL_POLICY,
+ VPP_VSCROLL_POLICY
-/* Calcule la surface pleine utilisable pour le panneau. */
-void gtk_view_panel_compute_allocation(GtkViewPanel *, GtkAllocation *);
+} ViewPanelProps;
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index e4e73a4..353022a 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -35,16 +35,46 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *);
/* Procède à l'initialisation de l'afficheur générique. */
static void gtk_view_panel_init(GtkViewPanel *);
+/* Définit une propriété du composant d'affichage. */
+static void gtk_view_panel_set_property(GObject *, guint, const GValue *, GParamSpec *);
+
+/* Fournit une propriété du composant d'affichage. */
+static void gtk_view_panel_get_property(GObject *, guint, GValue *, GParamSpec *);
+
+/* Détruit un composant d'affichage. */
+static void gtk_view_panel_destroy(GtkWidget *);
+
/* Encadre la construction graphique initiale de l'affichage. */
static void gtk_view_panel_realize(GtkWidget *);
+/* S'adapte à la surface concédée par le composant parent. */
+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 *);
+/* Détermine la taille allouée pour le contenu. */
+static void gtk_view_panel_compute_allocation(GtkViewPanel *, GtkAllocation *);
+
+/* Se débarrsse d'un ajustement pour un défilement donné. */
+static void gtk_view_panel_disconnect_adjustment(GtkViewPanel *, GtkOrientation);
+
+/* S'associe à un ajustement pour un défilement donné. */
+static void gtk_view_panel_set_adjustment(GtkViewPanel *, GtkOrientation, GtkAdjustment *);
+
+/* Ajuste les paramètres de défilement du composant. */
+static void gtk_view_panel_update_adjustment(GtkViewPanel *, GtkOrientation);
+
+/* Réagit à un défilement chez une barre associée au composant.*/
+static void gtk_view_panel_adjustment_value_changed(GtkAdjustment *, GtkViewPanel *);
+
+
+
/* Détermine le type du composant d'affichage générique. */
-G_DEFINE_TYPE(GtkViewPanel, gtk_view_panel, GTK_TYPE_FIXED)
+G_DEFINE_TYPE_WITH_CODE(GtkViewPanel, gtk_view_panel, GTK_TYPE_FIXED,
+ G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL))
/******************************************************************************
@@ -61,11 +91,24 @@ G_DEFINE_TYPE(GtkViewPanel, gtk_view_panel, GTK_TYPE_FIXED)
static void gtk_view_panel_class_init(GtkViewPanelClass *class)
{
+ GObjectClass *gobject_class; /* Plus haut niveau équivalent */
GtkWidgetClass *widget_class; /* Classe de haut niveau */
+ gobject_class = G_OBJECT_CLASS(class);
widget_class = GTK_WIDGET_CLASS(class);
+ gobject_class->set_property = gtk_view_panel_set_property;
+ gobject_class->get_property = gtk_view_panel_get_property;
+
+ /* Implémentation de l'interface "GtkScrollable" */
+ g_object_class_override_property(gobject_class, VPP_HADJUSTMENT, "hadjustment");
+ g_object_class_override_property(gobject_class, VPP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property(gobject_class, VPP_HSCROLL_POLICY, "hscroll-policy");
+ g_object_class_override_property(gobject_class, VPP_VSCROLL_POLICY, "vscroll-policy");
+
+ widget_class->destroy = gtk_view_panel_destroy;
widget_class->realize = gtk_view_panel_realize;
+ widget_class->size_allocate = gtk_view_panel_size_allocate;
widget_class->draw = gtk_view_panel_draw;
}
@@ -93,10 +136,12 @@ static void gtk_view_panel_init(GtkViewPanel *panel)
/******************************************************************************
* *
-* Paramètres : adj = valeurs de défilement à consulter. *
-* changed = note une mise à jour de valeur. [OUT] *
+* Paramètres : object = instance de composant GTK à manipuler. *
+* prop_id = identifiant de la propriété concernée. *
+* value = valeur attribuée. *
+* pspec = spécification de la propriété visée. *
* *
-* Description : S'assure que la valeur de défilement actuelle est valable. *
+* Description : Définit une propriété du composant d'affichage. *
* *
* Retour : - *
* *
@@ -104,30 +149,44 @@ static void gtk_view_panel_init(GtkViewPanel *panel)
* *
******************************************************************************/
-void gtk_view_panel_reclamp_adjustment(GtkAdjustment *adj, gboolean *changed)
+static void gtk_view_panel_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
- gdouble value; /* Valeur actuelle */
+ GtkViewPanel *panel; /* Autre vision de l'instance */
- value = gtk_adjustment_get_value(adj);
-
- value = CLAMP(value, 0, gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj));
+ panel = GTK_VIEW_PANEL(object);
- if (value != gtk_adjustment_get_value(adj))
+ switch (prop_id)
{
- gtk_adjustment_set_value(adj, value);
- *changed = TRUE;
+ case VPP_HADJUSTMENT:
+ gtk_view_panel_set_adjustment(panel, GTK_ORIENTATION_HORIZONTAL, g_value_get_object(value));
+ break;
+ case VPP_VADJUSTMENT:
+ gtk_view_panel_set_adjustment(panel, GTK_ORIENTATION_VERTICAL, g_value_get_object(value));
+ break;
+ case VPP_HSCROLL_POLICY:
+ //viewport->priv->hscroll_policy = g_value_get_enum (value);
+ //gtk_widget_queue_resize (GTK_WIDGET (viewport));
+ break;
+ case VPP_VSCROLL_POLICY:
+ //viewport->priv->vscroll_policy = g_value_get_enum (value);
+ //gtk_widget_queue_resize (GTK_WIDGET (viewport));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
}
- else *changed = FALSE;
}
/******************************************************************************
* *
-* Paramètres : panel = composant GTK à consulter. *
-* alloc = étendue à accorder à la vue. *
+* Paramètres : object = instance de composant GTK à manipuler. *
+* prop_id = identifiant de la propriété concernée. *
+* value = valeur à renvoyer. *
+* pspec = spécification de la propriété visée. *
* *
-* Description : Calcule la surface pleine utilisable pour le panneau. *
+* Description : Fournit une propriété du composant d'affichage. *
* *
* Retour : - *
* *
@@ -135,29 +194,56 @@ void gtk_view_panel_reclamp_adjustment(GtkAdjustment *adj, gboolean *changed)
* *
******************************************************************************/
-void gtk_view_panel_compute_allocation(GtkViewPanel *panel, GtkAllocation *alloc)
+static void gtk_view_panel_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
- GtkWidget *widget; /* Autre version de la vue */
- GtkAllocation allocation; /* Raccourci d'utilisation #1 */
- gint border_width; /* Raccourci d'utilisation #2 */
-
- widget = GTK_WIDGET(panel);
- gtk_widget_get_allocation(widget, &allocation);
- border_width = gtk_container_get_border_width(GTK_CONTAINER(panel));
+ GtkViewPanel *panel; /* Autre vision de l'instance */
- alloc->x = 0;
- alloc->y = 0;
+ panel = GTK_VIEW_PANEL(object);
- /*
- if (viewport->shadow_type != GTK_SHADOW_NONE)
+ switch (prop_id)
{
- alloc->x = widget->style->xthickness;
- alloc->y = widget->style->ythickness;
+ case VPP_HADJUSTMENT:
+ g_value_set_object(value, panel->hadjustment);
+ break;
+ case VPP_VADJUSTMENT:
+ g_value_set_object(value, panel->vadjustment);
+ break;
+ case VPP_HSCROLL_POLICY:
+ g_value_set_enum(value, panel->hscroll_policy);
+ break;
+ case VPP_VSCROLL_POLICY:
+ g_value_set_enum(value, panel->vscroll_policy);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
}
- */
- alloc->width = MAX(1, allocation.width - alloc->x * 2 - border_width * 2);
- alloc->height = MAX(1, allocation.height - alloc->y * 2 - border_width * 2);
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK à détruire. *
+* *
+* Description : Détruit un composant d'affichage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_destroy(GtkWidget *widget)
+{
+ GtkViewPanel *panel; /* Autre version du composant */
+
+ panel = GTK_VIEW_PANEL(widget);
+
+ gtk_view_panel_disconnect_adjustment(panel, GTK_ORIENTATION_HORIZONTAL);
+ gtk_view_panel_disconnect_adjustment(panel, GTK_ORIENTATION_VERTICAL);
+
+ GTK_WIDGET_CLASS(gtk_view_panel_parent_class)->destroy(widget);
}
@@ -180,7 +266,6 @@ static void gtk_view_panel_realize(GtkWidget *widget)
GdkWindowAttr attributes; /* Propriétés du composant */
guint attributes_mask; /* Masque de prise en compte */
GdkWindow *window; /* Fenêtre du composant */
- GdkRGBA white; /* Couleur de fond normale */
gtk_widget_get_allocation(widget, &allocation);
@@ -202,21 +287,35 @@ static void gtk_view_panel_realize(GtkWidget *widget)
&attributes, attributes_mask);
gtk_widget_set_window(widget, window);
+ gtk_widget_register_window(widget, window);
- gdk_window_set_user_data(window, widget);
+}
- gdk_rgba_parse(&white, "white");
- gtk_widget_override_background_color(widget, GTK_STATE_FLAG_NORMAL, &white);
- /*
- widget->style = gtk_style_attach(widget->style, widget->window);
+/******************************************************************************
+* *
+* 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_view_panel_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+ GtkViewPanel *panel; /* Autre version du composant */
+
+ GTK_WIDGET_CLASS(gtk_view_panel_parent_class)->size_allocate(widget, allocation);
- gdk_color_white(gtk_widget_get_colormap(widget), &white);
- gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &white);
+ panel = GTK_VIEW_PANEL(widget);
- GTK_VIEW_PANEL(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window));
- */
+ gtk_view_panel_update_adjustment(panel, GTK_ORIENTATION_HORIZONTAL);
+ gtk_view_panel_update_adjustment(panel, GTK_ORIENTATION_VERTICAL);
}
@@ -265,6 +364,218 @@ static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr)
/******************************************************************************
* *
+* Paramètres : panel = composant GTK à consulter. *
+* alloc = emplacement à déterminer. [OUT] *
+* *
+* Description : Détermine la taille allouée pour le contenu. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_compute_allocation(GtkViewPanel *panel, GtkAllocation *alloc)
+{
+ GtkWidget *widget; /* Autre vision du composant */
+ GtkAllocation allocation; /* Emplacement du composant */
+ GtkStyleContext *context; /* Contexte du style */
+ GtkStateFlags state; /* Etat du composant */
+ GtkBorder padding; /* Espace d'un espacement */
+ GtkBorder border; /* Espace d'une bordure */
+
+ widget = GTK_WIDGET(panel);
+
+ gtk_widget_get_allocation(widget, &allocation);
+
+ context = gtk_widget_get_style_context(widget);
+ state = gtk_widget_get_state_flags(widget);
+
+ gtk_style_context_save(context);
+ gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME);
+
+ gtk_style_context_get_padding(context, state, &padding);
+ gtk_style_context_get_border(context, state, &border);
+
+ gtk_style_context_restore(context);
+
+ /* Positions */
+
+ if (panel->show_border)
+ {
+ alloc->x = border.left;
+ alloc->y = border.top;
+ }
+ else
+ {
+ alloc->x = 0;
+ alloc->y = 0;
+ }
+
+ alloc->x += padding.left;
+ alloc->y += padding.top;
+
+ /* Dimensions */
+
+ if (panel->show_border)
+ {
+ alloc->width = MAX (1, allocation.width - alloc->x - padding.right - border.right);
+ alloc->height = MAX (1, allocation.height - alloc->y - padding.bottom - border.bottom);
+ }
+ else
+ {
+ alloc->width = MAX (1, allocation.width - alloc->x - padding.right);
+ alloc->height = MAX (1, allocation.height - alloc->y - padding.bottom);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK d'affichage à mettre à jour. *
+* orientation = indication sur le défilement à traiter. *
+* *
+* Description : Se débarrsse d'un ajustement pour un défilement donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_disconnect_adjustment(GtkViewPanel *panel, GtkOrientation orientation)
+{
+ GtkAdjustment **adjp; /* Ajustement à manipuler */
+
+ adjp = orientation == GTK_ORIENTATION_HORIZONTAL ? &panel->hadjustment : &panel->vadjustment;
+
+ if (*adjp != NULL)
+ {
+ g_signal_handlers_disconnect_by_func(*adjp, gtk_view_panel_adjustment_value_changed, panel);
+ g_object_unref(G_OBJECT(*adjp));
+ *adjp = NULL;
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK d'affichage à mettre à jour. *
+* orientation = indication sur le défilement à traiter. *
+* adj = nouvel ajustement à prendre en compte. *
+* *
+* Description : S'associe à un ajustement pour un défilement donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_set_adjustment(GtkViewPanel *panel, GtkOrientation orientation, GtkAdjustment *adj)
+{
+ GtkAdjustment **adjp; /* Ajustement à manipuler */
+
+ adjp = orientation == GTK_ORIENTATION_HORIZONTAL ? &panel->hadjustment : &panel->vadjustment;
+
+ /* S'il n'y a rien à faire... */
+ if (adj != NULL && adj == *adjp)
+ return;
+
+ if (!adj)
+ adj = gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+ gtk_view_panel_disconnect_adjustment(panel, orientation);
+
+ *adjp = adj;
+ g_object_ref_sink(adj);
+
+ gtk_view_panel_update_adjustment(panel, orientation);
+
+ g_signal_connect(adj, "value-changed", G_CALLBACK(gtk_view_panel_adjustment_value_changed), panel);
+
+ gtk_view_panel_adjustment_value_changed(adj, panel);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK d'affichage à mettre à jour. *
+* orientation = indication sur le défilement à traiter. *
+* *
+* Description : Ajuste les paramètres de défilement du composant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation orientation)
+{
+ GtkAllocation allocation; /* Emplacement du contenu */
+ GtkAdjustment *adj; /* Ajustement à manipuler */
+ gint req; /* Dimension requise */
+ gint allocated; /* Dimension allouée */
+
+ gtk_view_panel_compute_allocation(panel, &allocation);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ adj = panel->hadjustment;
+
+ GTK_VIEW_PANEL_GET_CLASS(panel)->compute_size(panel, &req, NULL);
+ allocated = allocation.width;
+
+ }
+ else
+ {
+ adj = panel->vadjustment;
+
+ GTK_VIEW_PANEL_GET_CLASS(panel)->compute_size(panel, NULL, &req);
+ allocated = allocation.height;
+
+ }
+
+ gtk_adjustment_configure(adj, gtk_adjustment_get_value(adj),
+ 0, MAX(req, allocated),
+ allocated * 0.1,
+ allocated * 0.9,
+ allocated);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : adj = défilement dont une valeur a changé. *
+* panel = panneau d'affichage concerné. *
+* *
+* Description : Réagit à un défilement chez une barre associée au composant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_adjustment_value_changed(GtkAdjustment *adj, GtkViewPanel *panel)
+{
+ GtkWidget *widget; /* Autre vision du composant */
+
+ widget = GTK_WIDGET(panel);
+
+ if (gtk_widget_get_realized(widget))
+ gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, false);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : panel = composant GTK à mettre à jour. *
* show = état de l'affichage auquel parvenir. *
* *
@@ -483,7 +794,7 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)
*/
- if (panel->get_coordinates(panel, addr, &x, &y))
+ if (panel->get_coordinates(panel, addr, &x, &y) && 0 /* ARG */)
{
viewport = gtk_widget_get_parent(GTK_WIDGET(panel));