diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-09-10 21:02:04 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-09-10 21:02:04 (GMT) |
commit | be1f2f147e8ce15f20ec4de439088714ffa50e8a (patch) | |
tree | eab8ad76fa6f39781568fae13fb7967cdedbd45a /src/gtkext/gtkviewpanel.c | |
parent | c03635088f26a18cdbd42c2528f00b9ccd8591d9 (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/gtkviewpanel.c')
-rw-r--r-- | src/gtkext/gtkviewpanel.c | 399 |
1 files changed, 355 insertions, 44 deletions
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)); |