From be1f2f147e8ce15f20ec4de439088714ffa50e8a Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 10 Sep 2014 21:02:04 +0000 Subject: Fixed and improved the rendering of view panels. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@401 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 8 + src/gtkext/gtkbufferview.c | 227 +++++++----------------- src/gtkext/gtkgraphview.c | 159 ++++++----------- src/gtkext/gtkviewpanel-int.h | 21 ++- src/gtkext/gtkviewpanel.c | 399 +++++++++++++++++++++++++++++++++++++----- 5 files changed, 499 insertions(+), 315 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe15323..790dbc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +14-09-10 Cyrille Bagard + + * src/gtkext/gtkbufferview.c: + * src/gtkext/gtkgraphview.c: + * src/gtkext/gtkviewpanel.c: + * src/gtkext/gtkviewpanel-int.h: + Fix and improve the rendering of view panels. + 14-09-08 Cyrille Bagard * src/core/params.c: 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)); -- cgit v0.11.2-87-g4458