summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-03-20 23:04:32 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-03-20 23:04:32 (GMT)
commitff1ce15f6c4b3516d7a34b09dd99abb32a0bd671 (patch)
treee3925ba68b25ca5a73c7547704668cb8fad32ef9 /src
parent86a892e1bf5d3483929da3ea72bfcbfd43f6c6bc (diff)
Introduced zoom in graph view.
Diffstat (limited to 'src')
-rw-r--r--src/glibext/gbufferview.c5
-rw-r--r--src/glibext/gbufferview.h2
-rw-r--r--src/gtkext/gtkbufferdisplay.c18
-rw-r--r--src/gtkext/gtkdisplaypanel-int.h13
-rw-r--r--src/gtkext/gtkdisplaypanel.c137
-rw-r--r--src/gtkext/gtkdisplaypanel.h6
-rw-r--r--src/gtkext/gtkgraphdisplay.c129
-rw-r--r--src/gui/menus/menubar.c2
-rw-r--r--src/gui/menus/view.c93
-rw-r--r--src/gui/menus/view.h2
10 files changed, 360 insertions, 47 deletions
diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c
index c5021f2..db8da28 100644
--- a/src/glibext/gbufferview.c
+++ b/src/glibext/gbufferview.c
@@ -1100,6 +1100,7 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const G
* options = règles d'affichage des colonnes modulables. *
* offsets = décalages supplémentaires à appliquer. *
* selected = ordonnée d'une ligne sélectionnée ou NULL. *
+* scale = échelle appliquée à la surface de rendu. *
* export = indique si la vue est en cours d'exportation. *
* *
* Description : Imprime la visualisation du tampon de lignes quelconques. *
@@ -1110,7 +1111,7 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const G
* *
******************************************************************************/
-void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint virt_y, const cairo_rectangle_int_t *area, const GDisplayOptions *options, const line_width_summary *offsets, gint *selected, bool export)
+void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint virt_y, const cairo_rectangle_int_t *area, const GDisplayOptions *options, const line_width_summary *offsets, gint *selected, double scale, bool export)
{
gint line_height; /* Hauteur d'une ligne */
gint cr_y; /* Ordonnée pour le dessin */
@@ -1118,7 +1119,7 @@ void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint virt_y, const
size_t last; /* Dernière ligne visée */
segcnt_list *highlighted; /* Segments mis en évidence */
- line_height = g_buffer_cache_get_line_height(view->cache);
+ line_height = g_buffer_cache_get_line_height(view->cache) * scale;
/* Indice et point de départ */
diff --git a/src/glibext/gbufferview.h b/src/glibext/gbufferview.h
index 9d40cbd..c6cc5aa 100644
--- a/src/glibext/gbufferview.h
+++ b/src/glibext/gbufferview.h
@@ -98,7 +98,7 @@ bool g_buffer_view_unhighlight_segments(GBufferView *);
bool g_buffer_view_highlight_segments(GBufferView *, gint, gint, const GDisplayOptions *, const line_width_summary *);
/* Imprime la visualisation du tampon de lignes quelconques. */
-void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, const cairo_rectangle_int_t *, const GDisplayOptions *, const line_width_summary *, gint *, bool);
+void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, const cairo_rectangle_int_t *, const GDisplayOptions *, const line_width_summary *, gint *, double, bool);
diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c
index b9784de..b7af1d6 100644
--- a/src/gtkext/gtkbufferdisplay.c
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -423,8 +423,14 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
if (parent->show_border)
{
- gtk_display_panel_define_border_path(parent, cr, 0, 0);
+ gtk_widget_get_allocation(widget, &allocation);
+
+ allocation.x = 0;
+ allocation.y = 0;
+
+ gtk_display_panel_define_border_path(parent, cr, &allocation);
cairo_clip(cr);
+
}
/* Décalage pour le défilement horizontal */
@@ -441,7 +447,7 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
cache = g_buffer_view_get_cache(display->view);
- left_margin = g_buffer_cache_get_left_margin(cache);
+ left_margin = g_buffer_cache_get_left_margin(cache) * parent->scale;
g_object_unref(G_OBJECT(cache));
@@ -494,6 +500,10 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
/* Impression du désassemblage */
+ cairo_save(cr);
+
+ cairo_scale(cr, parent->scale, parent->scale);
+
if (display->view != NULL)
{
g_generic_config_get_value(get_main_configuration(), MPK_SELECTION_LINE, &sel_line);
@@ -511,7 +521,7 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
virt_y += area.y;
g_buffer_view_draw(display->view, cr, virt_y, &area, parent->options, &display->offsets,
- selected, parent->export);
+ selected, parent->scale, parent->export);
}
@@ -528,6 +538,8 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
GTK_WIDGET_CLASS(gtk_buffer_display_parent_class)->draw(widget, cr);
+ cairo_restore(cr);
+
return FALSE;
}
diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h
index 7be5616..17fd6f0 100644
--- a/src/gtkext/gtkdisplaypanel-int.h
+++ b/src/gtkext/gtkdisplaypanel-int.h
@@ -71,6 +71,9 @@ typedef GLineCursor * (* get_cursor_fc) (const GtkDisplayPanel *);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
typedef void (* cache_glance_fc) (GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double);
+/* Spécifie l'échelle à appliquer à l'affichage du composant. */
+typedef void (* apply_scale_fc) (GtkDisplayPanel *, double, double);
+
/* Marque ou non le composant pour une exportation prochaine. */
typedef void (* prepare_export_fc) (GtkDisplayPanel *, bool);
@@ -86,6 +89,8 @@ struct _GtkDisplayPanel
GtkScrollablePolicy hscroll_policy; /* Politique horizontale */
GtkScrollablePolicy vscroll_policy; /* Politique verticale */
+ double scale; /* Echelle de l'affichage */
+
bool show_border; /* Affichage d'une bordure ? */
unsigned int view_index; /* Indice du type de contenu */
GDisplayOptions *options; /* Affichage des colonnes ? */
@@ -112,8 +117,14 @@ struct _GtkDisplayPanelClass
get_cursor_fc get_cursor; /* Fourniture d'une position */
cache_glance_fc cache_glance; /* Cache de la mignature */
+ apply_scale_fc scale; /* Mise à jour de l'échelle */
+
prepare_export_fc prepare_export; /* Préparation d'exportation */
+ /* Signaux */
+
+ void (* scaled) (GtkDisplayPanel *, double, double);
+
};
/* Propriétés propres au composant d'affichage */
@@ -129,7 +140,7 @@ typedef enum _ViewPanelProps
/* Définit un chemin décrivant la bordure autour du panneau. */
-void gtk_display_panel_define_border_path(GtkDisplayPanel *, cairo_t *, gint, gint);
+void gtk_display_panel_define_border_path(GtkDisplayPanel *, cairo_t *, const GtkAllocation *);
/* Dessine si besoin est une bordure autour du composant. */
void gtk_display_panel_draw_border(GtkDisplayPanel *, cairo_t *);
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index b32adfa..76c18ec 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -28,6 +28,7 @@
#include "gtkdisplaypanel-int.h"
+#include "../glibext/chrysamarshal.h"
#include "../glibext/gbinarycursor.h" // REMME
#include "../glibext/gloadedpanel-int.h"
@@ -161,6 +162,16 @@ static void gtk_display_panel_class_init(GtkDisplayPanelClass *class)
panel->compute_inc = gtk_display_panel_compute_scroll_inc;
+ /* Signaux */
+
+ g_signal_new("scaled",
+ GTK_TYPE_DISPLAY_PANEL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GtkDisplayPanelClass, scaled),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__DOUBLE_DOUBLE,
+ G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
+
}
@@ -181,6 +192,8 @@ static void gtk_display_panel_init(GtkDisplayPanel *panel)
gtk_widget_set_has_window(GTK_WIDGET(panel), TRUE);
gtk_widget_set_can_focus(GTK_WIDGET(panel), TRUE);
+ panel->scale = 1.0;
+
panel->export = false;
}
@@ -460,9 +473,14 @@ static void gtk_display_panel_size_allocate(GtkWidget *widget, GtkAllocation *al
static void gtk_display_panel_get_preferred_height(GtkWidget *widget, gint *minimum, gint *natural)
{
+ GtkDisplayPanel *panel; /* Autre version du composant */
gint req; /* Dimension requise */
- GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(GTK_DISPLAY_PANEL(widget), NULL, &req);
+ panel = GTK_DISPLAY_PANEL(widget);
+
+ GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(panel, NULL, &req);
+
+ req *= panel->scale;
if (minimum != NULL) *minimum = req;
if (natural != NULL) *natural = req;
@@ -486,9 +504,14 @@ static void gtk_display_panel_get_preferred_height(GtkWidget *widget, gint *mini
static void gtk_display_panel_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural)
{
+ GtkDisplayPanel *panel; /* Autre version du composant */
gint req; /* Dimension requise */
- GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(GTK_DISPLAY_PANEL(widget), &req, NULL);
+ panel = GTK_DISPLAY_PANEL(widget);
+
+ GTK_DISPLAY_PANEL_GET_CLASS(widget)->compute_size(panel, &req, NULL);
+
+ req *= panel->scale;
if (minimum != NULL) *minimum = req;
if (natural != NULL) *natural = req;
@@ -687,7 +710,7 @@ static void gtk_display_panel_update_adjustment(GtkDisplayPanel *panel, GtkOrien
{
adj = panel->hadjustment;
- GTK_DISPLAY_PANEL_GET_CLASS(panel)->compute_size(panel, &req, NULL);
+ gtk_widget_get_preferred_width(GTK_WIDGET(panel), &req, NULL);
allocated = allocation.width;
}
@@ -695,7 +718,7 @@ static void gtk_display_panel_update_adjustment(GtkDisplayPanel *panel, GtkOrien
{
adj = panel->vadjustment;
- GTK_DISPLAY_PANEL_GET_CLASS(panel)->compute_size(panel, NULL, &req);
+ gtk_widget_get_preferred_height(GTK_WIDGET(panel), &req, NULL);
allocated = allocation.height;
}
@@ -739,6 +762,73 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDi
/******************************************************************************
* *
* Paramètres : panel = composant GTK à mettre à jour. *
+* *
+* Description : Indique l'échelle appliquée à l'affichage du composant. *
+* *
+* Retour : Echelle appliquée à l'affichage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+double gtk_display_panel_get_scale(const GtkDisplayPanel *panel)
+{
+ double result; /* Echelle à retourner */
+
+ result = panel->scale;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK à mettre à jour. *
+* scale = échelle appliquée à l'affichage. *
+* *
+* Description : Spécifie l'échelle à appliquer à l'affichage du composant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_display_panel_set_scale(GtkDisplayPanel *panel, double scale)
+{
+ double old_scale; /* Echelle précédente */
+ GtkDisplayPanelClass *class; /* Classe associée au composant*/
+
+ if (scale > 1.0)
+ scale = 1.0;
+
+ else if (scale < 0.01)
+ scale = 0.01;
+
+ if (panel->scale != scale)
+ {
+ old_scale = panel->scale;
+
+ panel->scale = scale;
+
+ class = GTK_DISPLAY_PANEL_GET_CLASS(panel);
+
+ if (class->scale != NULL)
+ class->scale(panel, old_scale, scale);
+
+ gtk_widget_queue_resize(GTK_WIDGET(panel));
+
+ g_signal_emit_by_name(panel, "scaled", old_scale, scale);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK à mettre à jour. *
* show = état de l'affichage auquel parvenir. *
* *
* Description : Définit si une bordure est à afficher. *
@@ -785,9 +875,9 @@ void gtk_display_panel_prepare_export(GtkDisplayPanel *panel, bool export)
/******************************************************************************
* *
-* Paramètres : panel = composant GTK à venir consulter. *
-* cr = contexte graphique associé à l'événement. *
-* offset = décalage éventuel à appliquer. *
+* Paramètres : panel = composant GTK à venir consulter. *
+* cr = contexte graphique associé à l'événement. *
+* area = surface à considérer. *
* *
* Description : Définit un chemin décrivant la bordure autour du panneau. *
* *
@@ -797,35 +887,32 @@ void gtk_display_panel_prepare_export(GtkDisplayPanel *panel, bool export)
* *
******************************************************************************/
-void gtk_display_panel_define_border_path(GtkDisplayPanel *panel, cairo_t *cr, gint off_x, gint off_y)
+void gtk_display_panel_define_border_path(GtkDisplayPanel *panel, cairo_t *cr, const GtkAllocation *area)
{
- 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,
+ area->x + area->width - BORDER_CORNER_RADIUS - 0.5,
+ area->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,
+ area->x + area->width - BORDER_CORNER_RADIUS - 0.5,
+ area->y + area->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,
+ area->x + BORDER_CORNER_RADIUS + 0.5,
+ area->y + area->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,
+ area->x + BORDER_CORNER_RADIUS + 0.5,
+ area->y + BORDER_CORNER_RADIUS + 0.5,
BORDER_CORNER_RADIUS, 180 * degrees, 270 * degrees);
cairo_close_path(cr);
@@ -849,9 +936,10 @@ void gtk_display_panel_define_border_path(GtkDisplayPanel *panel, cairo_t *cr, g
void gtk_display_panel_draw_border(GtkDisplayPanel *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 */
+ GtkRequisition req; /* Taille allouée à l'élément */
+ GtkAllocation area; /* Emplacement à considérer */
if (panel->show_border)
{
@@ -873,7 +961,14 @@ void gtk_display_panel_draw_border(GtkDisplayPanel *panel, cairo_t *cr)
cairo_set_line_width(cr, 1.0);
- gtk_display_panel_define_border_path(panel, cr, 0, 0);
+ gtk_widget_get_preferred_size(GTK_WIDGET(panel), NULL, &req);
+
+ area.x = 0;
+ area.y = 0;
+ area.width = req.width;
+ area.height = req.height;
+
+ gtk_display_panel_define_border_path(panel, cr, &area);
cairo_stroke(cr);
gtk_style_context_restore(context);
diff --git a/src/gtkext/gtkdisplaypanel.h b/src/gtkext/gtkdisplaypanel.h
index 937d41d..9f58b87 100644
--- a/src/gtkext/gtkdisplaypanel.h
+++ b/src/gtkext/gtkdisplaypanel.h
@@ -52,6 +52,12 @@ typedef struct _GtkDisplayPanelClass GtkDisplayPanelClass;
/* Détermine le type du composant d'affichage générique. */
GType gtk_display_panel_get_type(void);
+/* Indique l'échelle appliquée à l'affichage du composant. */
+double gtk_display_panel_get_scale(const GtkDisplayPanel *);
+
+/* Spécifie l'échelle à appliquer à l'affichage du composant. */
+void gtk_display_panel_set_scale(GtkDisplayPanel *, double);
+
/* Définit si une bordure est à afficher. */
void gtk_display_panel_show_border(GtkDisplayPanel *, bool);
diff --git a/src/gtkext/gtkgraphdisplay.c b/src/gtkext/gtkgraphdisplay.c
index 97bb4d3..aeecc0f 100644
--- a/src/gtkext/gtkgraphdisplay.c
+++ b/src/gtkext/gtkgraphdisplay.c
@@ -146,6 +146,9 @@ static GLineCursor *gtk_graph_display_get_cursor(const GtkGraphDisplay *);
/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
static void gtk_graph_display_cache_glance(GtkGraphDisplay *, cairo_t *, const GtkAllocation *, double);
+/* Spécifie l'échelle à appliquer à l'affichage du composant. */
+static void gtk_graph_display_apply_scale(GtkGraphDisplay *, double, double);
+
/* Marque ou non le composant pour une exportation prochaine. */
static void gtk_graph_display_prepare_export(GtkGraphDisplay *, bool);
@@ -205,6 +208,8 @@ static void gtk_graph_display_class_init(GtkGraphDisplayClass *class)
panel_class->get_cursor = (get_cursor_fc)gtk_graph_display_get_cursor;
panel_class->cache_glance = (cache_glance_fc)gtk_graph_display_cache_glance;
+ panel_class->scale = (apply_scale_fc)gtk_graph_display_apply_scale;
+
panel_class->prepare_export = (prepare_export_fc)gtk_graph_display_prepare_export;
}
@@ -470,16 +475,23 @@ static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *display, GtkA
static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphDisplay *display)
{
+ GtkDisplayPanel *parent; /* Autre version du composant */
cairo_surface_t *pat_image; /* Fond du futur pinceau */
cairo_t *pat_cr; /* Pinceau pour le pinceau */
cairo_pattern_t *pattern; /* Patron de remplissage */
double degrees; /* Conversion en degrés */
size_t i; /* Boucle de parcours */
+ parent = GTK_DISPLAY_PANEL(display);
+
/* Eventuel fond pour la zone de compression */
if (display->may_collapsing && !GTK_DISPLAY_PANEL(display)->export)
{
+ cairo_save(cr);
+
+ cairo_scale(cr, parent->scale, parent->scale);
+
/* Préparation du pinceau */
pat_image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
@@ -555,13 +567,21 @@ static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphD
cairo_surface_destroy(pat_image);
+ cairo_restore(cr);
+
}
/* Dessin des ombres */
+ cairo_save(cr);
+
+ cairo_scale(cr, parent->scale, parent->scale);
+
void draw_shadow(GtkWidget *child, gpointer unused)
{
+ GGraphCluster *cluster; /* Cluster correspondant */
GtkAllocation alloc; /* Emplacement de l'enfant */
+ GtkAllocation area; /* Emplacement à considérer */
gint j; /* Boucle de parcours */
cairo_pattern_t *pattern; /* Zones d'application */
@@ -569,19 +589,30 @@ static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphD
if (!GTK_IS_DISPLAY_PANEL(child))
return;
- gtk_widget_get_allocation(child, &alloc);
+ cluster = g_graph_cluster_find_by_widget(display->cluster, child);
+ assert(cluster != NULL);
+
+ g_graph_cluster_get_allocation(cluster, &alloc);
+
+ alloc.x += GRAPH_MARGIN;
+ alloc.y += GRAPH_MARGIN;
+
+ area = alloc;
for (j = 1; j < SHADOW_SIZE; j++)
{
cairo_push_group(cr);
- gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, alloc.x + j, alloc.y + j);
+ area.x = alloc.x + j;
+ area.y = alloc.y + j;
+
+ gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, &area);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_fill(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, alloc.x, alloc.y);
+ gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, &alloc);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
cairo_fill(cr);
@@ -602,6 +633,8 @@ static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphD
for (i = 0; i < display->edges_count; i++)
g_graph_edge_draw(display->edges[i], cr, true, display->hl_edge_index == i);
+ cairo_restore(cr);
+
return FALSE;
}
@@ -710,6 +743,7 @@ static gboolean gtk_graph_display_motion_notify(GtkWidget *widget, GdkEventMotio
GtkAdjustment *hadj; /* Gestionnaire du défilement */
GtkAdjustment *vadj; /* Gestionnaire du défilement */
gdouble value; /* Nouvelle valeur bornée */
+ double scale; /* Echelle appliquée au rendu */
size_t i; /* Boucle de parcours */
/* Déplacement du graphique ? */
@@ -739,8 +773,10 @@ static gboolean gtk_graph_display_motion_notify(GtkWidget *widget, GdkEventMotio
/* Survol d'un lien ? */
else
{
+ scale = GTK_DISPLAY_PANEL(display)->scale;
+
for (i = 0; i < display->edges_count; i++)
- if (g_graph_edge_detect_at(display->edges[i], event->x, event->y))
+ if (g_graph_edge_detect_at(display->edges[i], event->x / scale, event->y / scale))
{
display->hl_edge_index = i;
break;
@@ -1131,21 +1167,28 @@ static GLineCursor *gtk_graph_display_get_cursor(const GtkGraphDisplay *display)
static void gtk_graph_display_cache_glance(GtkGraphDisplay *display, cairo_t *cr, const GtkAllocation *area, double scale)
{
+ GtkDisplayPanel *parent; /* Autre version du composant */
size_t i; /* Boucle de parcours */
+ parent = GTK_DISPLAY_PANEL(display);
+
+ cairo_scale(cr, scale * parent->scale, scale * parent->scale);
+
void draw_child_glance(GtkWidget *child, gpointer unused)
{
+ GGraphCluster *cluster; /* Cluster correspondant */
GtkAllocation sub_area; /* Emplacement réservé */
if (!GTK_IS_BUFFER_DISPLAY(child))
return;
- gtk_widget_get_allocation(child, &sub_area);
+ cluster = g_graph_cluster_find_by_widget(display->cluster, child);
+ assert(cluster != NULL);
- sub_area.x *= scale;
- sub_area.y *= scale;
- sub_area.width = sub_area.width * scale + 1;
- sub_area.height = sub_area.height * scale + 1;
+ g_graph_cluster_get_allocation(cluster, &sub_area);
+
+ sub_area.x += GRAPH_MARGIN;
+ sub_area.y += GRAPH_MARGIN;
g_loaded_panel_cache_glance(G_LOADED_PANEL(child), cr, &sub_area, scale);
@@ -1153,8 +1196,6 @@ static void gtk_graph_display_cache_glance(GtkGraphDisplay *display, cairo_t *cr
gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_child_glance, NULL);
- cairo_scale(cr, scale, scale);
-
for (i = 0; i < display->edges_count; i++)
g_graph_edge_draw(display->edges[i], cr, false, false);
@@ -1164,6 +1205,68 @@ static void gtk_graph_display_cache_glance(GtkGraphDisplay *display, cairo_t *cr
/******************************************************************************
* *
* Paramètres : display = composant GTK à mettre à jour. *
+* old = ancienne échelle appliquée. *
+* new = nouvelle échelle à appliquer. *
+* *
+* Description : Spécifie l'échelle à appliquer à l'affichage du composant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_display_apply_scale(GtkGraphDisplay *display, double old, double new)
+{
+ GtkDisplayPanel *parent; /* Autre version du composant */
+ gint right; /* Abscisse du coin droit */
+ gint bottom; /* Ordonnée du coin inférieur */
+
+ /* Traitement des blocs */
+
+ void apply_child_scale(GtkWidget *child, gpointer unused)
+ {
+ GGraphCluster *cluster; /* Cluster correspondant */
+ GtkAllocation sub_area; /* Emplacement réservé */
+ gint x; /* Abscisse du point d'arrivée */
+ gint y; /* Ordonnée du point d'arrivée */
+
+ if (!GTK_IS_BUFFER_DISPLAY(child))
+ return;
+
+ cluster = g_graph_cluster_find_by_widget(display->cluster, child);
+ assert(cluster != NULL);
+
+ g_graph_cluster_get_allocation(cluster, &sub_area);
+
+ x = (GRAPH_MARGIN + sub_area.x) * new;
+ y = (GRAPH_MARGIN + sub_area.y) * new;
+
+ gtk_fixed_move(GTK_FIXED(display->support), child, x, y);
+
+ gtk_display_panel_set_scale(GTK_DISPLAY_PANEL(child), new);
+
+ }
+
+ gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)apply_child_scale, NULL);
+
+ /* Calcul du nouvel espace nécessaire */
+
+ parent = GTK_DISPLAY_PANEL(display);
+
+ gtk_graph_display_compute_requested_size(display, &right, &bottom);
+
+ right *= parent->scale;
+ bottom *= parent->scale;
+
+ gtk_fixed_move(GTK_FIXED(display->support), display->extender, right - 1, bottom - 1);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : display = composant GTK à mettre à jour. *
* export = préparation d'une exportation complète du rendu ? *
* *
* Description : Marque ou non le composant pour une exportation prochaine. *
@@ -1238,8 +1341,7 @@ GtkWidget *gtk_graph_display_get_support(GtkGraphDisplay *display)
* *
* Paramètres : display = composant GTK à mettre à jour. *
* widget = composant GTK à insérer. *
-* x = abscisse du point d'insertion. *
-* y = ordonnée du point d'insertion. *
+* alloc = position du point d'insertion. *
* *
* Description : Place une vue sous forme de bloc dans le graphique. *
* *
@@ -1261,7 +1363,6 @@ void gtk_graph_display_put(GtkGraphDisplay *display, GtkWidget *widget, const Gt
}
-
/******************************************************************************
* *
* Paramètres : display = composant GTK à mettre à jour. *
diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c
index aa89a13..d386362 100644
--- a/src/gui/menus/menubar.c
+++ b/src/gui/menus/menubar.c
@@ -309,7 +309,7 @@ static void change_menubar_current_view(GMenuBar *bar, GLoadedPanel *old, GLoade
rebuild_menu_view_for_view(bar->view, new);
- update_access_for_view_in_menu_view(G_EDITOR_ITEM(bar)->ref, new);
+ update_access_for_view_in_menu_view(new);
update_access_for_view_in_menu_binary(new);
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index 255f1d9..018cfbf 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -40,6 +40,7 @@
#include "../core/panels.h"
#include "../../analysis/loaded.h"
#include "../../gtkext/easygtk.h"
+#include "../../gtkext/gtkdisplaypanel.h"
#include "../../gtkext/gtkgraphdisplay.h"
@@ -65,6 +66,9 @@ static void handle_loaded_panel_first_allocation(GtkWidget *, GdkRectangle *, GL
/* Effectue la bascule d'un panneau de chargement à un autre. */
static void change_current_view_support(unsigned int);
+/* Réagit avec le menu "Affichage -> Zoom *". */
+static void mcb_view_zoom(GtkCheckMenuItem *, gpointer );
+
/* Réagit avec le menu "Affichage -> (colonne xxx)". */
static void mcb_view_display_column(GtkCheckMenuItem *, gpointer);
@@ -126,6 +130,28 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar)
/* Séparation */
submenuitem = qck_create_menu_separator();
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+ /* Zooms */
+
+ submenuitem = qck_create_menu_item(ref, "mnu_view_zoom_in", _("Zoom in"),
+ G_CALLBACK(mcb_view_zoom), GINT_TO_POINTER(0));
+ add_accelerator_to_widget(submenuitem, "<Ctrl>plus");
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+ submenuitem = qck_create_menu_item(ref, "mnu_view_zoom_out", _("Zoom out"),
+ G_CALLBACK(mcb_view_zoom), GINT_TO_POINTER(1));
+ add_accelerator_to_widget(submenuitem, "<Ctrl>minus");
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+ submenuitem = qck_create_menu_item(ref, "mnu_view_zoom_reset", _("Reset zoom"),
+ G_CALLBACK(mcb_view_zoom), GINT_TO_POINTER(2));
+ add_accelerator_to_widget(submenuitem, "<Ctrl>0");
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+ /* Séparation */
+
+ submenuitem = qck_create_menu_separator();
g_object_set_data(ref, "mnu_view_start_options", submenuitem);
gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
@@ -399,8 +425,7 @@ void rebuild_menu_view_for_view(GtkWidget *widget, GLoadedPanel *new)
/******************************************************************************
* *
-* Paramètres : ref = espace de référencements à consulter. *
-* panel = panneau d'affichage actif ou NULL si aucun. *
+* Paramètres : new = nouvelle vue du contenu chargé analysé. *
* *
* Description : Met à jour les accès du menu "Affichage" selon le contenu. *
* *
@@ -410,12 +435,31 @@ void rebuild_menu_view_for_view(GtkWidget *widget, GLoadedPanel *new)
* *
******************************************************************************/
-void update_access_for_view_in_menu_view(GObject *ref, GLoadedPanel *panel)
+void update_access_for_view_in_menu_view(GLoadedPanel *new)
{
+ GObject *ref; /* Espace de référencements */
+ gboolean access; /* Accès à déterminer */
+ GtkWidget *item; /* Elément de menu à traiter */
+
+ ref = get_global_ref();
+
/* Bascules */
update_switch_access_in_menu_view();
+ /* Zooms */
+
+ access = GTK_IS_GRAPH_DISPLAY(new);
+
+ item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_in"));
+ gtk_widget_set_sensitive(item, access);
+
+ item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_out"));
+ gtk_widget_set_sensitive(item, access);
+
+ item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_reset"));
+ gtk_widget_set_sensitive(item, access);
+
}
@@ -843,6 +887,49 @@ static void change_current_view_support(unsigned int wanted)
/******************************************************************************
* *
+* Paramètres : menuitem = élément de menu sélectionné. *
+* data = données indiquant la nature du zoom. *
+* *
+* Description : Réagit avec le menu "Affichage -> Zoom *". *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void mcb_view_zoom(GtkCheckMenuItem *menuitem, gpointer data)
+{
+ GtkDisplayPanel *panel; /* Afficheur effectif de code */
+ double scale; /* Echelle à appliquer */
+
+ panel = GTK_DISPLAY_PANEL(get_current_view());
+
+ scale = gtk_display_panel_get_scale(panel);
+
+ switch (GPOINTER_TO_INT(data))
+ {
+ case 0:
+ scale /= 1.25;
+ break;
+
+ case 1:
+ scale *= 1.25;
+ break;
+
+ case 2:
+ scale = 1.0;
+ break;
+
+ }
+
+ gtk_display_panel_set_scale(panel, scale);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : menuitem = élément de menu ayant basculé. *
* unused = adresse non utilisée ici. *
* *
diff --git a/src/gui/menus/view.h b/src/gui/menus/view.h
index 2271d4c..d3d70ab 100644
--- a/src/gui/menus/view.h
+++ b/src/gui/menus/view.h
@@ -44,7 +44,7 @@ void rebuild_menu_view_for_content(GtkWidget *, GLoadedContent *);
void rebuild_menu_view_for_view(GtkWidget *, GLoadedPanel *);
/* Met à jour les accès du menu "Affichage" selon le contenu. */
-void update_access_for_view_in_menu_view(GObject *, GLoadedPanel *);
+void update_access_for_view_in_menu_view(GLoadedPanel *);
/* Réagit avec le menu "Affichage -> Panneaux latéraux". */
void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *);