3 from xml
.dom
import Node
5 def init_colours(window
, gc
):
10 def __init__(self
, widget
, node
):
13 self
.text
= self
.get_text(node
)
14 self
.layout
= widget
.create_pango_layout(self
.text
)
15 w
, h
= self
.layout
.get_pixel_size()
18 self
.bbox
= [w
+ 12, max(h
, 8)]
21 def render(self
, widget
, x
, y
):
23 fg
= widget
.style
.fg_gc
24 bg
= widget
.style
.bg_gc
25 surface
.draw_rectangle(fg
[g
.STATE_NORMAL
], True,
26 x
, y
, 8, self
.text_height
- 1)
28 if self
.node
in self
.widget
.selection
:
29 surface
.draw_rectangle(bg
[g
.STATE_SELECTED
], True,
30 x
+ 12, y
, self
.text_width
- 1, self
.text_height
- 1)
31 surface
.draw_layout(fg
[g
.STATE_SELECTED
], x
+ 12, y
, self
.layout
)
33 surface
.draw_layout(fg
[g
.STATE_NORMAL
], x
+ 12, y
, self
.layout
)
35 def get_text(self
, node
):
36 if node
.nodeType
== Node
.TEXT_NODE
:
37 return node
.nodeValue
.strip()
38 elif node
.nodeType
== Node
.ELEMENT_NODE
:
40 elif node
.nodeType
== Node
.COMMENT_NODE
:
41 return node
.nodeValue
.strip()
45 return '<noname>' + node
.nodeValue
49 def add_child(self
, child
):
50 # Add child GUINode, and return start point for next child.
51 # If child is None, return the first free point, but still update
52 # space needed (for initial connector).
54 self
.new_child_pos
= [16, max(16, self
.text_height
+ 2)]
55 self
.bbox
= [max(self
.bbox
[0], self
.new_child_pos
[0]),
56 max(self
.bbox
[1], self
.new_child_pos
[1])]
59 self
.bbox
[1] += child
.bbox
[1]
60 self
.bbox
[0] = max(self
.bbox
[0],
61 child
.bbox
[0] + self
.new_child_pos
[0])
62 self
.new_child_pos
[1] += child
.bbox
[1]
63 self
.kids
.append(child
)
64 return self
.new_child_pos
66 class Display(g
.EventBox
):
67 def __init__(self
, window
, view
):
68 g
.EventBox
.__init
__(self
)
69 self
.set_app_paintable(True)
70 self
.set_double_buffered(False)
71 self
.update_timeout
= 0
74 self
.parent_window
= window
77 s
= self
.get_style().copy()
78 s
.bg
[g
.STATE_NORMAL
] = g
.gdk
.color_parse('old lace')
81 #self.connect('destroy', self.destroyed)
82 self
.connect('button-press-event', self
.bg_event
)
86 #rox.app_options.add_notify(self.options_changed)
88 # Display is relative to this node
89 self
.ref_node
= view
.root
90 self
.scroll_offset
= (0, 0) # 0,0 => ref node at top-left
92 self
.last_alloc
= None
93 self
.connect('size-allocate', lambda w
, a
: self
.size_allocate(a
))
94 self
.connect('size-request', lambda w
, r
: self
.size_request(r
))
95 self
.connect('expose-event', lambda w
, e
: 1)
99 def size_allocate(self
, alloc
):
100 init_colours(self
.window
, self
.style
.black_gc
)
101 new
= (alloc
.width
, alloc
.height
)
102 if self
.last_alloc
== new
:
104 self
.last_alloc
= new
106 #print "Alloc", alloc.width, alloc.height
107 pm
= g
.gdk
.Pixmap(self
.window
, alloc
.width
, alloc
.height
, -1)
108 self
.window
.set_back_pixmap(pm
, False)
113 if not self
.pm
: return
115 if self
.view
.current_nodes
:
116 self
.ref_node
= self
.view
.current_nodes
[0] # XXX
118 self
.update_timeout
= 0
120 self
.pm
.draw_rectangle(self
.style
.bg_gc
[g
.STATE_NORMAL
], True,
121 0, 0, self
.last_alloc
[0], self
.last_alloc
[1])
123 self
.drawn
= {} # xmlNode -> GUINode
126 for n
in self
.view
.current_nodes
:
127 self
.selection
[n
] = None
128 self
.add_node(self
.ref_node
, self
.scroll_offset
[0], self
.scroll_offset
[1])
134 def size_request(self
, req
):
138 def add_node(self
, node
, x
, y
):
139 gn
= GUINode(self
, node
)
140 self
.drawn
[node
] = gn
141 gn
.render(self
, x
, y
)
144 for k
in node
.childNodes
:
145 cx
, cy
= gn
.add_child(c
)
148 if cx
> self
.last_alloc
[0] or cy
> self
.last_alloc
[1]:
150 c
= self
.add_node(k
, cx
, cy
)
154 def do_update_now(self
):
155 # Update now, if we need to
156 if self
.update_timeout
:
157 g
.timeout_remove(self
.update_timeout
)
160 def update_all(self
, node
= None):
161 if self
.update_timeout
:
162 return # Going to update anyway...
164 if self
.view
.running():
165 self
.update_timeout
= g
.timeout_add(2000, self
.update
)
167 self
.update_timeout
= g
.timeout_add(10, self
.update
)
169 def move_from(self
, old
= []):
172 def set_view(self
, view
):
174 self
.view
.remove_display(self
)
176 self
.view
.add_display(self
)
179 def show_menu(self
, bev
):
182 def bg_event(self
, widget
, event
):
183 if event
.type == g
.gdk
.BUTTON_PRESS
and event
.button
== 3:
184 self
.show_menu(event
)