diff options
Diffstat (limited to 'unit_trace/viz/viewer.py')
-rw-r--r-- | unit_trace/viz/viewer.py | 218 |
1 files changed, 109 insertions, 109 deletions
diff --git a/unit_trace/viz/viewer.py b/unit_trace/viz/viewer.py index 909da76..efc79a1 100644 --- a/unit_trace/viz/viewer.py +++ b/unit_trace/viz/viewer.py | |||
@@ -13,10 +13,10 @@ import copy | |||
13 | 13 | ||
14 | class GraphContextMenu(gtk.Menu): | 14 | class GraphContextMenu(gtk.Menu): |
15 | MAX_STR_LEN = 80 | 15 | MAX_STR_LEN = 80 |
16 | 16 | ||
17 | def __init__(self, selected): | 17 | def __init__(self, selected): |
18 | super(GraphContextMenu, self).__init__() | 18 | super(GraphContextMenu, self).__init__() |
19 | 19 | ||
20 | for event in selected: | 20 | for event in selected: |
21 | string = str(event) | 21 | string = str(event) |
22 | if len(string) > GraphContextMenu.MAX_STR_LEN - 3: | 22 | if len(string) > GraphContextMenu.MAX_STR_LEN - 3: |
@@ -24,100 +24,100 @@ class GraphContextMenu(gtk.Menu): | |||
24 | item = gtk.MenuItem(string) | 24 | item = gtk.MenuItem(string) |
25 | self.append(item) | 25 | self.append(item) |
26 | item.show() | 26 | item.show() |
27 | 27 | ||
28 | class GraphArea(gtk.DrawingArea): | 28 | class GraphArea(gtk.DrawingArea): |
29 | HORIZ_PAGE_SCROLL_FACTOR = 10.8 | 29 | HORIZ_PAGE_SCROLL_FACTOR = 10.8 |
30 | HORIZ_STEP_SCROLL_FACTOR = 0.8 | 30 | HORIZ_STEP_SCROLL_FACTOR = 0.8 |
31 | VERT_PAGE_SCROLL_FACTOR = 3.0 | 31 | VERT_PAGE_SCROLL_FACTOR = 3.0 |
32 | VERT_STEP_SCROLL_FACTOR = 0.5 | 32 | VERT_STEP_SCROLL_FACTOR = 0.5 |
33 | 33 | ||
34 | REFRESH_INFLATION_FACTOR = 20.0 | 34 | REFRESH_INFLATION_FACTOR = 20.0 |
35 | 35 | ||
36 | def __init__(self, renderer): | 36 | def __init__(self, renderer): |
37 | super(GraphArea, self).__init__() | 37 | super(GraphArea, self).__init__() |
38 | 38 | ||
39 | self.renderer = renderer | 39 | self.renderer = renderer |
40 | 40 | ||
41 | self.cur_x = 0 | 41 | self.cur_x = 0 |
42 | self.cur_y = 0 | 42 | self.cur_y = 0 |
43 | self.width = 0 | 43 | self.width = 0 |
44 | self.height = 0 | 44 | self.height = 0 |
45 | 45 | ||
46 | self.set_set_scroll_adjustments_signal('set-scroll-adjustments') | 46 | self.set_set_scroll_adjustments_signal('set-scroll-adjustments') |
47 | 47 | ||
48 | self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | | 48 | self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | |
49 | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.EXPOSURE_MASK) | 49 | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.EXPOSURE_MASK) |
50 | 50 | ||
51 | self.band_rect = None | 51 | self.band_rect = None |
52 | self.ctrl_clicked = False | 52 | self.ctrl_clicked = False |
53 | self.dirtied_regions = [] | 53 | self.dirtied_regions = [] |
54 | 54 | ||
55 | self.connect('expose-event', self.expose) | 55 | self.connect('expose-event', self.expose) |
56 | self.connect('size-allocate', self.size_allocate) | 56 | self.connect('size-allocate', self.size_allocate) |
57 | self.connect('set-scroll-adjustments', self.set_scroll_adjustments) | 57 | self.connect('set-scroll-adjustments', self.set_scroll_adjustments) |
58 | self.connect('button-press-event', self.button_press) | 58 | self.connect('button-press-event', self.button_press) |
59 | self.connect('button-release-event', self.button_release) | 59 | self.connect('button-release-event', self.button_release) |
60 | self.connect('motion-notify-event', self.motion_notify) | 60 | self.connect('motion-notify-event', self.motion_notify) |
61 | 61 | ||
62 | def expose(self, widget, expose_event, data=None): | 62 | def expose(self, widget, expose_event, data=None): |
63 | ctx = widget.window.cairo_create() | 63 | ctx = widget.window.cairo_create() |
64 | graph = self.renderer.get_graph() | 64 | graph = self.renderer.get_graph() |
65 | graph.update_view(self.cur_x, self.cur_y, self.width, self.height, ctx) | 65 | graph.update_view(self.cur_x, self.cur_y, self.width, self.height, ctx) |
66 | 66 | ||
67 | # We ourselves didn't update dirtied_regions, so this means that X or the | 67 | # We ourselves didn't update dirtied_regions, so this means that X or the |
68 | # window manager must have caused the expose event. So just update the | 68 | # window manager must have caused the expose event. So just update the |
69 | # expose_event's bounding area. | 69 | # expose_event's bounding area. |
70 | if not self.dirtied_regions or expose_event.send_event: | 70 | if not self.dirtied_regions or expose_event.send_event: |
71 | self.dirtied_regions = [(expose_event.area.x, expose_event.area.y, | 71 | self.dirtied_regions = [(expose_event.area.x, expose_event.area.y, |
72 | expose_event.area.width, expose_event.area.height)] | 72 | expose_event.area.width, expose_event.area.height)] |
73 | 73 | ||
74 | graph.render_surface(self.renderer.get_schedule(), self.dirtied_regions) | 74 | graph.render_surface(self.renderer.get_schedule(), self.dirtied_regions) |
75 | 75 | ||
76 | # render dragging band rectangle, if there is one | 76 | # render dragging band rectangle, if there is one |
77 | if self.band_rect is not None: | 77 | if self.band_rect is not None: |
78 | x, y, width, height = self.band_rect | 78 | x, y, width, height = self.band_rect |
79 | thickness = GraphFormat.BAND_THICKNESS | 79 | thickness = GraphFormat.BAND_THICKNESS |
80 | color = GraphFormat.BAND_COLOR | 80 | color = GraphFormat.BAND_COLOR |
81 | 81 | ||
82 | ctx.rectangle(x, y, width, height) | 82 | ctx.rectangle(x, y, width, height) |
83 | ctx.set_line_width(thickness) | 83 | ctx.set_line_width(thickness) |
84 | ctx.set_source_rgb(color[0], color[1], color[2]) | 84 | ctx.set_source_rgb(color[0], color[1], color[2]) |
85 | ctx.stroke() | 85 | ctx.stroke() |
86 | 86 | ||
87 | self.dirtied_regions = [] | 87 | self.dirtied_regions = [] |
88 | 88 | ||
89 | def get_renderer(self): | 89 | def get_renderer(self): |
90 | return self.renderer | 90 | return self.renderer |
91 | 91 | ||
92 | def get_graph(self): | 92 | def get_graph(self): |
93 | return self.renderer.get_graph() | 93 | return self.renderer.get_graph() |
94 | 94 | ||
95 | def set_scroll_adjustments(self, widget, horizontal, vertical, data=None): | 95 | def set_scroll_adjustments(self, widget, horizontal, vertical, data=None): |
96 | graph = self.renderer.get_graph() | 96 | graph = self.renderer.get_graph() |
97 | width = graph.get_width() | 97 | width = graph.get_width() |
98 | height = graph.get_height() | 98 | height = graph.get_height() |
99 | 99 | ||
100 | self.horizontal = horizontal | 100 | self.horizontal = horizontal |
101 | self.vertical = vertical | 101 | self.vertical = vertical |
102 | self.config_scrollbars(self.cur_x, self.cur_y) | 102 | self.config_scrollbars(self.cur_x, self.cur_y) |
103 | 103 | ||
104 | if self.horizontal is not None: | 104 | if self.horizontal is not None: |
105 | self.horizontal.connect('value-changed', self.horizontal_value_changed) | 105 | self.horizontal.connect('value-changed', self.horizontal_value_changed) |
106 | if self.vertical is not None: | 106 | if self.vertical is not None: |
107 | self.vertical.connect('value-changed', self.vertical_value_changed) | 107 | self.vertical.connect('value-changed', self.vertical_value_changed) |
108 | 108 | ||
109 | def horizontal_value_changed(self, adjustment): | 109 | def horizontal_value_changed(self, adjustment): |
110 | self.cur_x = min(adjustment.value, self.renderer.get_graph().get_width()) | 110 | self.cur_x = min(adjustment.value, self.renderer.get_graph().get_width()) |
111 | self.cur_x = max(adjustment.value, 0.0) | 111 | self.cur_x = max(adjustment.value, 0.0) |
112 | 112 | ||
113 | self._dirty(0, 0, self.width, self.height) | 113 | self._dirty(0, 0, self.width, self.height) |
114 | 114 | ||
115 | def vertical_value_changed(self, adjustment): | 115 | def vertical_value_changed(self, adjustment): |
116 | self.cur_y = min(adjustment.value, self.renderer.get_graph().get_height()) | 116 | self.cur_y = min(adjustment.value, self.renderer.get_graph().get_height()) |
117 | self.cur_y = max(adjustment.value, 0.0) | 117 | self.cur_y = max(adjustment.value, 0.0) |
118 | 118 | ||
119 | self._dirty(0, 0, self.width, self.height) | 119 | self._dirty(0, 0, self.width, self.height) |
120 | 120 | ||
121 | def size_allocate(self, widget, allocation): | 121 | def size_allocate(self, widget, allocation): |
122 | self.width = allocation.width | 122 | self.width = allocation.width |
123 | self.height = allocation.height | 123 | self.height = allocation.height |
@@ -127,21 +127,21 @@ class GraphArea(gtk.DrawingArea): | |||
127 | graph = self.renderer.get_graph() | 127 | graph = self.renderer.get_graph() |
128 | width = graph.get_width() | 128 | width = graph.get_width() |
129 | height = graph.get_height() | 129 | height = graph.get_height() |
130 | 130 | ||
131 | if self.horizontal is not None: | 131 | if self.horizontal is not None: |
132 | self.horizontal.set_all(hvalue, 0.0, width, graph.get_attrs().maj_sep * GraphArea.HORIZ_STEP_SCROLL_FACTOR, | 132 | self.horizontal.set_all(hvalue, 0.0, width, graph.get_attrs().maj_sep * GraphArea.HORIZ_STEP_SCROLL_FACTOR, |
133 | graph.get_attrs().maj_sep * GraphArea.HORIZ_PAGE_SCROLL_FACTOR, self.width) | 133 | graph.get_attrs().maj_sep * GraphArea.HORIZ_PAGE_SCROLL_FACTOR, self.width) |
134 | if self.vertical is not None: | 134 | if self.vertical is not None: |
135 | self.vertical.set_all(vvalue, 0.0, height, graph.get_attrs().y_item_size * GraphArea.VERT_STEP_SCROLL_FACTOR, | 135 | self.vertical.set_all(vvalue, 0.0, height, graph.get_attrs().y_item_size * GraphArea.VERT_STEP_SCROLL_FACTOR, |
136 | graph.get_attrs().y_item_size * GraphArea.VERT_PAGE_SCROLL_FACTOR, self.height) | 136 | graph.get_attrs().y_item_size * GraphArea.VERT_PAGE_SCROLL_FACTOR, self.height) |
137 | 137 | ||
138 | def _find_max_layer(self, regions): | 138 | def _find_max_layer(self, regions): |
139 | max_layer = Canvas.BOTTOM_LAYER | 139 | max_layer = Canvas.BOTTOM_LAYER |
140 | for event in regions: | 140 | for event in regions: |
141 | if event.get_layer() > max_layer: | 141 | if event.get_layer() > max_layer: |
142 | max_layer = event.get_layer() | 142 | max_layer = event.get_layer() |
143 | return max_layer | 143 | return max_layer |
144 | 144 | ||
145 | def _update_event_changes(self, list1, list2): | 145 | def _update_event_changes(self, list1, list2): |
146 | # if an event changed selected status, update the bounding area | 146 | # if an event changed selected status, update the bounding area |
147 | for event in list1: | 147 | for event in list1: |
@@ -152,12 +152,12 @@ class GraphArea(gtk.DrawingArea): | |||
152 | if event not in list1: | 152 | if event not in list1: |
153 | x, y, width, height = list2[event].get_dimensions() | 153 | x, y, width, height = list2[event].get_dimensions() |
154 | self._dirty_inflate(x - self.cur_x, y - self.cur_y, width, height, GraphFormat.BORDER_THICKNESS) | 154 | self._dirty_inflate(x - self.cur_x, y - self.cur_y, width, height, GraphFormat.BORDER_THICKNESS) |
155 | 155 | ||
156 | def motion_notify(self, widget, motion_event, data=None): | 156 | def motion_notify(self, widget, motion_event, data=None): |
157 | msg = None | 157 | msg = None |
158 | 158 | ||
159 | graph = self.renderer.get_graph() | 159 | graph = self.renderer.get_graph() |
160 | 160 | ||
161 | graph.render_surface(self.renderer.get_schedule(), [(motion_event.x, motion_event.y, | 161 | graph.render_surface(self.renderer.get_schedule(), [(motion_event.x, motion_event.y, |
162 | 0, 0)], True) | 162 | 0, 0)], True) |
163 | just_selected = graph.get_selected_regions(motion_event.x, motion_event.y, 0, 0) | 163 | just_selected = graph.get_selected_regions(motion_event.x, motion_event.y, 0, 0) |
@@ -166,62 +166,62 @@ class GraphArea(gtk.DrawingArea): | |||
166 | the_event = None | 166 | the_event = None |
167 | else: | 167 | else: |
168 | max_layer = self._find_max_layer(just_selected) | 168 | max_layer = self._find_max_layer(just_selected) |
169 | 169 | ||
170 | for event in just_selected: | 170 | for event in just_selected: |
171 | if event.get_layer() == max_layer: | 171 | if event.get_layer() == max_layer: |
172 | the_event = event | 172 | the_event = event |
173 | break | 173 | break |
174 | 174 | ||
175 | msg = str(the_event) | 175 | msg = str(the_event) |
176 | 176 | ||
177 | self.emit('update-event-description', the_event, msg) | 177 | self.emit('update-event-description', the_event, msg) |
178 | 178 | ||
179 | if self.band_rect is not None: | 179 | if self.band_rect is not None: |
180 | selected = {} | 180 | selected = {} |
181 | was_selected = self.renderer.get_schedule().get_selected() | 181 | was_selected = self.renderer.get_schedule().get_selected() |
182 | if self.ctrl_clicked: | 182 | if self.ctrl_clicked: |
183 | selected = copy.copy(was_selected) | 183 | selected = copy.copy(was_selected) |
184 | 184 | ||
185 | # dragging a rectangle | 185 | # dragging a rectangle |
186 | x = self.band_rect[0] | 186 | x = self.band_rect[0] |
187 | y = self.band_rect[1] | 187 | y = self.band_rect[1] |
188 | width = motion_event.x - self.band_rect[0] | 188 | width = motion_event.x - self.band_rect[0] |
189 | height = motion_event.y - self.band_rect[1] | 189 | height = motion_event.y - self.band_rect[1] |
190 | 190 | ||
191 | x_p, y_p, width_p, height_p = self._positivify(x, y, width, height) | 191 | x_p, y_p, width_p, height_p = self._positivify(x, y, width, height) |
192 | graph.render_surface(self.renderer.get_schedule(), [(x_p, y_p, width_p, height_p)], True) | 192 | graph.render_surface(self.renderer.get_schedule(), [(x_p, y_p, width_p, height_p)], True) |
193 | selected.update(graph.get_selected_regions(x_p, y_p, width_p, height_p)) | 193 | selected.update(graph.get_selected_regions(x_p, y_p, width_p, height_p)) |
194 | self.renderer.get_schedule().set_selected(selected) | 194 | self.renderer.get_schedule().set_selected(selected) |
195 | 195 | ||
196 | old_x, old_y, old_width, old_height = self.band_rect | 196 | old_x, old_y, old_width, old_height = self.band_rect |
197 | self.band_rect = (x, y, width, height) | 197 | self.band_rect = (x, y, width, height) |
198 | 198 | ||
199 | self._dirty_rect_border(old_x, old_y, old_width, old_height, GraphFormat.BAND_THICKNESS) | 199 | self._dirty_rect_border(old_x, old_y, old_width, old_height, GraphFormat.BAND_THICKNESS) |
200 | self._dirty_rect_border(x, y, width, height, GraphFormat.BAND_THICKNESS) | 200 | self._dirty_rect_border(x, y, width, height, GraphFormat.BAND_THICKNESS) |
201 | 201 | ||
202 | self._update_event_changes(was_selected, selected) | 202 | self._update_event_changes(was_selected, selected) |
203 | 203 | ||
204 | def button_press(self, widget, button_event, data=None): | 204 | def button_press(self, widget, button_event, data=None): |
205 | graph = self.renderer.get_graph() | 205 | graph = self.renderer.get_graph() |
206 | 206 | ||
207 | self.ctrl_clicked = button_event.state & gtk.gdk.CONTROL_MASK | 207 | self.ctrl_clicked = button_event.state & gtk.gdk.CONTROL_MASK |
208 | 208 | ||
209 | if button_event.button == 1: | 209 | if button_event.button == 1: |
210 | self.left_button_start_coor = (button_event.x, button_event.y) | 210 | self.left_button_start_coor = (button_event.x, button_event.y) |
211 | graph.render_surface(self.renderer.get_schedule(), \ | 211 | graph.render_surface(self.renderer.get_schedule(), \ |
212 | [(button_event.x, button_event.y, 0, 0)], True) | 212 | [(button_event.x, button_event.y, 0, 0)], True) |
213 | 213 | ||
214 | just_selected = graph.get_selected_regions(button_event.x, button_event.y, 0, 0) | 214 | just_selected = graph.get_selected_regions(button_event.x, button_event.y, 0, 0) |
215 | 215 | ||
216 | max_layer = self._find_max_layer(just_selected) | 216 | max_layer = self._find_max_layer(just_selected) |
217 | 217 | ||
218 | new_now_selected = None | 218 | new_now_selected = None |
219 | was_selected = self.renderer.get_schedule().get_selected() | 219 | was_selected = self.renderer.get_schedule().get_selected() |
220 | if self.ctrl_clicked: | 220 | if self.ctrl_clicked: |
221 | new_now_selected = copy.copy(was_selected) | 221 | new_now_selected = copy.copy(was_selected) |
222 | else: | 222 | else: |
223 | new_now_selected = {} | 223 | new_now_selected = {} |
224 | 224 | ||
225 | # only select those events which were in the top layer (it's | 225 | # only select those events which were in the top layer (it's |
226 | # not intuitive to click something and then have something | 226 | # not intuitive to click something and then have something |
227 | # below it get selected). Also, clicking something that | 227 | # below it get selected). Also, clicking something that |
@@ -237,43 +237,43 @@ class GraphArea(gtk.DrawingArea): | |||
237 | elif event in new_now_selected: | 237 | elif event in new_now_selected: |
238 | del new_now_selected[event] | 238 | del new_now_selected[event] |
239 | break # only pick one event when just clicking | 239 | break # only pick one event when just clicking |
240 | 240 | ||
241 | self.renderer.get_schedule().set_selected(new_now_selected) | 241 | self.renderer.get_schedule().set_selected(new_now_selected) |
242 | #self.last_selected = new_now_selected | 242 | #self.last_selected = new_now_selected |
243 | 243 | ||
244 | self._update_event_changes(new_now_selected, was_selected) | 244 | self._update_event_changes(new_now_selected, was_selected) |
245 | 245 | ||
246 | if self.band_rect is None: | 246 | if self.band_rect is None: |
247 | self.band_rect = (button_event.x, button_event.y, 0, 0) | 247 | self.band_rect = (button_event.x, button_event.y, 0, 0) |
248 | 248 | ||
249 | elif button_event.button == 3: | 249 | elif button_event.button == 3: |
250 | self._release_band() | 250 | self._release_band() |
251 | self.emit('request-context-menu', button_event, self.renderer.get_schedule().get_selected()) | 251 | self.emit('request-context-menu', button_event, self.renderer.get_schedule().get_selected()) |
252 | 252 | ||
253 | def button_release(self, widget, button_event, data=None): | 253 | def button_release(self, widget, button_event, data=None): |
254 | self.ctrl_clicked = False | 254 | self.ctrl_clicked = False |
255 | #self.last_selected = copy.copy(self.renderer.get_schedule().get_selected()) | 255 | #self.last_selected = copy.copy(self.renderer.get_schedule().get_selected()) |
256 | 256 | ||
257 | if button_event.button == 1: | 257 | if button_event.button == 1: |
258 | self._release_band() | 258 | self._release_band() |
259 | 259 | ||
260 | def _release_band(self): | 260 | def _release_band(self): |
261 | if self.band_rect is not None: | 261 | if self.band_rect is not None: |
262 | x, y, width, height = self.band_rect | 262 | x, y, width, height = self.band_rect |
263 | self._dirty_rect_border(x, y, width, height, GraphFormat.BAND_THICKNESS) | 263 | self._dirty_rect_border(x, y, width, height, GraphFormat.BAND_THICKNESS) |
264 | self.band_rect = None | 264 | self.band_rect = None |
265 | 265 | ||
266 | def _dirty(self, x, y, width, height): | 266 | def _dirty(self, x, y, width, height): |
267 | x = max(int(math.floor(x)), 0) | 267 | x = max(int(math.floor(x)), 0) |
268 | y = max(int(math.floor(y)), 0) | 268 | y = max(int(math.floor(y)), 0) |
269 | width = min(int(math.ceil(width)), self.width) | 269 | width = min(int(math.ceil(width)), self.width) |
270 | height = min(int(math.ceil(height)), self.height) | 270 | height = min(int(math.ceil(height)), self.height) |
271 | 271 | ||
272 | self.dirtied_regions.append((x, y, width, height)) | 272 | self.dirtied_regions.append((x, y, width, height)) |
273 | 273 | ||
274 | rect = gtk.gdk.Rectangle(x, y, width, height) | 274 | rect = gtk.gdk.Rectangle(x, y, width, height) |
275 | self.window.invalidate_rect(rect, True) | 275 | self.window.invalidate_rect(rect, True) |
276 | 276 | ||
277 | def _dirty_inflate(self, x, y, width, height, thickness): | 277 | def _dirty_inflate(self, x, y, width, height, thickness): |
278 | t = thickness * GraphArea.REFRESH_INFLATION_FACTOR | 278 | t = thickness * GraphArea.REFRESH_INFLATION_FACTOR |
279 | x -= t / 2.0 | 279 | x -= t / 2.0 |
@@ -281,17 +281,17 @@ class GraphArea(gtk.DrawingArea): | |||
281 | width += t | 281 | width += t |
282 | height += t | 282 | height += t |
283 | self._dirty(x, y, width, height) | 283 | self._dirty(x, y, width, height) |
284 | 284 | ||
285 | def _dirty_rect_border(self, x, y, width, height, thickness): | 285 | def _dirty_rect_border(self, x, y, width, height, thickness): |
286 | # support rectangles with negative width and height (i.e. -width = width, but going leftwards | 286 | # support rectangles with negative width and height (i.e. -width = width, but going leftwards |
287 | # instead of rightwards) | 287 | # instead of rightwards) |
288 | x, y, width, height = self._positivify(x, y, width, height) | 288 | x, y, width, height = self._positivify(x, y, width, height) |
289 | 289 | ||
290 | self._dirty_inflate(x, y, width, 0, thickness) | 290 | self._dirty_inflate(x, y, width, 0, thickness) |
291 | self._dirty_inflate(x, y, 0, height, thickness) | 291 | self._dirty_inflate(x, y, 0, height, thickness) |
292 | self._dirty_inflate(x, y + height, width, 0, thickness) | 292 | self._dirty_inflate(x, y + height, width, 0, thickness) |
293 | self._dirty_inflate(x + width, y, 0, height, thickness) | 293 | self._dirty_inflate(x + width, y, 0, height, thickness) |
294 | 294 | ||
295 | def _positivify(self, x, y, width, height): | 295 | def _positivify(self, x, y, width, height): |
296 | if width < 0: | 296 | if width < 0: |
297 | x += width | 297 | x += width |
@@ -299,28 +299,28 @@ class GraphArea(gtk.DrawingArea): | |||
299 | if height < 0: | 299 | if height < 0: |
300 | y += height | 300 | y += height |
301 | height = -height | 301 | height = -height |
302 | 302 | ||
303 | return x, y, width, height | 303 | return x, y, width, height |
304 | 304 | ||
305 | class GraphWindow(gtk.ScrolledWindow): | 305 | class GraphWindow(gtk.ScrolledWindow): |
306 | def __init__(self, renderer): | 306 | def __init__(self, renderer): |
307 | super(GraphWindow, self).__init__(None, None) | 307 | super(GraphWindow, self).__init__(None, None) |
308 | 308 | ||
309 | self.add_events(gtk.gdk.KEY_PRESS_MASK) | 309 | self.add_events(gtk.gdk.KEY_PRESS_MASK) |
310 | 310 | ||
311 | self.ctr = 0 | 311 | self.ctr = 0 |
312 | self.connect('key-press-event', self.key_press) | 312 | self.connect('key-press-event', self.key_press) |
313 | 313 | ||
314 | self.garea = GraphArea(renderer) | 314 | self.garea = GraphArea(renderer) |
315 | self.add(self.garea) | 315 | self.add(self.garea) |
316 | self.garea.show() | 316 | self.garea.show() |
317 | 317 | ||
318 | def key_press(self, widget, key_event): | 318 | def key_press(self, widget, key_event): |
319 | hadj = self.get_hadjustment() | 319 | hadj = self.get_hadjustment() |
320 | vadj = self.get_vadjustment() | 320 | vadj = self.get_vadjustment() |
321 | if hadj is None or vadj is None: | 321 | if hadj is None or vadj is None: |
322 | return | 322 | return |
323 | 323 | ||
324 | hupper = hadj.get_upper() | 324 | hupper = hadj.get_upper() |
325 | hlower = hadj.get_lower() | 325 | hlower = hadj.get_lower() |
326 | hpincr = hadj.get_page_increment() | 326 | hpincr = hadj.get_page_increment() |
@@ -333,9 +333,9 @@ class GraphWindow(gtk.ScrolledWindow): | |||
333 | vpincr = vadj.get_page_increment() | 333 | vpincr = vadj.get_page_increment() |
334 | vsincr = vadj.get_step_increment() | 334 | vsincr = vadj.get_step_increment() |
335 | vpsize = vadj.get_page_size() | 335 | vpsize = vadj.get_page_size() |
336 | 336 | ||
337 | ctrl_clicked = key_event.state & gtk.gdk.CONTROL_MASK | 337 | ctrl_clicked = key_event.state & gtk.gdk.CONTROL_MASK |
338 | 338 | ||
339 | adj_tuple = {'up' : (vadj, -vsincr, 0, vval, max), | 339 | adj_tuple = {'up' : (vadj, -vsincr, 0, vval, max), |
340 | 'ctrl-up' : (vadj, -vpincr, 0, vval, max), | 340 | 'ctrl-up' : (vadj, -vpincr, 0, vval, max), |
341 | 'down' : (vadj, vsincr, vupper - vpsize, vval, min), | 341 | 'down' : (vadj, vsincr, vupper - vpsize, vval, min), |
@@ -344,78 +344,78 @@ class GraphWindow(gtk.ScrolledWindow): | |||
344 | 'ctrl-left' : (hadj, -hpincr, 0, hval, max), | 344 | 'ctrl-left' : (hadj, -hpincr, 0, hval, max), |
345 | 'right' : (hadj, hsincr, hupper - hpsize, hval, min), | 345 | 'right' : (hadj, hsincr, hupper - hpsize, hval, min), |
346 | 'ctrl-right' : (hadj, hpincr, hupper - hpsize, hval, min)} | 346 | 'ctrl-right' : (hadj, hpincr, hupper - hpsize, hval, min)} |
347 | 347 | ||
348 | keystr = None | 348 | keystr = None |
349 | keymap = {gtk.keysyms.Up : 'up', gtk.keysyms.Down : 'down', | 349 | keymap = {gtk.keysyms.Up : 'up', gtk.keysyms.Down : 'down', |
350 | gtk.keysyms.Left : 'left', gtk.keysyms.Right : 'right'} | 350 | gtk.keysyms.Left : 'left', gtk.keysyms.Right : 'right'} |
351 | if key_event.keyval in keymap: | 351 | if key_event.keyval in keymap: |
352 | keystr = keymap[key_event.keyval] | 352 | keystr = keymap[key_event.keyval] |
353 | 353 | ||
354 | if ctrl_clicked: | 354 | if ctrl_clicked: |
355 | keystr = 'ctrl-' + keystr | 355 | keystr = 'ctrl-' + keystr |
356 | 356 | ||
357 | if keystr is not None: | 357 | if keystr is not None: |
358 | adj, inc, lim, val, extr = adj_tuple[keystr] | 358 | adj, inc, lim, val, extr = adj_tuple[keystr] |
359 | adj.set_value(extr(val + inc, lim)) | 359 | adj.set_value(extr(val + inc, lim)) |
360 | 360 | ||
361 | return True | 361 | return True |
362 | 362 | ||
363 | def get_graph_area(self): | 363 | def get_graph_area(self): |
364 | return self.garea | 364 | return self.garea |
365 | 365 | ||
366 | class MainWindow(gtk.Window): | 366 | class MainWindow(gtk.Window): |
367 | WINDOW_WIDTH_REQ = 500 | 367 | WINDOW_WIDTH_REQ = 500 |
368 | WINDOW_HEIGHT_REQ = 300 | 368 | WINDOW_HEIGHT_REQ = 300 |
369 | 369 | ||
370 | def __init__(self): | 370 | def __init__(self): |
371 | super(MainWindow, self).__init__(gtk.WINDOW_TOPLEVEL) | 371 | super(MainWindow, self).__init__(gtk.WINDOW_TOPLEVEL) |
372 | 372 | ||
373 | self.connect('delete_event', self.delete_event) | 373 | self.connect('delete_event', self.delete_event) |
374 | self.connect('destroy', self.die) | 374 | self.connect('destroy', self.die) |
375 | 375 | ||
376 | self.file_menu = gtk.Menu() | 376 | self.file_menu = gtk.Menu() |
377 | self.quit_item = gtk.MenuItem('_Quit', True) | 377 | self.quit_item = gtk.MenuItem('_Quit', True) |
378 | self.quit_item.connect('activate', self.quit_item_activate) | 378 | self.quit_item.connect('activate', self.quit_item_activate) |
379 | self.quit_item.show() | 379 | self.quit_item.show() |
380 | self.file_menu.append(self.quit_item) | 380 | self.file_menu.append(self.quit_item) |
381 | 381 | ||
382 | self.file_item = gtk.MenuItem('_File', True) | 382 | self.file_item = gtk.MenuItem('_File', True) |
383 | self.file_item.set_submenu(self.file_menu) | 383 | self.file_item.set_submenu(self.file_menu) |
384 | self.file_item.show() | 384 | self.file_item.show() |
385 | 385 | ||
386 | self.menu_bar = gtk.MenuBar() | 386 | self.menu_bar = gtk.MenuBar() |
387 | self.menu_bar.append(self.file_item) | 387 | self.menu_bar.append(self.file_item) |
388 | 388 | ||
389 | self.menu_bar.show() | 389 | self.menu_bar.show() |
390 | 390 | ||
391 | self.vbox = gtk.VBox(False, 0) | 391 | self.vbox = gtk.VBox(False, 0) |
392 | 392 | ||
393 | self.notebook = gtk.Notebook() | 393 | self.notebook = gtk.Notebook() |
394 | 394 | ||
395 | self.notebook.last_page = -1 | 395 | self.notebook.last_page = -1 |
396 | self.notebook.connect('switch-page', self.switch_page) | 396 | self.notebook.connect('switch-page', self.switch_page) |
397 | 397 | ||
398 | self.notebook.show() | 398 | self.notebook.show() |
399 | 399 | ||
400 | self.desc_label = gtk.Label('') | 400 | self.desc_label = gtk.Label('') |
401 | self.desc_label.set_justify(gtk.JUSTIFY_LEFT) | 401 | self.desc_label.set_justify(gtk.JUSTIFY_LEFT) |
402 | self.desc_label.show() | 402 | self.desc_label.show() |
403 | 403 | ||
404 | self.vbox.pack_start(self.menu_bar, False, False, 0) | 404 | self.vbox.pack_start(self.menu_bar, False, False, 0) |
405 | self.vbox.pack_start(self.notebook, True, True, 0) | 405 | self.vbox.pack_start(self.notebook, True, True, 0) |
406 | self.vbox.pack_start(self.desc_label, False, False, 0) | 406 | self.vbox.pack_start(self.desc_label, False, False, 0) |
407 | self.vbox.show() | 407 | self.vbox.show() |
408 | 408 | ||
409 | self.add(self.vbox) | 409 | self.add(self.vbox) |
410 | 410 | ||
411 | self.set_size_request(MainWindow.WINDOW_WIDTH_REQ, MainWindow.WINDOW_HEIGHT_REQ) | 411 | self.set_size_request(MainWindow.WINDOW_WIDTH_REQ, MainWindow.WINDOW_HEIGHT_REQ) |
412 | 412 | ||
413 | self.show() | 413 | self.show() |
414 | 414 | ||
415 | def connect_widgets(self, garea): | 415 | def connect_widgets(self, garea): |
416 | garea.connect('update-event-description', self.update_event_description) | 416 | garea.connect('update-event-description', self.update_event_description) |
417 | garea.connect('request-context-menu', self.request_context_menu) | 417 | garea.connect('request-context-menu', self.request_context_menu) |
418 | 418 | ||
419 | def set_renderers(self, renderers): | 419 | def set_renderers(self, renderers): |
420 | for i in range(0, self.notebook.get_n_pages()): | 420 | for i in range(0, self.notebook.get_n_pages()): |
421 | self.notebook.remove_page(0) | 421 | self.notebook.remove_page(0) |
@@ -424,7 +424,7 @@ class MainWindow(gtk.Window): | |||
424 | self.connect_widgets(gwindow.get_graph_area()) | 424 | self.connect_widgets(gwindow.get_graph_area()) |
425 | gwindow.show() | 425 | gwindow.show() |
426 | self.notebook.append_page(gwindow, gtk.Label(title)) | 426 | self.notebook.append_page(gwindow, gtk.Label(title)) |
427 | 427 | ||
428 | def switch_page(self, widget, page, page_num): | 428 | def switch_page(self, widget, page, page_num): |
429 | if self.notebook.get_nth_page(self.notebook.last_page) is not None: | 429 | if self.notebook.get_nth_page(self.notebook.last_page) is not None: |
430 | old_value = self.notebook.get_nth_page(self.notebook.last_page).get_hadjustment().get_value() | 430 | old_value = self.notebook.get_nth_page(self.notebook.last_page).get_hadjustment().get_value() |
@@ -432,27 +432,27 @@ class MainWindow(gtk.Window): | |||
432 | new_ofs = self.notebook.get_nth_page(page_num).get_graph_area().get_graph().get_origin()[0] | 432 | new_ofs = self.notebook.get_nth_page(page_num).get_graph_area().get_graph().get_origin()[0] |
433 | new_value = old_value - old_ofs + new_ofs | 433 | new_value = old_value - old_ofs + new_ofs |
434 | self.notebook.get_nth_page(page_num).get_hadjustment().set_value(new_value) | 434 | self.notebook.get_nth_page(page_num).get_hadjustment().set_value(new_value) |
435 | 435 | ||
436 | self.notebook.last_page = page_num | 436 | self.notebook.last_page = page_num |
437 | 437 | ||
438 | def update_event_description(self, widget, event, msg): | 438 | def update_event_description(self, widget, event, msg): |
439 | self.desc_label.set_text(msg) | 439 | self.desc_label.set_text(msg) |
440 | 440 | ||
441 | def request_context_menu(self, widget, gdk_event, selected): | 441 | def request_context_menu(self, widget, gdk_event, selected): |
442 | button = 0 | 442 | button = 0 |
443 | if hasattr(gdk_event, 'button'): | 443 | if hasattr(gdk_event, 'button'): |
444 | button = gdk_event.button | 444 | button = gdk_event.button |
445 | time = gdk_event.time | 445 | time = gdk_event.time |
446 | 446 | ||
447 | menu = GraphContextMenu(selected) | 447 | menu = GraphContextMenu(selected) |
448 | menu.popup(None, None, None, button, time) | 448 | menu.popup(None, None, None, button, time) |
449 | 449 | ||
450 | def quit_item_activate(self, widget): | 450 | def quit_item_activate(self, widget): |
451 | self.destroy() | 451 | self.destroy() |
452 | 452 | ||
453 | def delete_event(self, widget, event, data=None): | 453 | def delete_event(self, widget, event, data=None): |
454 | return False | 454 | return False |
455 | 455 | ||
456 | def die(self, widget, data=None): | 456 | def die(self, widget, data=None): |
457 | gtk.main_quit() | 457 | gtk.main_quit() |
458 | 458 | ||