From 30bc43ca00140bc215d6a1beb81ab5542e68d13b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 22 Oct 2009 22:41:50 +0000 Subject: Supported scrolling internally and thus fixed bugs with big binaries. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@132 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 19 ++++ src/graph/dot.c | 6 +- src/graph/dot.h | 2 +- src/graph/layout.c | 2 +- src/graph/node.c | 12 +- src/graph/node.h | 6 +- src/gtkext/gtkbinview-int.h | 17 +++ src/gtkext/gtkbinview.c | 143 +++++++++++++++++++++++- src/gtkext/gtkblockview.c | 260 +++++++++++++++++++++++++++++++++----------- src/gtkext/gtkgraphview.c | 183 +++++++++++++++++++++++++++++-- src/gtkext/gtkgraphview.h | 3 + 11 files changed, 560 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4560c9..626942f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +09-10-23 Cyrille Bagard + + * src/graph/dot.c: + * src/graph/dot.h: + * src/graph/layout.c: + * src/graph/node.c: + * src/graph/node.h: + Update calls and prototypes (mainly GtkFixed -> GtkGraphView). + + * src/gtkext/gtkbinview.c: + * src/gtkext/gtkbinview-int.h: + * src/gtkext/gtkblockview.c: + * src/gtkext/gtkgraphview.c: + * src/gtkext/gtkgraphview.h: + Support scrolling internally and thus fix bugs with big binaries. + + * src/project.c: + Remove the now useless view ports. + 09-10-12 Cyrille Bagard * src/arch/x86/instruction.c: diff --git a/src/graph/dot.c b/src/graph/dot.c index 9f8e3b3..27e60bc 100644 --- a/src/graph/dot.c +++ b/src/graph/dot.c @@ -132,7 +132,7 @@ void delete_graph_layout(graph_layout *layout) /****************************************************************************** * * * Paramètres : layout = graphique à supprimer de la mémoire. * -* fixed = support de destination. * +* view = support de destination. * * nodes = liste de noeuds à traiter. * * count = taille de la liste. * * * @@ -144,7 +144,7 @@ void delete_graph_layout(graph_layout *layout) * * ******************************************************************************/ -void place_nodes_of_graph_layout(const graph_layout *layout, GtkFixed *fixed, GGraphNode **nodes, size_t count) +void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view, GGraphNode **nodes, size_t count) { int height; /* Hauteur du graphique */ node_t *iter; /* Boucle de parcours */ @@ -158,7 +158,7 @@ void place_nodes_of_graph_layout(const graph_layout *layout, GtkFixed *fixed, GG printf(" pos :: (%d ; %d)\n", iter->u.coord.x, height - iter->u.coord.y); node = find_graph_node_by_name(nodes, count, iter->name); - g_graph_node_place(node, fixed, iter->u.coord.x, height - iter->u.coord.y); + g_graph_node_place(node, view, iter->u.coord.x, height - iter->u.coord.y); } } diff --git a/src/graph/dot.h b/src/graph/dot.h index 630c1cb..47550a8 100644 --- a/src/graph/dot.h +++ b/src/graph/dot.h @@ -41,7 +41,7 @@ graph_layout *create_graph_layout(char *); void delete_graph_layout(graph_layout *); /* Place tous les éléments du graphique à l'écran. */ -void place_nodes_of_graph_layout(const graph_layout *, GtkFixed *, GGraphNode **, size_t); +void place_nodes_of_graph_layout(const graph_layout *, GtkGraphView *, GGraphNode **, size_t); /* Charge la définition de tous les liens graphiques. */ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *, size_t *); diff --git a/src/graph/layout.c b/src/graph/layout.c index 0b4a6c6..667074b 100644 --- a/src/graph/layout.c +++ b/src/graph/layout.c @@ -92,7 +92,7 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count) /* Affichage du graphique */ - place_nodes_of_graph_layout(layout, GTK_FIXED(view), nodes, count); + place_nodes_of_graph_layout(layout, view, nodes, count); links = create_links_from_graph_layout(layout, &links_count); gtk_graph_view_attach_links(view, links, links_count); diff --git a/src/graph/node.c b/src/graph/node.c index e6427d8..09cfe30 100644 --- a/src/graph/node.c +++ b/src/graph/node.c @@ -223,10 +223,10 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds) /****************************************************************************** * * -* Paramètres : node = intermédiaire à consulter. * -* fixed = support de destination. * -* x = abscisse du point d'intégration. * -* y = ordonnée du point d'intégration. * +* Paramètres : node = intermédiaire à consulter. * +* view = support de destination. * +* x = abscisse du point d'intégration. * +* y = ordonnée du point d'intégration. * * * * Description : Place le morceau de code de l'intermédiaire à l'écran. * * * @@ -236,7 +236,7 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds) * * ******************************************************************************/ -void g_graph_node_place(const GGraphNode *node, GtkFixed *fixed, gint x, gint y) +void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint y) { GtkRequisition requisition; /* Taille à l'écran actuelle */ @@ -245,7 +245,7 @@ void g_graph_node_place(const GGraphNode *node, GtkFixed *fixed, gint x, gint y) x -= requisition.width / 2; y -= requisition.height / 2; - gtk_fixed_put(fixed, GTK_WIDGET(node->view), x, y); + gtk_graph_view_put(view, GTK_WIDGET(node->view), x, y); } diff --git a/src/graph/node.h b/src/graph/node.h index 456e236..4998553 100644 --- a/src/graph/node.h +++ b/src/graph/node.h @@ -25,10 +25,8 @@ #define _GRAPH_NODE_H -#include - - #include "../gtkext/gtkbinview.h" +#include "../gtkext/gtkgraphview.h" @@ -59,7 +57,7 @@ GGraphNode *g_graph_node_new(GtkBinView *); char *g_graph_node_register_for_dot(const GGraphNode *, char *); /* Place le morceau de code de l'intermédiaire à l'écran. */ -void g_graph_node_place(const GGraphNode *, GtkFixed *, gint , gint); +void g_graph_node_place(const GGraphNode *, GtkGraphView *, gint , gint); diff --git a/src/gtkext/gtkbinview-int.h b/src/gtkext/gtkbinview-int.h index e785bab..ab72a84 100644 --- a/src/gtkext/gtkbinview-int.h +++ b/src/gtkext/gtkbinview-int.h @@ -33,6 +33,9 @@ +/* Réagit à un défilement quelconque. */ +typedef void (* scroll_fc) (GtkBinView *); + /* Définit les lignes à associer à la représentation. */ typedef void (* set_rendering_lines_fc) (GtkBinView *, GRenderingLine *, GRenderingLine *); @@ -47,6 +50,9 @@ struct _GtkBinView { GtkFixed parent; /* A laisser en premier */ + GtkAdjustment *hadjustment; /* Barre de défilement horiz. */ + GtkAdjustment *vadjustment; /* Barre de défilement vert. */ + GdkGC *gc; /* Contexte graphique du rendu */ bool show_border; /* Affichage d'une bordure ? */ @@ -56,6 +62,7 @@ struct _GtkBinView GRenderingLine *lines; /* Contenu à représenter */ GRenderingLine *last; /* Dernière ligne associée */ + scroll_fc scroll; /* Défilement du contenu */ set_rendering_lines_fc set_lines; /* Association des lignes */ define_main_address_fc define_address; /* Sélection externe d'adresse */ get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */ @@ -68,10 +75,20 @@ struct _GtkBinViewClass /* Signaux */ + void (* set_scroll_adjustments) (GtkBinView *, GtkAdjustment *, GtkAdjustment *); + void (* lines_set) (GtkBinView *); }; +/* Calcule la surface pleine utilisable pour la vue. */ +void gtk_bin_view_compute_allocation(GtkBinView *, GtkAllocation *); + +/* S'assure que la valeur de défilement actuelle est valable. */ +void gtk_bin_view_reclamp_adjustment(GtkAdjustment *, gboolean *); + + + #endif /* _GTKEXT_GTKBINVIEW_INT_H */ diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c index 147a59c..0a9ce6e 100644 --- a/src/gtkext/gtkbinview.c +++ b/src/gtkext/gtkbinview.c @@ -25,9 +25,12 @@ #include "gtkbinview-int.h" +#include "iodamarshal.h" +/* Enregistrement les défilements à associer au composant GTK. */ +static void gtk_binview_set_scroll_adjustments(GtkBinView *, GtkAdjustment *, GtkAdjustment *); /* Encadre la construction graphique initiale de la visualisation. */ static void gtk_bin_view_realize(GtkWidget *); @@ -35,6 +38,8 @@ static void gtk_bin_view_realize(GtkWidget *); /* Met à jour l'affichage de la visualisation de code binaire. */ static gboolean gtk_bin_view_expose(GtkBinView *, GdkEventExpose *); +/* Prend acte d'un nouveau défilement. */ +static void gtk_bin_view_adj_value_changed(GtkAdjustment *, GtkBinView *); @@ -68,6 +73,19 @@ static void gtk_binview_class_init(GtkBinViewClass *class) widget_class->realize = gtk_bin_view_realize; widget_class->expose_event = gtk_bin_view_expose; + class->set_scroll_adjustments = gtk_binview_set_scroll_adjustments; + + widget_class->set_scroll_adjustments_signal = + g_signal_new(("set_scroll_adjustments"), + GTK_TYPE_BIN_VIEW, + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET(GtkBinViewClass, set_scroll_adjustments), + NULL, NULL, + g_cclosure_user_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_ADJUSTMENT, + GTK_TYPE_ADJUSTMENT); + g_signal_new("lines-set", GTK_TYPE_BIN_VIEW, G_SIGNAL_RUN_LAST, @@ -81,6 +99,34 @@ static void gtk_binview_class_init(GtkBinViewClass *class) /****************************************************************************** * * +* Paramètres : view = vue à compléter. * +* hadjustment = nouveau défilement horizontal à intégrer. * +* vadjustment = nouveau défilement vertical à intégrer. * +* * +* Description : Enregistrement les défilements à associer au composant GTK. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binview_set_scroll_adjustments(GtkBinView *view, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment) +{ + view->hadjustment = hadjustment; + view->vadjustment = vadjustment; + + g_signal_connect(hadjustment, "value_changed", + G_CALLBACK(gtk_bin_view_adj_value_changed), view); + + g_signal_connect(vadjustment, "value_changed", + G_CALLBACK(gtk_bin_view_adj_value_changed), view); + +} + + +/****************************************************************************** +* * * Paramètres : view = composant GTK à initialiser. * * * * Description : Procède à l'initialisation de l'afficheur de morceaux. * @@ -205,6 +251,96 @@ static gboolean gtk_bin_view_expose(GtkBinView *view, GdkEventExpose *event) } +/****************************************************************************** +* * +* Paramètres : view = composant GTK à consulter. * +* alloc = étendue à accorder à la vue. * +* * +* Description : Calcule la surface pleine utilisable pour la vue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_bin_view_compute_allocation(GtkBinView *view, GtkAllocation *alloc) +{ + GtkWidget *widget; /* Autre version de la vue */ + GtkAllocation *allocation; /* Raccourci d'utilisation #1 */ + gint border_width; /* Raccourci d'utilisation #2 */ + + widget = GTK_WIDGET(view); + allocation = &widget->allocation; + border_width = GTK_CONTAINER(view)->border_width; + + alloc->x = 0; + alloc->y = 0; + + /* + if (viewport->shadow_type != GTK_SHADOW_NONE) + { + alloc->x = widget->style->xthickness; + alloc->y = widget->style->ythickness; + } + */ + + 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 : adj = valeurs de défilement à consulter. * +* changed = note une mise à jour de valeur. [OUT] * +* * +* Description : S'assure que la valeur de défilement actuelle est valable. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_bin_view_reclamp_adjustment(GtkAdjustment *adj, gboolean *changed) +{ + gdouble value; /* Valeur actuelle */ + + value = adj->value; + + value = CLAMP(value, 0, adj->upper - adj->page_size); + + if (value != adj->value) + { + adj->value = value; + *changed = TRUE; + } + else *changed = FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : adj = défilement à l'origine de l'action. * +* view = composant GTK à redessiner. * +* * +* Description : Prend acte d'un nouveau défilement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_bin_view_adj_value_changed(GtkAdjustment *adj, GtkBinView *view) +{ + view->scroll(view); + +} + /****************************************************************************** * * @@ -432,7 +568,6 @@ void gtk_bin_view_scroll_to_address(GtkBinView *view, vmpa_t addr) { gint x; /* Abscisse à garantir */ gint y; /* Ordonnée à garantir */ - GtkViewport *support; /* Support avec défilements */ GtkAdjustment *adj; /* Défilement à mettre à jour */ if (view->define_address != NULL) @@ -440,16 +575,14 @@ void gtk_bin_view_scroll_to_address(GtkBinView *view, vmpa_t addr) if (view->get_coordinates(view, addr, &x, &y)) { - support = GTK_VIEWPORT(gtk_widget_get_parent(GTK_WIDGET(view))); - - adj = gtk_viewport_get_hadjustment(support); + adj = view->hadjustment; if (x > (adj->upper - adj->page_size)) x = adj->upper - adj->page_size; gtk_adjustment_set_value(adj, x); - adj = gtk_viewport_get_vadjustment(support); + adj = view->vadjustment; if (y > (adj->upper - adj->page_size)) y = adj->upper - adj->page_size; diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c index 0a23317..a79b3ff 100644 --- a/src/gtkext/gtkblockview.c +++ b/src/gtkext/gtkblockview.c @@ -153,13 +153,21 @@ gtk_text_view2_set_attributes_from_style (GtkTextAttributes *values, /* Procède à l'initialisation de l'afficheur d'un bloc binaire. */ static void gtk_block_view_init(GtkBlockView *); - - /* Encadre la construction graphique initiale de la visualisation. */ static void gtk_block_view_realize(GtkWidget *); +/* Fournit la taille de composant requise pour un plein rendu. */ +static void gtk_block_view_size_request(GtkWidget *, GtkRequisition *); + +/* S'adapte à la surface concédée par le composant parent. */ +static void gtk_block_view_size_allocate(GtkWidget *, GtkAllocation *); + + +/* Réagit à un défilement quelconque. */ +static void gtk_block_view_scroll(GtkBlockView *); + /* Définit les lignes du bloc de représentation. */ static void gtk_block_view_set_rendering_lines(GtkBlockView *, GRenderingLine *, GRenderingLine *); @@ -191,9 +199,6 @@ static bool gtk_block_view_get_address_coordinates(const GtkBlockView *, vmpa_t, static void gtk_block_view_class_init(GtkBlockViewClass *klass); -static void gtk_block_view_init(GtkBlockView *cpu); -static void gtk_block_view_size_request(GtkWidget *widget, - GtkRequisition *requisition); static void gtk_block_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation); @@ -203,6 +208,8 @@ static gboolean gtk_block_view_button_press(GtkWidget *, GdkEventButton *event); /* Met à jour l'affichage de la vue sous forme de bloc. */ static gboolean gtk_block_view_expose(GtkWidget *, GdkEventExpose *); + + static void gtk_block_view_destroy(GtkObject *object); @@ -480,6 +487,7 @@ static void gtk_block_view_init(GtkBlockView *view) binview = GTK_BIN_VIEW(view); + binview->scroll = (scroll_fc)gtk_block_view_scroll; binview->set_lines = (set_rendering_lines_fc)gtk_block_view_set_rendering_lines; binview->get_coordinates = (get_addr_coordinates_fc)gtk_block_view_get_address_coordinates; @@ -531,7 +539,7 @@ static void gtk_block_view_init(GtkBlockView *view) style->left_margin = 10; style->right_margin = 10; - style->wrap_mode = GTK_WRAP_WORD; + style->wrap_mode = GTK_WRAP_NONE; style->justification = GTK_JUSTIFY_LEFT; style->direction = gtk_widget_get_direction(view); @@ -544,49 +552,11 @@ static void gtk_block_view_init(GtkBlockView *view) //gtk_text_layout_get_size (GTK_BLOCK_VIEW(view)->layout, &width, &height); - gtk_text_layout_set_screen_width (GTK_BLOCK_VIEW(view)->layout, - MAX (1, 1000)); - } } - -static void -gtk_block_view_size_request(GtkWidget *widget, - GtkRequisition *requisition) -{ - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); - g_return_if_fail(requisition != NULL); - - requisition->width = 80; - requisition->height = 100; -} - - -static void -gtk_block_view_size_allocate(GtkWidget *widget, - GtkAllocation *allocation) -{ - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_BLOCK_VIEW(widget)); - g_return_if_fail(allocation != NULL); - - widget->allocation = *allocation; - - if (GTK_WIDGET_REALIZED(widget)) { - gdk_window_move_resize( - widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height - ); - } -} - - - /****************************************************************************** * * * Paramètres : widget = composant GTK à redessiner. * @@ -615,6 +585,101 @@ static void gtk_block_view_realize(GtkWidget *widget) } +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à consulter. * +* requisition = dimensions souhaitées. [OUT] * +* * +* Description : Fournit la taille de composant requise pour un plein rendu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_view_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + gtk_text_layout_get_size(GTK_BLOCK_VIEW(widget)->layout, + &requisition->width, &requisition->height); + +} + + +/****************************************************************************** +* * +* 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_block_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkBinView *view; /* Autre version du composant */ + 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 */ + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED(widget)) + gdk_window_move_resize(widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + view = GTK_BIN_VIEW(widget); + + if (view->hadjustment == NULL || view->vadjustment == NULL) + return; + + gtk_text_layout_get_size(GTK_BLOCK_VIEW(view)->layout, &width, &height); + + gtk_bin_view_compute_allocation(view, &valloc); + + /* Défilement horizontal */ + + view->hadjustment->page_size = valloc.width; + view->hadjustment->step_increment = valloc.width * 0.1; + view->hadjustment->page_increment = valloc.width * 0.9; + + view->hadjustment->upper = MAX(width, valloc.width); + + gtk_bin_view_reclamp_adjustment(view->hadjustment, &changed); + + gtk_adjustment_changed(view->hadjustment); + + if (changed) + gtk_adjustment_value_changed(view->hadjustment); + + /* Défilement vertical */ + + view->vadjustment->page_size = valloc.height; + view->vadjustment->step_increment = GTK_BLOCK_VIEW(view)->line_height; + view->vadjustment->page_increment = view->vadjustment->step_increment * 10.0; + + view->vadjustment->upper = MAX(height, valloc.height); + + gtk_bin_view_reclamp_adjustment(view->vadjustment, &changed); + + gtk_adjustment_changed(view->vadjustment); + + if (changed) + gtk_adjustment_value_changed(view->vadjustment); + +} + + + + static gboolean gtk_block_view_button_press(GtkWidget *widget, GdkEventButton *event) { gboolean result; /* Décision à retourner */ @@ -682,20 +747,67 @@ void gtk_block_view_update_margin(GRenderingLine *line, GtkBlockView *view) * * * Description : Met à jour l'affichage de la vue sous forme de bloc. * * * -* Retour : FALSE pour poursuivre la propagation de l'événement. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) +static void gtk_block_view_compute_fake_coord(GtkBlockView *view, gint *x, gint *y) +{ + if (GTK_BIN_VIEW(view)->hadjustment != NULL) + *x -= gtk_adjustment_get_value(GTK_BIN_VIEW(view)->hadjustment); + + if (GTK_BIN_VIEW(view)->vadjustment != NULL) + *y += gtk_adjustment_get_value(GTK_BIN_VIEW(view)->vadjustment); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à redessiner. * +* event = informations liées à l'événement. * +* * +* Description : Met à jour l'affichage de la vue sous forme de bloc. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_view_compute_real_coord(GtkBlockView *view, gint *x, gint *y) { - GtkBlockView *view; + if (GTK_BIN_VIEW(view)->hadjustment != NULL) + *x += gtk_adjustment_get_value(GTK_BIN_VIEW(view)->hadjustment); + + if (GTK_BIN_VIEW(view)->vadjustment != NULL) + *y -= gtk_adjustment_get_value(GTK_BIN_VIEW(view)->vadjustment); + +} - //GtkWidget *widget; /* Autre version du composant */ +/****************************************************************************** +* * +* Paramètres : view = composant GTK à redessiner. * +* event = informations liées à l'événement. * +* * +* Description : Met à jour l'affichage de la vue sous forme de bloc. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) +{ + GtkBlockView *view; /* Autre version du composant */ GtkBinView *bview; /* Autre version du composant */ GtkStyle *style; /* Style associé au composant */ + gint fake_x; /* Abscisse virtuelle */ + gint fake_y; /* Ordonnée virtuelle */ GtkBinViewClass *parent_class; /* Version pure du parent */ GtkTextIter iter; /* Point d'insertion */ GdkRectangle rect; /* Zone d'un point */ @@ -726,22 +838,22 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) style = gtk_widget_get_style(GTK_WIDGET(view)); - - //gtk_widget_get_size_request(widget, &width, &height); - + fake_x = 0; + fake_y = 0; + gtk_block_view_compute_fake_coord(view, &fake_x, &fake_y); /* Dessin de la marge gauche */ gdk_gc_set_foreground(bview->gc, &style->mid[GTK_WIDGET_STATE(widget)]); gdk_draw_rectangle(GDK_DRAWABLE(widget->window), bview->gc, TRUE, - 0, event->area.y, view->left_margin, event->area.y + event->area.height); + fake_x, event->area.y, view->left_margin, event->area.y + event->area.height); gdk_gc_set_foreground(bview->gc, &style->dark[GTK_WIDGET_STATE(widget)]); gdk_draw_line(GDK_DRAWABLE(widget->window), bview->gc, - view->left_margin, event->area.y, - view->left_margin, event->area.y + event->area.height); + fake_x + view->left_margin, event->area.y, + fake_x + view->left_margin, event->area.y + event->area.height); /* Eventuelle bordure globale */ @@ -751,11 +863,13 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) /* Informations individuelles des lignes */ - gtk_text_layout_get_line_at_y(view->layout, &iter, event->area.y, NULL); + gtk_text_layout_get_line_at_y(view->layout, &iter, fake_y, NULL); gtk_text_layout_get_iter_location(view->layout, &iter, &rect); - while (rect.y < (event->area.y + event->area.height)) + while (rect.y < (fake_y + event->area.height)) { + gtk_block_view_compute_real_coord(view, &rect.x, &rect.y); + mark = gtk_text_iter_get_marks(&iter)->data; line = g_object_get_data(G_OBJECT(mark), "line"); @@ -770,7 +884,7 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) else pixbuf = NULL; if (pixbuf != NULL) - gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), bview->gc, pixbuf, 0, 0, 10, rect.y, + gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), bview->gc, pixbuf, 0, 0, fake_x + 10, rect.y, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), GDK_RGB_DITHER_NORMAL, 0, 0); @@ -779,7 +893,7 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) { pixbuf = GTK_BLOCK_VIEW_GET_CLASS(view)->entry_pix; - gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), bview->gc, pixbuf, 0, 0, 10, rect.y, + gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), bview->gc, pixbuf, 0, 0, fake_x + 10, rect.y, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), GDK_RGB_DITHER_NORMAL, 0, 0); @@ -792,17 +906,10 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) /* Impression du désassemblage */ - - gtk_text_layout_set_screen_width (GTK_BLOCK_VIEW(bview)->layout, - MAX (1, 1000)); - - - gtk_text_layout_draw(GTK_BLOCK_VIEW(bview)->layout, widget, GDK_DRAWABLE(widget->window), - NULL, view->left_text, 0, event->area.x, event->area.y, + NULL, -fake_x + view->left_text, fake_y, event->area.x, event->area.y, event->area.width, event->area.height, &child_exposes); - gdk_window_end_paint(GDK_DRAWABLE(widget->window)); return TRUE; @@ -810,6 +917,8 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event) } + + static void gtk_block_view_destroy(GtkObject *object) { @@ -903,6 +1012,25 @@ void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format) /****************************************************************************** * * * Paramètres : view = composant GTK à mettre à jour. * +* * +* Description : Réagit à un défilement quelconque. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_view_scroll(GtkBlockView *view) +{ + gtk_widget_queue_draw(GTK_WIDGET(view)); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * * lines = informations à intégrer. * * last = dernière ligne à intégrer ou NULL pour toutes. * * * diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index d62cc33..34e0e80 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -38,6 +38,9 @@ struct _GtkGraphView { GtkBinView parent; /* A laisser en premier */ + GtkFixed *support; /* Support des vues en bloc */ + + GtkRequisition requisition; /* Espace requis d'affichage */ vmpa_t start; /* Début de la portion vue */ vmpa_t end; /* Fin de la portion affichée */ @@ -68,12 +71,21 @@ 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 taille de composant requise pour un plein rendu. */ +static void gtk_graph_view_size_request(GtkWidget *, GtkRequisition *); + +/* 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_expose(GtkGraphView *, GdkEventExpose *); +static gboolean gtk_graph_view_expose(GtkWidget *, GdkEventExpose *, GtkGraphView *); /* Supprime tout contenu de l'afficheur de code en graphique. */ static void gtk_graph_view_reset(GtkGraphView *); +/* Réagit à un défilement quelconque. */ +static void gtk_graph_view_scroll(GtkGraphView *); + /* Définit les lignes du graphique de représentation. */ static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, GRenderingLine *); @@ -112,7 +124,8 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *klass) widget_class = (GtkWidgetClass *)klass; - widget_class->expose_event = gtk_graph_view_expose; + widget_class->size_request = gtk_graph_view_size_request; + widget_class->size_allocate = gtk_graph_view_size_allocate; } @@ -132,13 +145,28 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *klass) static void gtk_graph_view_init(GtkGraphView *view) { GtkBinView *binview; /* Instance parente */ + GdkColor white; /* Couleur de fond normale */ binview = GTK_BIN_VIEW(view); + binview->scroll = (scroll_fc)gtk_graph_view_scroll; binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines; binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address; binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; + view->support = GTK_FIXED(gtk_fixed_new()); + gtk_fixed_set_has_window(view->support, TRUE); + + g_signal_connect(G_OBJECT(view->support), "expose-event", + G_CALLBACK(gtk_graph_view_expose), view); + + gtk_widget_show(GTK_WIDGET(view->support)); + + gdk_color_white(gtk_widget_get_colormap(GTK_WIDGET(view->support)), &white); + gtk_widget_modify_bg(GTK_WIDGET(view->support), GTK_STATE_NORMAL, &white); + + gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->support), 0, 0); + view->mutex = g_mutex_new(); view->cond = g_cond_new(); @@ -147,6 +175,98 @@ static void gtk_graph_view_init(GtkGraphView *view) /****************************************************************************** * * +* Paramètres : widget = composant GTK à consulter. * +* requisition = dimensions souhaitées. [OUT] * +* * +* Description : Fournit la taille de composant requise pour un plein rendu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void gtk_graph_view_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + gpointer fixed_class; /* Classe parente */ + GtkGraphView *view; /* Autre vision du composant */ + + fixed_class = g_type_class_peek_parent(GTK_GRAPH_VIEW_GET_CLASS(widget)); + + GTK_WIDGET_CLASS(fixed_class)->size_request(GTK_FIXED(widget), requisition); + + view = GTK_GRAPH_VIEW(widget); + + if (view->requisition.width == 0 && view->requisition.height == 0) + view->requisition = *requisition; + +} + + +/****************************************************************************** +* * +* 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_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + gpointer fixed_class; /* Classe parente */ + GtkBinView *view; /* Autre version du composant */ + GtkAllocation valloc; /* Surface utilisable */ + gboolean changed; /* Changement de valeur ? */ + + /* Mise à jour GTK */ + + fixed_class = g_type_class_peek_parent(GTK_GRAPH_VIEW_GET_CLASS(widget)); + + GTK_WIDGET_CLASS(fixed_class)->size_allocate(GTK_FIXED(widget), allocation); + + view = GTK_BIN_VIEW(widget); + + gtk_bin_view_compute_allocation(view, &valloc); + + /* Défilement horizontal */ + + view->hadjustment->page_size = valloc.width; + view->hadjustment->step_increment = valloc.width * 0.1; + view->hadjustment->page_increment = valloc.width * 0.9; + + view->hadjustment->upper = MAX(GTK_GRAPH_VIEW(view)->requisition.width, valloc.width); + + gtk_bin_view_reclamp_adjustment(view->hadjustment, &changed); + + gtk_adjustment_changed(view->hadjustment); + + if (changed) + gtk_adjustment_value_changed(view->hadjustment); + + /* Défilement vertical */ + + view->vadjustment->page_size = valloc.height; + view->vadjustment->step_increment = valloc.width * 0.1; + view->vadjustment->page_increment = valloc.width * 0.9; + + view->vadjustment->upper = MAX(GTK_GRAPH_VIEW(view)->requisition.height, valloc.height); + + gtk_bin_view_reclamp_adjustment(view->vadjustment, &changed); + + gtk_adjustment_changed(view->vadjustment); + + if (changed) + gtk_adjustment_value_changed(view->vadjustment); + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Crée un nouveau composant pour l'affichage en graphique. * @@ -171,8 +291,9 @@ GtkWidget* gtk_graph_view_new(void) /****************************************************************************** * * -* Paramètres : view = composant GTK à redessiner. * -* event = informations liées à l'événement. * +* Paramètres : widget = composant GTK à redessiner. * +* event = informations liées à l'événement. * +* view = support maître à consulter. * * * * Description : Met à jour l'affichage de la vue sous forme graphique. * * * @@ -182,13 +303,13 @@ GtkWidget* gtk_graph_view_new(void) * * ******************************************************************************/ -static gboolean gtk_graph_view_expose(GtkGraphView *view, GdkEventExpose *event) +static gboolean gtk_graph_view_expose(GtkWidget *widget, GdkEventExpose *event, GtkGraphView *view) { size_t i; /* Boucle de parcours */ for (i = 0; i < view->links_count; i++) gtk_link_renderer_draw(view->links[i], - GDK_DRAWABLE(GTK_WIDGET(view)->window), + GDK_DRAWABLE(widget->window), GTK_BIN_VIEW(view)->gc); return FALSE; @@ -212,6 +333,9 @@ static void gtk_graph_view_reset(GtkGraphView *view) { size_t i; /* Boucle de parcours */ + view->requisition.width = 0; + view->requisition.height = 0; + view->start = 0; view->end = 0; @@ -247,6 +371,28 @@ static void gtk_graph_view_reset(GtkGraphView *view) + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* * +* Description : Réagit à un défilement quelconque. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_graph_view_scroll(GtkGraphView *view) +{ + gtk_fixed_move(GTK_FIXED(view), GTK_WIDGET(view->support), + -GTK_BIN_VIEW(view)->hadjustment->value, + -GTK_BIN_VIEW(view)->vadjustment->value); + +} + + /****************************************************************************** * * * Paramètres : view = composant GTK à mettre à jour. * @@ -322,7 +468,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) view->childs = gtk_graph_view_load_nodes(view, GTK_BIN_VIEW(view)->binary, first, last); - build_graph_view(GTK_FIXED(view), view->childs, view->childs_count); + build_graph_view(view, view->childs, view->childs_count); break; @@ -507,6 +653,29 @@ static void notify_graph_view(GtkBinView *view, GtkGraphView *parent) /****************************************************************************** * * +* Paramètres : view = composant GTK à mettre à jour. * +* widget = composant GTK à insérer. * +* x = abscisse du point d'insertion. * +* y = ordonnée du point d'insertion. * +* * +* Description : Place une vue sous forme de bloc dans le graphique. * +* * +* Retour : Plutôt que de redéfinir *toutes* les méthodes de * +* GtkContainer, on étend ! * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, gint x, gint y) +{ + gtk_fixed_put(view->support, widget, x, y); + +} + + +/****************************************************************************** +* * * Paramètres : view = composant GTK à mettre à jour. * * links = liens graphiques entre les blocs à intégrer. * * count = quantité de ces liens graphiques. * diff --git a/src/gtkext/gtkgraphview.h b/src/gtkext/gtkgraphview.h index 1d0c2ab..3706343 100644 --- a/src/gtkext/gtkgraphview.h +++ b/src/gtkext/gtkgraphview.h @@ -54,6 +54,9 @@ GType gtk_graph_view_get_type(void); /* Crée un nouveau composant pour l'affichage en graphique. */ GtkWidget* gtk_graph_view_new(void); +/* Place une vue sous forme de bloc dans le graphique. */ +void gtk_graph_view_put(GtkGraphView *, GtkWidget *, gint, gint); + /* Définit les liens graphiques à présenter avec la vue. */ void gtk_graph_view_attach_links(GtkGraphView *, GtkLinkRenderer **, size_t); -- cgit v0.11.2-87-g4458