From ef174ce487411fceffd5d5098b51e66b65bb93b8 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 17 Oct 2016 23:04:33 +0200 Subject: Produced nicer graphic node rendering with shadows. --- ChangeLog | 8 +++ src/gtkext/gtkbufferview.c | 55 +++++++++++++-- src/gtkext/gtkgraphview.c | 48 ++++++++++++- src/gtkext/gtkviewpanel-int.h | 7 ++ src/gtkext/gtkviewpanel.c | 152 +++++++++++++++++++++++++++++------------- 5 files changed, 215 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5da8f28..32646d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +16-10-17 Cyrille Bagard + + * src/gtkext/gtkbufferview.c: + * src/gtkext/gtkgraphview.c: + * src/gtkext/gtkviewpanel-int.h: + * src/gtkext/gtkviewpanel.c: + Produce nicer graphic node rendering with shadows. + 16-10-16 Cyrille Bagard * src/arch/arm/v7/link.c: diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index f0efce0..2032547 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -342,6 +342,7 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) cairo_region_t *region; /* Région visible à redessiner */ cairo_rectangle_int_t area; /* Surface correspondante */ GtkStyleContext *context; /* Contexte du thème actuel */ + GdkRGBA color; /* Couleur de thème récupérée */ gint fake_x; /* Abscisse virtuelle */ gint fake_y; /* Ordonnée virtuelle */ bool sel_line; /* Souslignage de la sélection */ @@ -359,22 +360,66 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) cairo_region_get_extents(region, &area); cairo_region_destroy(region); + context = gtk_widget_get_style_context(widget); + + if (pview->show_border) + { + gtk_view_panel_define_border_path(pview, cr, 0, 0); + cairo_clip(cr); + } + /* 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_TOOLBAR); + + gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color); + + cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); + + cairo_rectangle(cr, 0, area.y, view->left_margin, area.height); + cairo_fill(cr); + + gtk_style_context_restore(context); + + /* Fond de la zone de texte */ gtk_style_context_save(context); - gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH); + gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW); + + gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color); + + cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.7); + + cairo_rectangle(cr, view->left_margin, area.y, area.width, area.height); + cairo_fill(cr); + + gtk_style_context_restore(context); + + /* Ligne de séparation */ + + gtk_style_context_save(context); + + gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); + + gtk_style_context_get_border_color(context, GTK_STATE_FLAG_ACTIVE, &color); + + cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); + + cairo_set_line_width(cr, 1.0); - gtk_render_background(context, cr, 0, area.y, view->left_margin, area.height); - gtk_render_frame(context, cr, 0, area.y - 10, view->left_margin, area.height + 20); + cairo_move_to(cr, view->left_margin + 0.5, area.y - 0.5); + cairo_line_to(cr, view->left_margin + 0.5, area.y + area.height + 0.5); + cairo_stroke(cr); gtk_style_context_restore(context); /* Eventuelle bordure globale */ - GTK_WIDGET_CLASS(gtk_buffer_view_parent_class)->draw(widget, cr); + if (pview->show_border) + gtk_view_panel_draw_border(pview, cr); /* Impression du désassemblage */ diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index 6255602..5b32f69 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -71,6 +71,9 @@ struct _GtkGraphViewClass }; +/* Profondeur de l'ombre */ +#define SHADOW_SIZE 4 + /* Initialise la classe générique des graphiques de code. */ static void gtk_graph_view_class_init(GtkGraphViewClass *); @@ -152,8 +155,14 @@ G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_VIEW_PANEL) static void gtk_graph_view_class_init(GtkGraphViewClass *class) { + GObjectClass *object; /* Autre version de la classe */ GtkViewPanelClass *panel_class; /* Classe parente */ + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_view_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_graph_view_finalize; + panel_class = GTK_VIEW_PANEL_CLASS(class); panel_class->compute_size = (compute_requested_size_fc)gtk_graph_view_compute_requested_size; @@ -314,8 +323,8 @@ static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *widt needed.height = 0; } - if (width != NULL) *width = needed.width; - if (height != NULL) *height = needed.height; + if (width != NULL) *width = needed.width + SHADOW_SIZE; + if (height != NULL) *height = needed.height + SHADOW_SIZE; } @@ -366,6 +375,41 @@ static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView { size_t i; /* Boucle de parcours */ + void draw_shadow(GtkWidget *child, gpointer unused) + { + GtkAllocation alloc; /* Emplacement de l'enfant */ + gint j; /* Boucle de parcours */ + cairo_pattern_t *pattern; /* Zones d'application */ + + gtk_widget_get_allocation(child, &alloc); + + for (j = 1; j < SHADOW_SIZE; j++) + { + cairo_push_group(cr); + + gtk_view_panel_define_border_path(GTK_VIEW_PANEL(child), cr, alloc.x + j, alloc.y + j); + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); + cairo_fill(cr); + + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + + gtk_view_panel_define_border_path(GTK_VIEW_PANEL(child), cr, alloc.x, alloc.y); + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0); + cairo_fill(cr); + + pattern = cairo_pop_group(cr); + + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.3); + cairo_mask(cr, pattern); + cairo_fill(cr); + + } + + } + + gtk_container_foreach(GTK_CONTAINER(view->support), (GtkCallback)draw_shadow, NULL); + + for (i = 0; i < view->edges_count; i++) g_graph_edge_draw(view->edges[i], cr, true); diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h index 9f53051..f827b2c 100644 --- a/src/gtkext/gtkviewpanel-int.h +++ b/src/gtkext/gtkviewpanel-int.h @@ -125,6 +125,13 @@ typedef enum _ViewPanelProps } ViewPanelProps; +/* Définit un chemin décrivant la bordure autour du panneau. */ +void gtk_view_panel_define_border_path(GtkViewPanel *, cairo_t *, gint, gint); + +/* Dessine si besoin est une bordure autour du composant. */ +void gtk_view_panel_draw_border(GtkViewPanel *, cairo_t *); + + /* --------------------------- CONVERSIONS DE COORDONNEES --------------------------- */ diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index 4d5a57e..8672bb9 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -24,9 +24,15 @@ #include "gtkviewpanel.h" +#include + + #include "gtkviewpanel-int.h" +/* Amplitude de l'arrondi pour les coins */ +#define BORDER_CORNER_RADIUS 10.0 + /* Procède à l'initialisation de l'afficheur générique. */ static void gtk_view_panel_class_init(GtkViewPanelClass *); @@ -49,9 +55,6 @@ 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 *); - /* Fournit la hauteur idéale pour le composant d'affichage. */ static void gtk_view_panel_get_preferred_height(GtkWidget *, gint *, gint *); @@ -120,7 +123,6 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class) 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; widget_class->get_preferred_height = gtk_view_panel_get_preferred_height; widget_class->get_preferred_width = gtk_view_panel_get_preferred_width; @@ -356,50 +358,6 @@ static void gtk_view_panel_size_allocate(GtkWidget *widget, GtkAllocation *alloc /****************************************************************************** * * -* Paramètres : widget = composant GTK à redessiner. * -* cr = contexte graphique associé à l'événement. * -* * -* Description : Met à jour l'affichage du composant d'affichage. * -* * -* Retour : FALSE pour poursuivre la propagation de l'événement. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr) -{ - GtkViewPanel *panel; /* Autre version du composant */ - GtkRequisition req; /* Taille allouée à l'élément */ - GtkStyleContext *context; /* Contexte du thème actuel */ - - GTK_WIDGET_CLASS(gtk_view_panel_parent_class)->draw(widget, cr); - - panel = GTK_VIEW_PANEL(widget); - - if (panel->show_border) - { - gtk_widget_get_preferred_size(widget, NULL, &req); - - context = gtk_widget_get_style_context(widget); - - gtk_style_context_save(context); - - gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); - - gtk_render_frame(context, cr, 0, 0, req.width, req.height); - - gtk_style_context_restore(context); - - } - - return FALSE; - -} - - -/****************************************************************************** -* * * Paramètres : widget = composant GTK à examiner. * * minimum = hauteur minimale à préciser ou NULL. [OUT] * * natural = hauteur idéale à préciser ou NULL. [OUT] * @@ -730,6 +688,104 @@ void gtk_view_panel_show_border(GtkViewPanel *panel, bool show) /****************************************************************************** * * +* Paramètres : panel = composant GTK à venir consulter. * +* cr = contexte graphique associé à l'événement. * +* offset = décallage éventuel à appliquer. * +* * +* Description : Définit un chemin décrivant la bordure autour du panneau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_view_panel_define_border_path(GtkViewPanel *panel, cairo_t *cr, gint off_x, gint off_y) +{ + GtkRequisition req; /* Taille allouée à l'élément */ + double degrees; /* Conversion en degrés */ + + gtk_widget_get_preferred_size(GTK_WIDGET(panel), NULL, &req); + + degrees = M_PI / 180.0; + + cairo_new_sub_path(cr); + + cairo_arc(cr, + off_x + req.width - BORDER_CORNER_RADIUS - 0.5, + off_y + BORDER_CORNER_RADIUS + 0.5, + BORDER_CORNER_RADIUS, -90 * degrees, 0 * degrees); + + cairo_arc(cr, + off_x + req.width - BORDER_CORNER_RADIUS - 0.5, + off_y + req.height - BORDER_CORNER_RADIUS - 0.5, + BORDER_CORNER_RADIUS, 0 * degrees, 90 * degrees); + + cairo_arc(cr, + off_x + BORDER_CORNER_RADIUS + 0.5, + off_y + req.height - BORDER_CORNER_RADIUS - 0.5, + BORDER_CORNER_RADIUS, 90 * degrees, 180 * degrees); + + cairo_arc(cr, + off_x + BORDER_CORNER_RADIUS + 0.5, + off_y + BORDER_CORNER_RADIUS + 0.5, + BORDER_CORNER_RADIUS, 180 * degrees, 270 * degrees); + + cairo_close_path(cr); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à venir consulter. * +* cr = contexte graphique associé à l'événement. * +* * +* Description : Dessine si besoin est une bordure autour du composant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_view_panel_draw_border(GtkViewPanel *panel, cairo_t *cr) +{ + GtkWidget *widget; /* Autre version du composant */ + GtkRequisition req; /* Taille allouée à l'élément */ + GtkStyleContext *context; /* Contexte du thème actuel */ + GdkRGBA color; /* Couleur de thème récupérée */ + + if (panel->show_border) + { + widget = GTK_WIDGET(panel); + + gtk_widget_get_preferred_size(widget, NULL, &req); + + context = gtk_widget_get_style_context(widget); + + gtk_style_context_save(context); + + gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME); + + gtk_style_context_get_border_color(context, GTK_STATE_FLAG_ACTIVE, &color); + + cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); + + cairo_set_line_width(cr, 1.0); + + gtk_view_panel_define_border_path(panel, cr, 0, 0); + cairo_stroke(cr); + + gtk_style_context_restore(context); + + } + +} + + +/****************************************************************************** +* * * Paramètres : panel = composant GTK à mettre à jour. * * binary = binaire associé à intégrer. * * view = aspect du binaire à présenter. * -- cgit v0.11.2-87-g4458