From: Jorge Gorbe Date: Tue, 6 Nov 2012 19:03:54 +0000 (+0100) Subject: More improvements: X-Git-Url: http://slack.codemaniacs.com/git/?a=commitdiff_plain;h=e4bfa65f75276bd4a5dac6785d5967f028d1efd1;p=resacon2012.git More improvements: - Highlight pointed nodes if a pointer is selected in treeview - Expression text entry works - Arrow labels are correctly placed now :) --- diff --git a/samples/test4.cc b/samples/test4.cc index 607a0e9..576cab0 100644 --- a/samples/test4.cc +++ b/samples/test4.cc @@ -9,4 +9,7 @@ int main() m["lolailo"]=3; m["xyz"]=4; m["meh"]=5; + + auto i = m.find("xyz"); + return i->second; } diff --git a/samples/view.py b/samples/view.py index 31b9999..70f9a63 100644 --- a/samples/view.py +++ b/samples/view.py @@ -1,6 +1,7 @@ import gdb import gdb.types import gtk +import cairo import pango import pangocairo import math @@ -119,7 +120,6 @@ def arrow_points(A, B): class GraphViewerNode(): def __init__(self, x, y, name, gdb_value): - print "node created: %d, %d, %s, %s"% (x, y, name, gdb_value.address) self.x = x self.y = y self.width = 30 @@ -132,33 +132,38 @@ class GraphViewerNode(): -class GraphViewer(gtk.DrawingArea): +class GraphViewer(gtk.Layout): def __init__(self, value_viewer): - super(gtk.DrawingArea, self).__init__() + super(gtk.Layout, self).__init__() self.nodes = [] - self.selected_node = None + self.selected_node = None # node selected by clicking on it + self.highlighted_node = None # node highlighted by selecting its address on the treeview self.value_viewer = value_viewer self.add_events(gtk.gdk.BUTTON_PRESS_MASK) self.connect("expose_event", self.on_expose) self.connect("button_press_event", self.on_click) def on_expose(self, widget, event): - context = pangocairo.CairoContext(widget.window.cairo_create()) + context = pangocairo.CairoContext(widget.bin_window.cairo_create()) context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) context.clip() + context.set_antialias(cairo.ANTIALIAS_SUBPIXEL) self.draw(context) return False def on_click(self, widget, event): - self.selected_node = None + new_selected_node = None for node in self.nodes: if event.x >= node.x and event.x < node.x + node.width and event.y >= node.y and event.y < node.y + node.height: - self.selected_node = node + new_selected_node = node - if self.selected_node != None: - self.value_viewer.set_value(self.selected_node.gdb_value) + if new_selected_node is not self.selected_node: + self.selected_node = new_selected_node + if self.selected_node is not None: + self.value_viewer.set_value(self.selected_node.gdb_value) + + self.queue_draw() - self.queue_draw() return False @@ -167,6 +172,7 @@ class GraphViewer(gtk.DrawingArea): name_layout = context.create_layout() name_layout.set_font_description(pango.FontDescription("sans 8")) display_name = str(node.gdb_value.address) #node.name + #display_name = node.name if node is not self.selected_node: template_args_start = display_name.find("<") if template_args_start != -1: @@ -184,6 +190,9 @@ class GraphViewer(gtk.DrawingArea): if node is self.selected_node: context.set_source_rgb(1,0,0) context.set_line_width(3) + elif node is self.highlighted_node: + context.set_source_rgb(0.3,0.7,0.4) + context.set_line_width(3) context.rectangle(node.x, node.y, node.width, node.height) context.stroke() context.restore() @@ -215,10 +224,18 @@ class GraphViewer(gtk.DrawingArea): vy = p2[1]-p1[1] name_layout = context.create_layout() name_layout.set_font_description(pango.FontDescription("sans 8")) - name_layout.set_text(name) + name_layout.set_text(u"\u2192"+name) _, name_height = name_layout.get_pixel_size() - context.move_to((1-NAME_OFFSET)*p1[0] + NAME_OFFSET*p2[0], (1-NAME_OFFSET)*p1[1] + NAME_OFFSET*p2[1]) - context.rotate(-orientation(vx, vy)) + rotation = -orientation(vx, vy) + y_offset = -name_height - 2 # a couple of extra pixels to avoid text "stepping on the line" + + # cairo seems to ignore context.translate for text ops, but set_matrix works ok :D + transform = cairo.Matrix() + transform.translate((1-NAME_OFFSET)*p1[0] + NAME_OFFSET*p2[0], (1-NAME_OFFSET)*p1[1] + NAME_OFFSET*p2[1] ) + transform.rotate(rotation) + transform.translate(0, y_offset) + context.set_matrix(transform) + context.set_source_rgb(1,0,0) context.show_layout(name_layout) context.restore() @@ -270,6 +287,27 @@ class GdbValueViewer(gtk.TreeView): self.set_search_column(0) self.field_column.set_sort_column_id(0) + self.selection = self.get_selection() + self.selection.set_mode(gtk.SELECTION_SINGLE) + self.selection.connect("changed", self.on_selection_changed) + + def on_selection_changed(self, selection): + (model, iterator) = selection.get_selected() + new_highlighted_node = None + + if iterator is not None: + value = model.get_value(iterator, 1) + for node in self.graph_viewer.nodes: + if str(node.gdb_value.address) == value: + new_highlighted_node = node + + if self.graph_viewer.highlighted_node is not new_highlighted_node: + self.graph_viewer.highlighted_node = new_highlighted_node + self.graph_viewer.queue_draw() + + def set_graph_viewer(self, graph_viewer): + self.graph_viewer = graph_viewer + def visit_value(self, value, store_iter): if type_has_fields(value.type): for f in value.type.fields(): @@ -298,8 +336,10 @@ class ViewerWindow(gtk.Window): def __init__(self): super(gtk.Window, self).__init__() self.entry = gtk.Entry() + self.entry.connect("activate", self.on_entry_changed) self.properties = GdbValueViewer() - self.viewer = GraphViewer(self.properties) + self.viewer = GraphViewer(self.properties) # node viewer changes tree values when clicking on nodes + self.properties.set_graph_viewer(self.viewer) # tree viewer can highlight nodes self.vbox = gtk.VBox() self.paned = gtk.HPaned() labelhbox = gtk.HBox() @@ -314,6 +354,13 @@ class ViewerWindow(gtk.Window): self.set_default_size(1000,600) self.paned.set_position(750) + def on_entry_changed(self, entry): + expression = entry.get_text() + value = gdb.parse_and_eval(expression) + nodes = create_viewer_nodes(value, self.recursion_level) + self.viewer.nodes = nodes + self.viewer.queue_draw() + def visit_values(node_dict, value, x, y, recursion_level): """ Recursively traverse children of a gdb Value, storing pairs (address, GraphViewerNode). @@ -354,7 +401,6 @@ def visit_values(node_dict, value, x, y, recursion_level): def create_viewer_nodes(value, recursion_level): # create the nodes - print "creating nodes" nodes = {} width, height = visit_values(nodes, value, 50, 50, recursion_level) @@ -362,15 +408,12 @@ def create_viewer_nodes(value, recursion_level): for addr in nodes: value = nodes[addr].gdb_value if type_is_pointer(value.type) and value != 0: - print "pointer node" nodes[addr].connections["*"] = nodes[str(value)] else: - print "struct node@%s: %s"%(addr,value) for f in value.type.fields(): child = value[f.name] if type_is_pointer(child.type): if child != 0: - print "connection %s --> %s"%(addr, child), value, f.name if str(child) in nodes: nodes[addr].connections[f.name] = nodes[str(child)] @@ -405,11 +448,13 @@ class ViewerCommand(gdb.Command): else: recursion_level = 10 + is_gtk_main_running = False try: window = ViewerWindow() window.connect("destroy", gtk.main_quit) + window.recursion_level = recursion_level window.show_all() nodes = create_viewer_nodes(value, recursion_level)