diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/gtksnippet.c | 135 | ||||
-rw-r--r-- | src/gtksnippet.h | 3 |
3 files changed, 115 insertions, 29 deletions
@@ -1,3 +1,9 @@ +2008-08-05 Cyrille Bagard <nocbos@gmail.com> + + * src/gtksnippet.c: + * src/gtksnippet.h: + Define a margin for setting breakpoints. + 2008-08-03 Cyrille Bagard <nocbos@gmail.com> * src/arch/x86/instruction.h: diff --git a/src/gtksnippet.c b/src/gtksnippet.c index 15696dc..7dc60f6 100644 --- a/src/gtksnippet.c +++ b/src/gtksnippet.c @@ -30,6 +30,7 @@ #define CONTENT_BUFFER_LEN 64 +#define MARGIN_SPACE 4 static void gtk_snippet_class_init(GtkSnippetClass *klass); @@ -39,9 +40,13 @@ static void gtk_snippet_size_request(GtkWidget *widget, static void gtk_snippet_size_allocate(GtkWidget *widget, GtkAllocation *allocation); static void gtk_snippet_realize(GtkWidget *widget); + + +static gboolean gtk_snippet_button_press(GtkSnippet *snippet, GdkEventButton *event, gpointer *data); + static gboolean gtk_snippet_expose(GtkWidget *widget, GdkEventExpose *event); -static void gtk_snippet_paint(GtkWidget *widget); +static void gtk_snippet_paint(GtkSnippet *snippet); static void gtk_snippet_destroy(GtkObject *object); @@ -98,6 +103,8 @@ gtk_snippet_class_init(GtkSnippetClass *klass) widget_class = (GtkWidgetClass *) klass; object_class = (GtkObjectClass *) klass; + + widget_class->button_press_event = gtk_snippet_button_press; widget_class->realize = gtk_snippet_realize; widget_class->size_request = gtk_snippet_size_request; widget_class->size_allocate = gtk_snippet_size_allocate; @@ -166,7 +173,7 @@ gtk_snippet_realize(GtkWidget *widget) attributes.height = widget->allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK; + attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK; attributes_mask = GDK_WA_X | GDK_WA_Y; @@ -192,6 +199,40 @@ gtk_snippet_realize(GtkWidget *widget) } +static gboolean gtk_snippet_button_press(GtkSnippet *snippet, GdkEventButton *event, gpointer *data) +{ + unsigned int index; /* Indice de la ligne visée */ + PangoLayoutIter *iter; /* Boucle de parcours */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ + + index = 0; + iter = pango_layout_get_iter(snippet->layout); + + for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) + { + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + if (y0 / PANGO_SCALE <= event->y && event->y < y1 / PANGO_SCALE) break; + } + + pango_layout_iter_free(iter); + + + if (event->x < (2 * MARGIN_SPACE + snippet->line_height)) + { + snippet->info[index].bp_set = !snippet->info[index].bp_set; + + /* TODO: regions */ + gtk_snippet_paint(snippet); + + } + + + return FALSE; + +} + + static gboolean gtk_snippet_expose(GtkWidget *widget, GdkEventExpose *event) @@ -207,41 +248,60 @@ gtk_snippet_expose(GtkWidget *widget, static void -gtk_snippet_paint(GtkWidget *widget) +gtk_snippet_paint(GtkSnippet *snippet) { - /* - cairo_t *cr; + GtkWidget *widget; /* Version GTK du composant */ + GdkGCValues values; /* Propriétés du contexte */ + GdkColor white; /* Couleur du fond */ + int width; /* Largeur de l'élément */ + int height; /* Hauteur de l'élément */ + GdkColor red; /* Couleur des arrêts */ + PangoLayoutIter *iter; /* Boucle de parcours */ + unsigned int index; /* Indice de la ligne visée */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ + + widget = GTK_WIDGET(snippet); + gdk_gc_get_values(snippet->gc, &values); - cr = gdk_cairo_create(widget->window); + gdk_color_white(gtk_widget_get_colormap(widget), &white); + gdk_gc_set_foreground(snippet->gc, &white); - cairo_translate(cr, 0, 7); + gtk_widget_get_size_request(widget, &width, &height); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_paint(cr); + gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, + TRUE, 0, 0, width, height); - gint pos = GTK_SNIPPET(widget)->sel; - gint rect = pos / 5; + gdk_color_parse("#ff0000", &red); + gdk_color_alloc(gtk_widget_get_colormap(widget), &red); + gdk_gc_set_foreground(snippet->gc, &red); - cairo_set_source_rgb(cr, 0.2, 0.4, 0); - gint i; - for ( i = 1; i <= 20; i++) { - if (i > 20 - rect) { - cairo_set_source_rgb(cr, 0.6, 1.0, 0); - } else { - cairo_set_source_rgb(cr, 0.2, 0.4, 0); - } - cairo_rectangle(cr, 8, i*4, 30, 3); - cairo_rectangle(cr, 42, i*4, 30, 3); - cairo_fill(cr); - } + index = 0; + iter = pango_layout_get_iter(snippet->layout); + + for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) + { + if (!snippet->info[index].bp_set) continue; + + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + - cairo_destroy(cr); - printf("rendering...\n"); - */ - gdk_draw_layout(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, - 0, 0, GTK_SNIPPET(widget)->layout); + gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, + FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, + snippet->line_height - 2, snippet->line_height - 2, + 0, 360 * 64); + + } + + pango_layout_iter_free(iter); + + gdk_gc_set_foreground(snippet->gc, &values.foreground); + + gdk_draw_layout(GDK_DRAWABLE(widget->window), snippet->gc, + 2 * MARGIN_SPACE + snippet->line_height, 0, + snippet->layout); } @@ -337,6 +397,7 @@ void gtk_snippet_add_line(GtkSnippet *snippet, uint64_t offset, asm_instr *instr snippet->info[snippet->info_count - 1].offset = offset; snippet->info[snippet->info_count - 1].instr = instr; snippet->info[snippet->info_count - 1].comment = (comment != NULL ? strdup(comment) : NULL); + snippet->info[snippet->info_count - 1].bp_set = FALSE; } @@ -362,6 +423,9 @@ void gtk_snippet_build_content(GtkSnippet *snippet) char buffer[CONTENT_BUFFER_LEN]; /* Zone tampon à utiliser */ int width; /* Largeur de l'objet actuelle */ int height; /* Hauteur de l'objet actuelle */ + PangoLayoutIter *iter; /* Boucle de parcours */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ content_len = strlen("<tt>") + 1; content = (char *)calloc(content_len, sizeof(char)); @@ -435,7 +499,20 @@ void gtk_snippet_build_content(GtkSnippet *snippet) pango_layout_set_markup(snippet->layout, content, content_len - 1); pango_layout_get_pixel_size(snippet->layout, &width, &height); - gtk_widget_set_size_request(GTK_WIDGET(snippet), width, height); + + snippet->line_height = 0; + iter = pango_layout_get_iter(snippet->layout); + + do + { + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + snippet->line_height = MAX(snippet->line_height, (y1 - y0) / PANGO_SCALE); + } + while (pango_layout_iter_next_line(iter)); + + pango_layout_iter_free(iter); + + gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height); } diff --git a/src/gtksnippet.h b/src/gtksnippet.h index e66eedc..349fd20 100644 --- a/src/gtksnippet.h +++ b/src/gtksnippet.h @@ -69,6 +69,8 @@ typedef struct _code_line_info asm_instr *instr; /* Eventuelle instruction */ char *comment; /* Eventuel commentaire */ + gboolean bp_set; /* Point d'arrêt défini */ + } code_line_info; @@ -80,6 +82,7 @@ struct _GtkSnippet { PangoLayout *layout; /* Moteur de rendu du code ASM */ GdkGC *gc; /* Contexte graphique du rendu */ + int line_height; /* Hauteur maximale des lignes */ const asm_processor *proc; /* Architecture utilisée */ code_line_info *info; /* Contenu à représenter */ |