A Discrete-Event Network Simulator
qkdnetsim_etsi_014 @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
grid.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 
3 
4 import cairo
5 import sys
6 import re
7 import gtk
8 
9 
10 
11 class DataRange:
12 
18  def __init__(self, start = 0, end = 0, value = ''):
19  """! Initializer
20  @param self this object
21  @param start start
22  @param end end
23  @param value value
24  """
25  self.startstart = start
26  self.endend = end
27  self.valuevalue = value
28 
30 
34  def __init__(self, at = 0, value = ''):
35  """! Initializer
36  @param self this object
37  @param at you
38  @param value value
39  """
40  self.atat = at
41  self.valuevalue = value
42 
43 class EventFloat:
44 
48  def __init__(self, at = 0, value = 0.0):
49  """! Initializer
50  @param self this object
51  @param at you
52  @param value value
53  """
54  self.atat = at
55  self.valuevalue = value
56 
57 class EventInt:
58 
62  def __init__(self, at = 0, value = 0.0):
63  """! Initializer
64  @param self this object
65  @param at you
66  @param value value
67  """
68  self.atat = at
69  self.valuevalue = value
70 def ranges_cmp(a, b):
71  diff = a.start - b.start
72  if diff < 0:
73  return -1
74  elif diff > 0:
75  return +1
76  else:
77  return 0
78 def events_cmp(a, b):
79  diff = a.at - b.at
80  if diff < 0:
81  return -1
82  elif diff > 0:
83  return +1
84  else:
85  return 0
86 
88 
92  def __init__(self, name = ''):
93  """! Initializer
94  @param self this object
95  @param name name
96  """
97  self.namename = name
98  self.rangesranges = []
99  return
100  def __search(self, key):
101  """! Search
102  @param self this object
103  @param key key
104  @return index if found or -1 if not found
105  """
106  l = 0
107  u = len(self.rangesranges)-1
108  while l <= u:
109  i = int((l + u) / 2)
110  if key >= self.rangesranges[i].start and key <= self.rangesranges[i].end:
111  return i
112  elif key < self.rangesranges[i].start:
113  u = i - 1
114  else:
115  # key > self.ranges[i].end
116  l = i + 1
117  return - 1
118  def add_range(self, range):
119  """! Add range
120  @param self this object
121  @param range range
122  @return none
123  """
124  self.rangesranges.append(range)
125  def get_all(self):
126  """! Get all ranges
127  @param self this object
128  @return the ranges
129  """
130  return self.rangesranges
131  def get_ranges(self, start, end):
132  """! Get selected ranges
133  @param self this object
134  @param start range start
135  @param end range end
136  @return the range or and empty list
137  """
138  s = self.__search__search(start)
139  e = self.__search__search(end)
140  if s == -1 and e == -1:
141  return []
142  elif s == -1:
143  return self.rangesranges[0:e + 1]
144  elif e == -1:
145  return self.rangesranges[s:len(self.rangesranges)]
146  else:
147  return self.rangesranges[s:e + 1]
148  def get_ranges_bounds(self, start, end):
149  """! Get ranges bounds
150  @param self this object
151  @param start range start
152  @param end range end
153  @return range
154  """
155  s = self.__search__search(start)
156  e = self.__search__search(end)
157  if s == -1 and e == -1:
158  return(0, 0)
159  elif s == -1:
160  return(0, e + 1)
161  elif e == -1:
162  return(s, len(self.rangesranges))
163  else:
164  return(s, e + 1)
165  def sort(self):
166  """! Sort ranges
167  @param self this object
168  @return none
169  """
170  self.rangesranges.sort(ranges_cmp)
171  def get_bounds(self):
172  """! Get bounds
173  @param self this object
174  @return the bounds
175  """
176  if len(self.rangesranges) > 0:
177  lo = self.rangesranges[0].start
178  hi = self.rangesranges[len(self.rangesranges)-1].end
179  return(lo, hi)
180  else:
181  return(0, 0)
182 
184 
188  def __init__(self, name = ''):
189  """! Get ranges bounds
190  @param self this object
191  @param name name
192  """
193  self.namename = name
194  self.eventsevents = []
195  def __search(self, key):
196  """! Search function
197  @param self this object
198  @param key the key
199  @return event index
200  """
201  l = 0
202  u = len(self.eventsevents)-1
203  while l <= u:
204  i = int((l + u) / 2)
205  if key == self.eventsevents[i].at:
206  return i
207  elif key < self.eventsevents[i].at:
208  u = i - 1
209  else:
210  # key > self.events[i].at
211  l = i + 1
212  return l
213  def add_event(self, event):
214  """! Add Event
215  @param self this object
216  @param event event to add
217  @return none
218  """
219  self.eventsevents.append(event)
220  def get_events(self, start, end):
221  """! Get Events
222  @param self this object
223  @param start starting event
224  @param end ending event
225  @return the events
226  """
227  s = self.__search__search(start)
228  e = self.__search__search(end)
229  return self.eventsevents[s:e + 1]
230  def get_events_bounds(self, start, end):
231  """! Get Events Bounds
232  @param self this object
233  @param start starting event
234  @param end ending event
235  @return event bounds
236  """
237  s = self.__search__search(start)
238  e = self.__search__search(end)
239  return(s, e + 1)
240  def sort(self):
241  """! Sort function
242  @param self this object
243  @return none
244  """
245  self.eventsevents.sort(events_cmp)
246  def get_bounds(self):
247  """! Get Bounds
248  @param self this object
249  @return the bounds
250  """
251  if len(self.eventsevents) > 0:
252  lo = self.eventsevents[0].at
253  hi = self.eventsevents[-1].at
254  return(lo, hi)
255  else:
256  return(0, 0)
257 
258 
259 class Timeline:
260 
268  def __init__(self, name = ''):
269  """! Initializer
270  @param self this object
271  @param name name
272  """
273  self.rangesranges = []
274  self.event_strevent_str = []
275  self.event_intevent_int = []
276  self.namename = name
277  def get_range(self, name):
278  """! Get range
279  @param self this object
280  @param name name
281  @return the range
282  """
283  for range in self.rangesranges:
284  if range.name == name:
285  return range
286  timeline = TimelineDataRange(name)
287  self.rangesranges.append(timeline)
288  return timeline
289  def get_event_str(self, name):
290  """! Get Event String
291  @param self this object
292  @param name name
293  @return the event string
294  """
295  for event_str in self.event_strevent_str:
296  if event_str.name == name:
297  return event_str
298  timeline = TimelineEvent(name)
299  self.event_strevent_str.append(timeline)
300  return timeline
301  def get_event_int(self, name):
302  """! Get Event Int
303  @param self this object
304  @param name name
305  @return eevent int
306  """
307  for event_int in self.event_intevent_int:
308  if event_int.name == name:
309  return event_int
310  timeline = TimelineEvent(name)
311  self.event_intevent_int.append(timeline)
312  return timeline
313  def get_ranges(self):
314  """! Get Ranges
315  @param self this object
316  @return the ranges
317  """
318  return self.rangesranges
319  def get_events_str(self):
320  """! Get Events string
321  @param self this object
322  @return event string
323  """
324  return self.event_strevent_str
325  def get_events_int(self):
326  """! Get Events int
327  @param self this object
328  @return evrnt int
329  """
330  return self.event_intevent_int
331  def sort(self):
332  """! Sort the ranges and events
333  @param self this object
334  @return none
335  """
336  for range in self.rangesranges:
337  range.sort()
338  for event in self.event_intevent_int:
339  event.sort()
340  for event in self.event_strevent_str:
341  event.sort()
342  def get_bounds(self):
343  """! Get Bounds
344  @param self this object
345  @return the bounds
346  """
347  lo = 0
348  hi = 0
349  for range in self.rangesranges:
350  (range_lo, range_hi) = range.get_bounds()
351  if range_lo < lo:
352  lo = range_lo
353  if range_hi > hi:
354  hi = range_hi
355  for event_str in self.event_strevent_str:
356  (ev_lo, ev_hi) = event_str.get_bounds()
357  if ev_lo < lo:
358  lo = ev_lo
359  if ev_hi > hi:
360  hi = ev_hi
361  for event_int in self.event_intevent_int:
362  (ev_lo, ev_hi) = event_int.get_bounds()
363  if ev_lo < lo:
364  lo = ev_lo
365  if ev_hi > hi:
366  hi = ev_hi
367  return(lo, hi)
368 
369 
370 class Timelines:
371 
373  def __init__(self):
374  """ Initializer
375  @param self: this object
376  """
377  self.timelinestimelines = []
378  def get(self, name):
379  """! Get Timeline
380  @param self this object
381  @param name name
382  @return the timeline for the name
383  """
384  for timeline in self.timelinestimelines:
385  if timeline.name == name:
386  return timeline
387  timeline = Timeline(name)
388  self.timelinestimelines.append(timeline)
389  return timeline
390  def get_all(self):
391  """! Get All Timeline
392  @param self this object
393  @return all timelines
394  """
395  return self.timelinestimelines
396  def sort(self):
397  """! Sort the timelines
398  @param self this object
399  @return none
400  """
401  for timeline in self.timelinestimelines:
402  timeline.sort()
403  def get_bounds(self):
404  """! Get Bounds
405  @param self this object
406  @return the bounds for all timelines
407  """
408  lo = 0
409  hi = 0
410  for timeline in self.timelinestimelines:
411  (t_lo, t_hi) = timeline.get_bounds()
412  if t_lo < lo:
413  lo = t_lo
414  if t_hi > hi:
415  hi = t_hi
416  return(lo, hi)
418  """! Get All Ranges
419  @param self this object
420  @return the keys for all ranges
421  """
422  range_values = {}
423  for timeline in self.timelinestimelines:
424  for ranges in timeline.get_ranges():
425  for ran in ranges.get_all():
426  range_values[ran.value] = 1
427  return range_values.keys()
428 
429 
430 class Color:
431 
437  def __init__(self, r = 0.0, g = 0.0, b = 0.0):
438  """! Initializer
439  @param self: this object
440  @param r: red
441  @param g: green
442  @param b: blue
443  """
444  self.rr = r
445  self.gg = g
446  self.bb = b
447  def set(self, r, g, b):
448  """! Set color
449  @param self: this object
450  @param r: red
451  @param g: green
452  @param b: blue
453  @return none
454  """
455  self.rr = r
456  self.gg = g
457  self.bb = b
458 
459 
460 class Colors:
461 
466  default_colors = [Color(1, 0, 0), Color(0, 1, 0), Color(0, 0, 1), Color(1, 1, 0), Color(1, 0, 1), Color(0, 1, 1)]
467  def __init__(self):
468  """! Initializer
469  @param self this object
470  """
471  self.__colors__colors = {}
472  def add(self, name, color):
473  """! Add
474  @param self this object
475  @param name name of the color
476  @param color color value
477  @return none
478  """
479  self.__colors__colors[name] = color
480  def lookup(self, name):
481  """! Lookup name
482  @param self this object
483  @param name name
484  @return named color
485  """
486  if not self.__colors__colors.has_key(name):
487  self.addadd(name, self.default_colorsdefault_colors.pop())
488  return self.__colors__colors.get(name)
489 
490 
492 
502  def __init__(self):
503  """! Initializer
504  @param self this object
505  """
506  self.__padding__padding = 10
507  def set_padding(self, padding):
508  """! Set padding
509  @param self this object
510  @param padding padding
511  @return none
512  """
513  self.__padding__padding = padding
514  def set_legends(self, legends, colors):
515  """! Set padding
516  @param self this object
517  @param legends legends
518  @param colors colors
519  @return none
520  """
521  self.__legends__legends = legends
522  self.__colors__colors = colors
523  def layout(self, width):
524  """! Set padding
525  @param self this object
526  @param width width
527  @return none
528  """
529  self.__width__width = width
530  surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
531  ctx = cairo.Context(surface)
532  line_height = 0
533  total_height = self.__padding__padding
534  line_used = self.__padding__padding
535  for legend in self.__legends__legends:
536  (t_width, t_height) = ctx.text_extents(legend)[2:4]
537  item_width = self.__padding__padding + self.__padding__padding + t_width + self.__padding__padding
538  item_height = t_height + self.__padding__padding
539  if item_height > line_height:
540  line_height = item_height
541  if line_used + item_width > self.__width__width:
542  line_used = self.__padding__padding + item_width
543  total_height += line_height
544  else:
545  line_used += item_width
546  x = line_used - item_width
547  total_height += line_height
548  self.__height__height = total_height
549 
550  def get_height(self):
551  """! Set padding
552  @param self this object
553  @return height
554  """
555  return self.__height__height
556  def draw(self, ctx):
557  """! Set padding
558  @param self this object
559  @param ctx ctx
560  @return none
561  """
562  i = 0
563  line_height = 0
564  total_height = self.__padding__padding
565  line_used = self.__padding__padding
566  for legend in self.__legends__legends:
567  (t_width, t_height) = ctx.text_extents(legend)[2:4]
568  item_width = self.__padding__padding + self.__padding__padding + t_width + self.__padding__padding
569  item_height = t_height + self.__padding__padding
570  if item_height > line_height:
571  line_height = item_height
572  if line_used + item_width > self.__width__width:
573  line_used = self.__padding__padding + item_width
574  total_height += line_height
575  else:
576  line_used += item_width
577  x = line_used - item_width
578  ctx.rectangle(x, total_height, self.__padding__padding, self.__padding__padding)
579  ctx.set_source_rgb(0, 0, 0)
580  ctx.set_line_width(2)
581  ctx.stroke_preserve()
582  ctx.set_source_rgb(self.__colors__colors[i].r,
583  self.__colors__colors[i].g,
584  self.__colors__colors[i].b)
585  ctx.fill()
586  ctx.move_to(x + self.__padding__padding*2, total_height + t_height)
587  ctx.set_source_rgb(0, 0, 0)
588  ctx.show_text(legend)
589  i += 1
590 
591  return
592 
593 
595 
617  def __init__(self):
618  """! Initializer
619  @param self this object
620  """
621  self.paddingpadding = 10
622  return
623  def get_height(self):
624  """! Get Height
625  @param self this object
626  @return height
627  """
628  return self.heightheight
629  def set_timelines(self, timelines, colors):
630  """! Set Timelines
631  @param self this object
632  @param timelines timelines
633  @param colors colors
634  @return none
635  """
636  self.timelinestimelines = timelines
637  self.colorscolors = colors
638  def set_render_range(self, start, end):
639  """! Set Render Range
640  @param self this object
641  @param start start
642  @param end end
643  @return none
644  """
645  self.startstart = start
646  self.endend = end
647  def get_data_x_start(self):
648  """! Get Data X Start
649  @param self: this object
650  @return X start
651  """
652  return self.paddingpadding / 2 + self.left_widthleft_width + self.paddingpadding + self.right_widthright_width + self.paddingpadding / 2
653  def layout(self, width):
654  """! Get Data X Start
655  @param self this object
656  @param width width
657  @return none
658  """
659  surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
660  ctx = cairo.Context(surface)
661  max_text_height = ctx.text_extents("ABCDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz0123456789")[3]
662 
663  left_width = 0
664  right_width = 0
665  left_n_lines = 0
666  range_n = 0
667  eventint_n = 0
668  eventstr_n = 0
669  for timeline in self.timelinestimelines.get_all():
670  left_n_lines += 1
671  t_width = ctx.text_extents(timeline.name)[2]
672  left_width = max(left_width, t_width)
673  for rang in timeline.get_ranges():
674  t_width = ctx.text_extents(rang.name)[2]
675  right_width = max(right_width, t_width)
676  range_n += 1
677  for events_int in timeline.get_events_int():
678  t_width = ctx.text_extents(events_int.name)[2]
679  right_width = max(right_width, t_width)
680  eventint_n += 1
681  for events_str in timeline.get_events_str():
682  t_width = ctx.text_extents(events_str.name)[2]
683  right_width = max(right_width, t_width)
684  eventstr_n += 1
685 
686  left_height = left_n_lines * max_text_height + (left_n_lines - 1) * self.paddingpadding
687  right_n_lines = range_n + eventint_n + eventstr_n
688  right_height = (right_n_lines - 1) * self.paddingpadding + right_n_lines * max_text_height
689  right_data_height = (eventint_n + eventstr_n) * (max_text_height + 5) + range_n * 10
690  right_data_height += (right_n_lines - 1) * self.paddingpadding
691 
692  height = max(left_height, right_height)
693  height = max(height, right_data_height)
694 
695  self.left_widthleft_width = left_width
696  self.right_widthright_width = right_width
697  self.max_text_heightmax_text_height = max_text_height
698  self.widthwidth = width
699  self.heightheight = height + self.paddingpadding
700  def draw_line(self, ctx, x, y, width, height):
701  """! Draw Line
702  @param self this object
703  @param ctx ctx
704  @param x x
705  @param y y
706  @param width width
707  @param height height
708  @return none
709  """
710  ctx.move_to(x, y)
711  ctx.rel_line_to(width, height)
712  ctx.close_path()
713  ctx.set_operator(cairo.OPERATOR_SOURCE)
714  ctx.set_line_width(1.0)
715  ctx.set_source_rgb(0, 0, 0)
716  ctx.stroke()
717  def draw_events(self, ctx, events, x, y, width, height):
718  """! Draw Event
719  @param self this object
720  @param ctx ctx
721  @param events events
722  @param x x
723  @param y y
724  @param width width
725  @param height height
726  @return none
727  """
728  if (self.grey_backgroundgrey_background % 2) == 0:
729  ctx.rectangle(x, y - self.paddingpadding / 2,
730  width, height + self.paddingpadding)
731  ctx.set_source_rgb(0.9, 0.9, 0.9)
732  ctx.fill()
733  last_x_drawn = int(x)
734  (lo, hi) = events.get_events_bounds(self.startstart, self.endend)
735  for event in events.events[lo:hi]:
736  real_x = int(x + (event.at - self.startstart) * width / (self.endend - self.startstart))
737  if real_x > last_x_drawn + 2:
738  ctx.rectangle(real_x, y, 1, 1)
739  ctx.set_source_rgb(1, 0, 0)
740  ctx.stroke()
741  ctx.move_to(real_x, y + self.max_text_heightmax_text_height)
742  ctx.set_source_rgb(0, 0, 0)
743  ctx.show_text(str(event.value))
744  last_x_drawn = real_x
745  self.grey_backgroundgrey_background += 1
746  def draw_ranges(self, ctx, ranges, x, y, width, height):
747  """! Draw Ranges
748  @param self this object
749  @param ctx ctx
750  @param ranges ranges
751  @param x x
752  @param y y
753  @param width width
754  @param height height
755  @return none
756  """
757  if (self.grey_backgroundgrey_background % 2) == 0:
758  ctx.rectangle(x, y - self.paddingpadding / 2,
759  width, height + self.paddingpadding)
760  ctx.set_source_rgb(0.9, 0.9, 0.9)
761  ctx.fill()
762  last_x_drawn = int(x - 1)
763  (lo, hi) = ranges.get_ranges_bounds(self.startstart, self.endend)
764  for data_range in ranges.ranges[lo:hi]:
765  s = max(data_range.start, self.startstart)
766  e = min(data_range.end, self.endend)
767  x_start = int(x + (s - self.startstart) * width / (self.endend - self.startstart))
768  x_end = int(x + (e - self.startstart) * width / (self.endend - self.startstart))
769  if x_end > last_x_drawn:
770  ctx.rectangle(x_start, y, x_end - x_start, 10)
771  ctx.set_source_rgb(0, 0, 0)
772  ctx.stroke_preserve()
773  color = self.colorscolors.lookup(data_range.value)
774  ctx.set_source_rgb(color.r, color.g, color.b)
775  ctx.fill()
776  last_x_drawn = x_end
777 
778  self.grey_backgroundgrey_background += 1
779 
780  def draw(self, ctx):
781  """! Draw
782  @param self this object
783  @param ctx ctx
784  @return none
785  """
786  timeline_top = 0
787  top_y = self.paddingpadding / 2
788  left_x_start = self.paddingpadding / 2
789  left_x_end = left_x_start + self.left_widthleft_width
790  right_x_start = left_x_end + self.paddingpadding
791  right_x_end = right_x_start + self.right_widthright_width
792  data_x_start = right_x_end + self.paddingpadding / 2
793  data_x_end = self.widthwidth
794  data_width = data_x_end - data_x_start
795  cur_y = top_y
796  self.draw_linedraw_line(ctx, 0, 0, self.widthwidth, 0)
797  self.grey_backgroundgrey_background = 1
798  for timeline in self.timelinestimelines.get_all():
799  (y_bearing, t_width, t_height) = ctx.text_extents(timeline.name)[1:4]
800  ctx.move_to(left_x_start, cur_y + self.max_text_heightmax_text_height - (t_height + y_bearing))
801  ctx.show_text(timeline.name);
802  for events_int in timeline.get_events_int():
803  (y_bearing, t_width, t_height) = ctx.text_extents(events_int.name)[1:4]
804  ctx.move_to(right_x_start, cur_y + self.max_text_heightmax_text_height - (t_height + y_bearing))
805  ctx.show_text(events_int.name)
806  self.draw_eventsdraw_events(ctx, events_int, data_x_start, cur_y, data_width, self.max_text_heightmax_text_height + 5)
807  cur_y += self.max_text_heightmax_text_height + 5 + self.paddingpadding
808  self.draw_linedraw_line(ctx, right_x_start - self.paddingpadding / 2, cur_y - self.paddingpadding / 2,
809  self.right_widthright_width + self.paddingpadding, 0)
810 
811  for events_str in timeline.get_events_str():
812  (y_bearing, t_width, t_height) = ctx.text_extents(events_str.name)[1:4]
813  ctx.move_to(right_x_start, cur_y + self.max_text_heightmax_text_height - (t_height + y_bearing))
814  ctx.show_text(events_str.name)
815  self.draw_eventsdraw_events(ctx, events_str, data_x_start, cur_y, data_width, self.max_text_heightmax_text_height + 5)
816  cur_y += self.max_text_heightmax_text_height + 5 + self.paddingpadding
817  self.draw_linedraw_line(ctx, right_x_start - self.paddingpadding / 2, cur_y - self.paddingpadding / 2,
818  self.right_widthright_width + self.paddingpadding, 0)
819  for ranges in timeline.get_ranges():
820  (y_bearing, t_width, t_height) = ctx.text_extents(ranges.name)[1:4]
821  ctx.move_to(right_x_start, cur_y + self.max_text_heightmax_text_height - (t_height + y_bearing))
822  ctx.show_text(ranges.name)
823  self.draw_rangesdraw_ranges(ctx, ranges, data_x_start, cur_y, data_width, 10)
824  cur_y += self.max_text_heightmax_text_height + self.paddingpadding
825  self.draw_linedraw_line(ctx, right_x_start - self.paddingpadding / 2, cur_y - self.paddingpadding / 2,
826  self.right_widthright_width + self.paddingpadding, 0)
827  self.draw_linedraw_line(ctx, 0, cur_y - self.paddingpadding / 2,
828  self.widthwidth, 0)
829  bot_y = cur_y - self.paddingpadding / 2
830  self.draw_linedraw_line(ctx, left_x_end + self.paddingpadding / 2, 0,
831  0, bot_y)
832  self.draw_linedraw_line(ctx, right_x_end + self.paddingpadding / 2, 0,
833  0, bot_y)
834  return
835 
836 
838 
852  def __init__(self):
853  """! Initializer
854  @param self this object
855  """
856  self.__top__top = 0
857  return
858  def set_bounds(self, lo, hi):
859  """! Set Bounds
860  @param self this object
861  @param lo lo
862  @param hi hi
863  @return none
864  """
865  self.__lo__lo = lo
866  self.__hi__hi = hi
867  def get_position(self, x):
868  """! Get Position
869  @param self this object
870  @param x x
871  @return real x
872  """
873  real_x = (x - self.__lo__lo ) * self.__width__width / (self.__hi__hi - self.__lo__lo)
874  return real_x
875  def set_top(self):
876  """! Set Top
877  @param self this object
878  @return none
879  """
880  self.__top__top = 1
881  def set_bot(self):
882  """! Set Bottom
883  @param self this object
884  @return none
885  """
886  self.__top__top = 0
887  def layout(self, width):
888  """! Layout
889  @param self this object
890  @param width width
891  @return none
892  """
893  surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
894  ctx = cairo.Context(surface)
895 
896  # calculate scale delta
897  data_delta = self.__hi__hi - self.__lo__lo
898  closest = 1
899  while (closest*10) < data_delta:
900  closest *= 10
901  if (data_delta / closest) == 0:
902  delta = closest
903  elif(data_delta / closest) == 1:
904  delta = closest / 10
905  else:
906  delta = closest
907  start = self.__lo__lo - (self.__lo__lo % delta) + delta
908  end = self.__hi__hi - (self.__hi__hi % delta)
909 
910  self.__delta__delta = delta
911  self.__width__width = width
912 
913  # calculate text height
914  max_text_height = ctx.text_extents("ABCDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz0123456789")[3]
915  self.max_text_heightmax_text_height = max_text_height
916  height = max_text_height + 10
917  self.__height__height = height
918 
919  def get_height(self):
920  """! Get Height
921  @param self: this object
922  @return height
923  """
924  return self.__height__height
925  def draw(self, ctx):
926  """! Draw
927  @param self this object
928  @param ctx ctx
929  @return none
930  """
931  delta = self.__delta__delta
932  start = self.__lo__lo - (self.__lo__lo % delta) + delta
933  end = self.__hi__hi - (self.__hi__hi % delta)
934 
935  if self.__top__top == 1:
936  s = -1
937  else:
938  s = 1
939  # print scale points
940  ctx.set_source_rgb(0, 0, 0)
941  ctx.set_line_width(1.0)
942  ticks = range(int(start), int(end + delta), int(delta))
943  for x in ticks:
944  real_x = (x - self.__lo__lo ) * self.__width__width / (self.__hi__hi - self.__lo__lo)
945  ctx.move_to(real_x, 0)
946  ctx.line_to(real_x, 5*s)
947  ctx.close_path()
948  ctx.stroke()
949  (t_y_bearing, t_width, t_height) = ctx.text_extents(str(x))[1:4]
950  if self.__top__top:
951  text_delta = t_height + t_y_bearing
952  else:
953  text_delta = -t_y_bearing
954  ctx.move_to(real_x - t_width / 2, (5 + 5 + text_delta)*s)
955  ctx.show_text(str(x))
956  # draw subticks
957  delta /= 10
958  if delta > 0:
959  start = self.__lo__lo - (self.__lo__lo % delta) + delta
960  end = self.__hi__hi - (self.__hi__hi % delta)
961  for x in range(int(start), int(end + delta), int(delta)):
962  real_x = (x - self.__lo__lo ) * self.__width__width / (self.__hi__hi - self.__lo__lo)
963  ctx.move_to(real_x, 0)
964  ctx.line_to(real_x, 3*s)
965  ctx.close_path()
966  ctx.stroke()
967 
968 
969 
971 
993  def __init__(self, start, end):
994  """! Initializer
995  @param self this object
996  @param start start
997  @param end end
998  """
999  self.__start__start = float(start)
1000  self.__end__end = float(end)
1001  self.__mid_scale__mid_scale = ScaleRenderer()
1002  self.__mid_scale__mid_scale.set_top()
1003  self.__bot_scale__bot_scale = ScaleRenderer()
1004  self.__bot_scale__bot_scale.set_bounds(start, end)
1005  self.__bot_scale__bot_scale.set_bot()
1006  self.__width__width = 1
1007  self.__height__height = 1
1008  def get_width(self):
1009  """! Get Width
1010  @param self: this object
1011  @return width
1012  """
1013  return self.__width__width
1014  def get_height(self):
1015  """! Get Height
1016  @param self this object
1017  @return height
1018  """
1019  return self.__height__height
1020  # return x, y, width, height
1022  """! Get Data Rectangle
1023  @param self this object
1024  @return rectangle
1025  """
1026  y_start = self.__top_legend__top_legend.get_height()
1027  x_start = self.__data__data.get_data_x_start()
1028  return(x_start, y_start, self.__width__width - x_start, self.__data__data.get_height())
1029  def scale_data(self, x):
1030  """! Get Data Rectangle
1031  @param self this object
1032  @param x x
1033  @return scaled x
1034  """
1035  x_start = self.__data__data.get_data_x_start()
1036  x_scaled = x / (self.__width__width - x_start) * (self.__r_end__r_end - self.__r_start__r_start)
1037  return x_scaled
1038  # return x, y, width, height
1040  """! Get Selection Rectangle
1041  @param self this object
1042  @return rectangle
1043  """
1044  y_start = self.__top_legend__top_legend.get_height() + self.__data__data.get_height() + self.__mid_scale__mid_scale.get_height() + 20
1045  y_height = self.__bot_scale__bot_scale.get_height() + 20
1046  x_start = self.__bot_scale__bot_scale.get_position(self.__r_start__r_start)
1047  x_end = self.__bot_scale__bot_scale.get_position(self.__r_end__r_end)
1048  return(x_start, y_start, x_end - x_start, y_height)
1049  def scale_selection(self, x):
1050  """! Scale Selection
1051  @param self this object
1052  @param x the X
1053  @return scaled X
1054  """
1055  x_scaled = x / self.__width__width * (self.__end__end - self.__start__start)
1056  return x_scaled
1057  def set_range(self, start, end):
1058  """! Set Range
1059  @param self this object
1060  @param start start
1061  @param end end
1062  @return none
1063  """
1064  s = min(start, end)
1065  e = max(start, end)
1066  start = max(self.__start__start, s)
1067  end = min(self.__end__end, e)
1068  self.__r_start__r_start = start
1069  self.__r_end__r_end = end
1070  self.__data__data.set_render_range(start, end)
1071  self.__mid_scale__mid_scale.set_bounds(start, end)
1072  self.layoutlayout(self.__width__width, self.__height__height)
1073  def get_range(self):
1074  """! Get Range
1075  @param self this object
1076  @return range
1077  """
1078  return(self.__r_start__r_start, self.__r_end__r_end)
1079  def set_data(self, data):
1080  """! Set Date
1081  @param self this object
1082  @param data data
1083  @return none
1084  """
1085  self.__data__data = data
1086  def set_top_legend(self, top_legend):
1087  """! Set Top Legend
1088  @param self this object
1089  @param top_legend The legend
1090  @return none
1091  """
1092  self.__top_legend__top_legend = top_legend
1093  def layout(self, width, height):
1094  """! Set Layout
1095  @param self this object
1096  @param width width
1097  @param height height
1098  @return none
1099  """
1100  self.__width__width = width
1101  self.__height__height = height
1102  self.__top_legend__top_legend.layout(width)
1103  top_legend_height = self.__top_legend__top_legend.get_height()
1104  self.__data__data.layout(width)
1105  self.__mid_scale__mid_scale.layout(width - self.__data__data.get_data_x_start())
1106  self.__bot_scale__bot_scale.layout(width)
1107  return
1108  def __x_pixel(self, x, width):
1109  """! X Pixel
1110  @param self this object
1111  @param x x
1112  @param width width
1113  @return x pixel
1114  """
1115  new_x = (x - self.__start__start) * width / (self.__end__end - self.__start__start)
1116  return new_x
1117 
1118  def draw(self, ctx):
1119  """! Draw
1120  @param self this object
1121  @param ctx ctx
1122  @return none
1123  """
1124  # default background is white
1125  ctx.save()
1126  ctx.set_source_rgb(1, 1, 1)
1127  ctx.set_operator(cairo.OPERATOR_SOURCE)
1128  ctx.rectangle(0, 0, self.__width__width, self.__height__height)
1129  ctx.fill()
1130 
1131  # top legend
1132  ctx.save()
1133  self.__top_legend__top_legend.draw(ctx)
1134  top_legend_height = self.__top_legend__top_legend.get_height()
1135  ctx.restore()
1136 
1137  # separation line
1138  ctx.move_to(0, top_legend_height)
1139  ctx.line_to(self.__width__width, top_legend_height)
1140  ctx.close_path()
1141  ctx.set_line_width(2)
1142  ctx.set_source_rgb(0, 0, 0)
1143  ctx.stroke()
1144 
1145  # data
1146  ctx.save()
1147  ctx.translate(0,
1148  top_legend_height)
1149  self.__data__data.draw(ctx)
1150  ctx.restore()
1151 
1152  # scale below data
1153  ctx.save()
1154  ctx.translate(self.__data__data.get_data_x_start(),
1155  top_legend_height + self.__data__data.get_height() + self.__mid_scale__mid_scale.get_height())
1156  self.__mid_scale__mid_scale.draw(ctx)
1157  ctx.restore()
1158 
1159  height_used = top_legend_height + self.__data__data.get_height() + self.__mid_scale__mid_scale.get_height()
1160 
1161  # separation between scale and left pane
1162  ctx.move_to(self.__data__data.get_data_x_start(), height_used)
1163  ctx.rel_line_to(0, -self.__mid_scale__mid_scale.get_height())
1164  ctx.close_path()
1165  ctx.set_source_rgb(0, 0, 0)
1166  ctx.set_line_width(2)
1167  ctx.stroke()
1168 
1169  # separation below scale
1170  ctx.move_to(0, height_used)
1171  ctx.line_to(self.__width__width, height_used)
1172  ctx.close_path()
1173  ctx.set_line_width(2)
1174  ctx.set_source_rgb(0, 0, 0)
1175  ctx.stroke()
1176 
1177  select_start = self.__bot_scale__bot_scale.get_position(self.__r_start__r_start)
1178  select_end = self.__bot_scale__bot_scale.get_position(self.__r_end__r_end)
1179 
1180  # left connection between top scale and bottom scale
1181  ctx.move_to(0, height_used);
1182  ctx.line_to(self.__data__data.get_data_x_start(), height_used)
1183  ctx.line_to(select_start, height_used + 20)
1184  ctx.line_to(0, height_used + 20)
1185  ctx.line_to(0, height_used)
1186  ctx.set_source_rgb(0, 0, 0)
1187  ctx.set_line_width(1)
1188  ctx.stroke_preserve()
1189  ctx.set_source_rgb(0.9, 0.9, 0.9)
1190  ctx.fill()
1191 
1192  # right connection between top scale and bottom scale
1193  ctx.move_to(self.__width__width, height_used)
1194  ctx.line_to(self.__width__width, height_used + 20)
1195  ctx.line_to(select_end, height_used + 20)
1196  ctx.line_to(self.__width__width, height_used)
1197  ctx.set_source_rgb(0, 0, 0)
1198  ctx.set_line_width(1)
1199  ctx.stroke_preserve()
1200  ctx.set_source_rgb(0.9, 0.9, 0.9)
1201  ctx.fill()
1202 
1203  height_used += 20
1204 
1205  # unused area background
1206  unused_start = self.__bot_scale__bot_scale.get_position(self.__r_start__r_start)
1207  unused_end = self.__bot_scale__bot_scale.get_position(self.__r_end__r_end)
1208  unused_height = self.__bot_scale__bot_scale.get_height() + 20
1209  ctx.rectangle(0, height_used,
1210  unused_start,
1211  unused_height)
1212  ctx.rectangle(unused_end,
1213  height_used,
1214  self.__width__width - unused_end,
1215  unused_height)
1216  ctx.set_source_rgb(0.9, 0.9, 0.9)
1217  ctx.fill()
1218 
1219  # border line around bottom scale
1220  ctx.move_to(unused_end, height_used)
1221  ctx.line_to(self.__width__width, height_used)
1222  ctx.line_to(self.__width__width, height_used + unused_height)
1223  ctx.line_to(0, height_used + unused_height)
1224  ctx.line_to(0, height_used)
1225  ctx.line_to(unused_start, height_used)
1226  ctx.close_path()
1227  ctx.set_line_width(2)
1228  ctx.set_source_rgb(0, 0, 0)
1229  ctx.stroke()
1230  ctx.move_to(unused_start, height_used)
1231  ctx.line_to(unused_end, height_used)
1232  ctx.close_path()
1233  ctx.set_line_width(1)
1234  ctx.set_source_rgb(0.9, 0.9, 0.9)
1235  ctx.stroke()
1236 
1237  # unused area dot borders
1238  ctx.save()
1239  ctx.move_to(max(unused_start, 2), height_used)
1240  ctx.rel_line_to(0, unused_height)
1241  ctx.move_to(min(unused_end, self.__width__width - 2), height_used)
1242  ctx.rel_line_to(0, unused_height)
1243  ctx.set_dash([5], 0)
1244  ctx.set_source_rgb(0, 0, 0)
1245  ctx.set_line_width(1)
1246  ctx.stroke()
1247  ctx.restore()
1248 
1249  # bottom scale
1250  ctx.save()
1251  ctx.translate(0, height_used)
1252  self.__bot_scale__bot_scale.draw(ctx)
1253  ctx.restore()
1254 
1255 
1256 class GtkGraphicRenderer(gtk.DrawingArea):
1257 
1287  def __init__(self, data):
1288  """! Initializer
1289  @param self this object
1290  @param data data
1291  """
1292  super(GtkGraphicRenderer, self).__init__()
1293  self.__data__data = data
1294  self.__moving_left__moving_left = False
1295  self.__moving_right__moving_right = False
1296  self.__moving_both__moving_both = False
1297  self.__moving_top__moving_top = False
1298  self.__force_full_redraw__force_full_redraw = True
1299  self.add_events(gtk.gdk.POINTER_MOTION_MASK)
1300  self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
1301  self.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
1302  self.connect("expose_event", self.exposeexpose)
1303  self.connect('size-allocate', self.size_allocatesize_allocate)
1304  self.connect('motion-notify-event', self.motion_notifymotion_notify)
1305  self.connect('button-press-event', self.button_pressbutton_press)
1306  self.connect('button-release-event', self.button_releasebutton_release)
1307  def set_smaller_zoom(self):
1308  """! Set Smaller Zoom
1309  @param self this object
1310  @return none
1311  """
1312  (start, end) = self.__data__data.get_range()
1313  self.__data__data.set_range(start, start + (end - start)*2)
1314  self.__force_full_redraw__force_full_redraw = True
1315  self.queue_draw()
1316  def set_bigger_zoom(self):
1317  """! Set Bigger Zoom
1318  @param self this object
1319  @return none
1320  """
1321  (start, end) = self.__data__data.get_range()
1322  self.__data__data.set_range(start, start + (end - start) / 2)
1323  self.__force_full_redraw__force_full_redraw = True
1324  self.queue_draw()
1325  def output_png(self, filename):
1326  """! Output PNG
1327  @param self this object
1328  @param filename file name
1329  @return none
1330  """
1331  surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
1332  self.__data__data.get_width(),
1333  self.__data__data.get_height())
1334  ctx = cairo.Context(self.__buffer_surface__buffer_surface)
1335  self.__data__data.draw(ctx)
1336  surface.write_to_png(filename)
1337  def button_press(self, widget, event):
1338  """! Button Press
1339  @param self this object
1340  @param widget widget
1341  @param event event
1342  @return true if button has been pressed otherwise false
1343  """
1344  (x, y, width, height) = self.__data__data.get_selection_rectangle()
1345  (d_x, d_y, d_width, d_height) = self.__data__data.get_data_rectangle()
1346  if event.y > y and event.y < y + height:
1347  if abs(event.x - x) < 5:
1348  self.__moving_left__moving_left = True
1349  return True
1350  if abs(event.x - (x + width)) < 5:
1351  self.__moving_right__moving_right = True
1352  return True
1353  if event.x > x and event.x < x + width:
1354  self.__moving_both__moving_both = True
1355  self.__moving_both_start__moving_both_start = event.x
1356  self.__moving_both_cur__moving_both_cur = event.x
1357  return True
1358  if event.y > d_y and event.y < (d_y + d_height):
1359  if event.x > d_x and event.x < (d_x + d_width):
1360  self.__moving_top__moving_top = True
1361  self.__moving_top_start__moving_top_start = event.x
1362  self.__moving_top_cur__moving_top_cur = event.x
1363  return True
1364  return False
1365  def button_release(self, widget, event):
1366  """! Button Release
1367  @param self this object
1368  @param widget widget
1369  @param event event
1370  @return true if button was released otherwise false
1371  """
1372  if self.__moving_left__moving_left:
1373  self.__moving_left__moving_left = False
1374  left = self.__data__data.scale_selection(self.__moving_left_cur__moving_left_cur)
1375  right = self.__data__data.get_range()[1]
1376  self.__data__data.set_range(left, right)
1377  self.__force_full_redraw__force_full_redraw = True
1378  self.queue_draw()
1379  return True
1380  if self.__moving_right__moving_right:
1381  self.__moving_right__moving_right = False
1382  right = self.__data__data.scale_selection(self.__moving_right_cur__moving_right_cur)
1383  left = self.__data__data.get_range()[0]
1384  self.__data__data.set_range(left, right)
1385  self.__force_full_redraw__force_full_redraw = True
1386  self.queue_draw()
1387  return True
1388  if self.__moving_both__moving_both:
1389  self.__moving_both__moving_both = False
1390  delta = self.__data__data.scale_selection(self.__moving_both_cur__moving_both_cur - self.__moving_both_start__moving_both_start)
1391  (left, right) = self.__data__data.get_range()
1392  self.__data__data.set_range(left + delta, right + delta)
1393  self.__force_full_redraw__force_full_redraw = True
1394  self.queue_draw()
1395  return True
1396  if self.__moving_top__moving_top:
1397  self.__moving_top__moving_top = False
1398  return False
1399  def motion_notify(self, widget, event):
1400  """! Motion Notify
1401  @param self this object
1402  @param widget widget
1403  @param event event
1404  @return true if moving otherwise false
1405  """
1406  (x, y, width, height) = self.__data__data.get_selection_rectangle()
1407  if self.__moving_left__moving_left:
1408  if event.x <= 0:
1409  self.__moving_left_cur__moving_left_cur = 0
1410  elif event.x >= x + width:
1411  self.__moving_left_cur__moving_left_cur = x + width
1412  else:
1413  self.__moving_left_cur__moving_left_cur = event.x
1414  self.queue_draw_area(0, int(y), int(self.__width__width), int(height))
1415  return True
1416  if self.__moving_right__moving_right:
1417  if event.x >= self.__width__width:
1418  self.__moving_right__moving_right = self.__width__width
1419  elif event.x < x:
1420  self.__moving_right_cur__moving_right_cur = x
1421  else:
1422  self.__moving_right_cur__moving_right_cur = event.x
1423  self.queue_draw_area(0, int(y), int(self.__width__width), int(height))
1424  return True
1425  if self.__moving_both__moving_both:
1426  cur_e = self.__width__width - (x + width - self.__moving_both_start__moving_both_start)
1427  cur_s = (self.__moving_both_start__moving_both_start - x)
1428  if event.x < cur_s:
1429  self.__moving_both_cur__moving_both_cur = cur_s
1430  elif event.x > cur_e:
1431  self.__moving_both_cur__moving_both_cur = cur_e
1432  else:
1433  self.__moving_both_cur__moving_both_cur = event.x
1434  self.queue_draw_area(0, int(y), int(self.__width__width), int(height))
1435  return True
1436  if self.__moving_top__moving_top:
1437  self.__moving_top_cur__moving_top_cur = event.x
1438  delta = self.__data__data.scale_data(self.__moving_top_start__moving_top_start - self.__moving_top_cur__moving_top_cur)
1439  (left, right) = self.__data__data.get_range()
1440  self.__data__data.set_range(left + delta, right + delta)
1441  self.__force_full_redraw__force_full_redraw = True
1442  self.__moving_top_start__moving_top_start = event.x
1443  self.queue_draw()
1444  return True
1445  (d_x, d_y, d_width, d_height) = self.__data__data.get_data_rectangle()
1446  if event.y > y and event.y < y + height:
1447  if abs(event.x - x) < 5 or abs(event.x - (x + width)) < 5:
1448  widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.SB_H_DOUBLE_ARROW))
1449  return True
1450  if event.x > x and event.x < x + width:
1451  widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
1452  return True
1453  if event.y > d_y and event.y < (d_y + d_height):
1454  if event.x > d_x and event.x < (d_x + d_width):
1455  widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
1456  return True
1457  widget.window.set_cursor(None)
1458  return False
1459  def size_allocate(self, widget, allocation):
1460  """! Size Allocate
1461  @param self this object
1462  @param widget widget
1463  @param allocation allocation
1464  @return none
1465  """
1466  self.__width__width = allocation.width
1467  self.__height__height = allocation.height
1468  self.__data__data.layout(allocation.width, allocation.height)
1469  self.__force_full_redraw__force_full_redraw = True
1470  self.queue_draw()
1471  def expose(self, widget, event):
1472  """! Expose
1473  @param self this object
1474  @param widget widget
1475  @param event event
1476  @return false
1477  """
1478  if self.__force_full_redraw__force_full_redraw:
1479  self.__buffer_surface__buffer_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
1480  self.__data__data.get_width(),
1481  self.__data__data.get_height())
1482  ctx = cairo.Context(self.__buffer_surface__buffer_surface)
1483  self.__data__data.draw(ctx)
1484  self.__force_full_redraw__force_full_redraw = False
1485  ctx = widget.window.cairo_create()
1486  ctx.rectangle(event.area.x, event.area.y,
1487  event.area.width, event.area.height)
1488  ctx.clip()
1489  ctx.set_source_surface(self.__buffer_surface__buffer_surface)
1490  ctx.paint()
1491  (x, y, width, height) = self.__data__data.get_selection_rectangle()
1492  if self.__moving_left__moving_left:
1493  ctx.move_to(max(self.__moving_left_cur__moving_left_cur, 2), y)
1494  ctx.rel_line_to(0, height)
1495  ctx.close_path()
1496  ctx.set_line_width(1)
1497  ctx.set_source_rgb(0, 0, 0)
1498  ctx.stroke()
1499  if self.__moving_right__moving_right:
1500  ctx.move_to(min(self.__moving_right_cur__moving_right_cur, self.__width__width - 2), y)
1501  ctx.rel_line_to(0, height)
1502  ctx.close_path()
1503  ctx.set_line_width(1)
1504  ctx.set_source_rgb(0, 0, 0)
1505  ctx.stroke()
1506  if self.__moving_both__moving_both:
1507  delta_x = self.__moving_both_cur__moving_both_cur - self.__moving_both_start__moving_both_start
1508  left_x = x + delta_x
1509  ctx.move_to(x + delta_x, y)
1510  ctx.rel_line_to(0, height)
1511  ctx.close_path()
1512  ctx.move_to(x + width + delta_x, y)
1513  ctx.rel_line_to(0, height)
1514  ctx.close_path()
1515  ctx.set_source_rgb(0, 0, 0)
1516  ctx.set_line_width(1)
1517  ctx.stroke()
1518  return False
1519 
1520 
1522 
1528  def __init__(self):
1529  """! Initializer
1530  @param self this object
1531  """
1532  return
1533  def run(self, graphic):
1534  """! Run function
1535  @param self this object
1536  @param graphic graphic
1537  @return none
1538  """
1539  window = gtk.Window()
1540  self.__window__window = window
1541  window.set_default_size(200, 200)
1542  vbox = gtk.VBox()
1543  window.add(vbox)
1544  render = GtkGraphicRenderer(graphic)
1545  self.__render__render = render
1546  vbox.pack_end(render, True, True, 0)
1547  hbox = gtk.HBox()
1548  vbox.pack_start(hbox, False, False, 0)
1549  smaller_zoom = gtk.Button("Zoom Out")
1550  smaller_zoom.connect("clicked", self.__set_smaller_cb__set_smaller_cb)
1551  hbox.pack_start(smaller_zoom)
1552  bigger_zoom = gtk.Button("Zoom In")
1553  bigger_zoom.connect("clicked", self.__set_bigger_cb__set_bigger_cb)
1554  hbox.pack_start(bigger_zoom)
1555  output_png = gtk.Button("Output Png")
1556  output_png.connect("clicked", self.__output_png_cb__output_png_cb)
1557  hbox.pack_start(output_png)
1558  window.connect('destroy', gtk.main_quit)
1559  window.show_all()
1560  #gtk.bindings_activate(gtk.main_quit, 'q', 0)
1561  gtk.main()
1562  def __set_smaller_cb(self, widget):
1563  """! Set Smaller Callback
1564  @param self this object
1565  @param widget widget
1566  @return none
1567  """
1568  self.__render__render.set_smaller_zoom()
1569  def __set_bigger_cb(self, widget):
1570  """! Set Bigger Callback
1571  @param self this object
1572  @param widget widget
1573  @return none
1574  """
1575  self.__render__render.set_bigger_zoom()
1576  def __output_png_cb(self, widget):
1577  """! Output PNG Callback
1578  @param self this object
1579  @param widget widget
1580  @return none
1581  """
1582  dialog = gtk.FileChooserDialog("Output Png", self.__window__window,
1583  gtk.FILE_CHOOSER_ACTION_SAVE, ("Save", 1))
1584  self.__dialog__dialog = dialog
1585  dialog.set_default_response(1)
1586  dialog.connect("response", self.__dialog_response_cb__dialog_response_cb)
1587  dialog.show()
1588  return
1589  def __dialog_response_cb(self, widget, response):
1590  """! Dialog Response Callback
1591  @param self this object
1592  @param widget widget
1593  @param response response
1594  @return none
1595  """
1596  if response == 1:
1597  filename = self.__dialog__dialog.get_filename()
1598  self.__render__render.output_png(filename)
1599  widget.hide()
1600  return
1601 
1602 
1603 
1604 def read_data(filename):
1605  timelines = Timelines()
1606  colors = Colors()
1607  m1 = re.compile('range ([^ ]+) ([^ ]+) ([^ ]+) ([0-9]+) ([0-9]+)')
1608  m2 = re.compile('event-str ([^ ]+) ([^ ]+) ([^ ]+) ([0-9]+)')
1609  m3 = re.compile('event-int ([^ ]+) ([^ ]+) ([0-9]+) ([0-9]+)')
1610  m4 = re.compile('color ([^ ]+) #([a-fA-F0-9]{2,2})([a-fA-F0-9]{2,2})([a-fA-F0-9]{2,2})')
1611 
1612  with open(filename) as fh:
1613  for line in fh.readlines():
1614  m = m1.match(line)
1615  if m:
1616  line_name = m.group(1)
1617  timeline = timelines.get(m.group(1))
1618  rang = timeline.get_range(m.group(2))
1619  data_range = DataRange()
1620  data_range.value = m.group(3)
1621  data_range.start = int(m.group(4))
1622  data_range.end = int(m.group(5))
1623  rang.add_range(data_range)
1624  continue
1625  m = m2.match(line)
1626  if m:
1627  line_name = m.group(1)
1628  timeline = timelines.get(m.group(1))
1629  ev = timeline.get_event_str(m.group(2))
1630  event = EventString()
1631  event.value = m.group(3)
1632  event.at = int(m.group(4))
1633  ev.add_event(event)
1634  continue
1635  m = m3.match(line)
1636  if m:
1637  line_name = m.group(1)
1638  timeline = timelines.get(m.group(1))
1639  ev = timeline.get_event_int(m.group(2))
1640  event = EventInt()
1641  event.value = int(m.group(3))
1642  event.at = int(m.group(4))
1643  ev.add_event(event)
1644  continue
1645 
1646  m = m4.match(line)
1647  if m:
1648  r = int(m.group(2), 16)
1649  g = int(m.group(3), 16)
1650  b = int(m.group(4), 16)
1651  color = Color(r / 255, g / 255, b / 255)
1652  colors.add(m.group(1), color)
1653  continue
1654  timelines.sort()
1655  return (colors, timelines)
1656 
1657 
1658 
1659 def main():
1660  (colors, timelines) = read_data(sys.argv[1])
1661  (lower_bound, upper_bound) = timelines.get_bounds()
1662  graphic = GraphicRenderer(lower_bound, upper_bound)
1663  top_legend = TopLegendRenderer()
1664  range_values = timelines.get_all_range_values()
1665  range_colors = []
1666  for range_value in range_values:
1667  range_colors.append(colors.lookup(range_value))
1668  top_legend.set_legends(range_values,
1669  range_colors)
1670  graphic.set_top_legend(top_legend)
1671  data = TimelinesRenderer()
1672  data.set_timelines(timelines, colors)
1673  graphic.set_data(data)
1674 
1675  # default range
1676  range_mid = (upper_bound - lower_bound) / 2
1677  range_width = (upper_bound - lower_bound) / 10
1678  range_lo = range_mid - range_width / 2
1679  range_hi = range_mid + range_width / 2
1680  graphic.set_range(range_lo, range_hi)
1681 
1682  main_window = MainWindow()
1683  main_window.run(graphic)
1684 
1685 
1686 main()
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
Color class.
Definition: grid.py:430
def __init__(self, r=0.0, g=0.0, b=0.0)
Initializer.
Definition: grid.py:437
def set(self, r, g, b)
Set color.
Definition: grid.py:447
r
red
Definition: grid.py:444
g
green
Definition: grid.py:445
b
blue
Definition: grid.py:446
Colors class.
Definition: grid.py:460
def __init__(self)
Initializer.
Definition: grid.py:467
def lookup(self, name)
Lookup name.
Definition: grid.py:480
def add(self, name, color)
Add.
Definition: grid.py:472
list default_colors
default colors XXX add more
Definition: grid.py:466
__colors
colors
Definition: grid.py:471
DataRange class.
Definition: grid.py:11
value
value
Definition: grid.py:27
start
start
Definition: grid.py:25
def __init__(self, start=0, end=0, value='')
Initializer.
Definition: grid.py:18
EventFloat class.
Definition: grid.py:43
def __init__(self, at=0, value=0.0)
Initializer.
Definition: grid.py:48
value
value
Definition: grid.py:55
EventInt class.
Definition: grid.py:57
def __init__(self, at=0, value=0.0)
Initializer.
Definition: grid.py:62
value
value
Definition: grid.py:69
EventString class.
Definition: grid.py:29
value
value
Definition: grid.py:41
def __init__(self, at=0, value='')
Initializer.
Definition: grid.py:34
GraphicRenderer class.
Definition: grid.py:970
__mid_scale
mid scale
Definition: grid.py:1001
def set_top_legend(self, top_legend)
Set Top Legend.
Definition: grid.py:1086
def get_range(self)
Get Range.
Definition: grid.py:1073
def draw(self, ctx)
Draw.
Definition: grid.py:1118
def get_selection_rectangle(self)
Get Selection Rectangle.
Definition: grid.py:1039
def set_range(self, start, end)
Set Range.
Definition: grid.py:1057
def get_height(self)
Get Height.
Definition: grid.py:1014
def get_data_rectangle(self)
Get Data Rectangle.
Definition: grid.py:1021
__bot_scale
bottom scale
Definition: grid.py:1003
def scale_selection(self, x)
Scale Selection.
Definition: grid.py:1049
__top_legend
top legend
Definition: grid.py:1092
def layout(self, width, height)
Set Layout.
Definition: grid.py:1093
def set_data(self, data)
Set Date.
Definition: grid.py:1079
def __x_pixel(self, x, width)
X Pixel.
Definition: grid.py:1108
def __init__(self, start, end)
Initializer.
Definition: grid.py:993
def get_width(self)
Get Width.
Definition: grid.py:1008
def scale_data(self, x)
Get Data Rectangle.
Definition: grid.py:1029
GtkGraphicRenderer class.
Definition: grid.py:1256
__force_full_redraw
full redraw
Definition: grid.py:1298
__moving_top_start
moving top start
Definition: grid.py:1361
def set_smaller_zoom(self)
Set Smaller Zoom.
Definition: grid.py:1307
def motion_notify(self, widget, event)
Motion Notify.
Definition: grid.py:1399
__moving_both_cur
moving both cur
Definition: grid.py:1356
__moving_right
moving right
Definition: grid.py:1295
__moving_left
moving left
Definition: grid.py:1294
__moving_right_cur
moving right cur
Definition: grid.py:1420
__buffer_surface
buffer surface
Definition: grid.py:1479
__moving_top_cur
moving top cur
Definition: grid.py:1362
def size_allocate(self, widget, allocation)
Size Allocate.
Definition: grid.py:1459
__moving_top
moving top
Definition: grid.py:1297
__moving_both_start
moving both start
Definition: grid.py:1355
def set_bigger_zoom(self)
Set Bigger Zoom.
Definition: grid.py:1316
def button_press(self, widget, event)
Button Press.
Definition: grid.py:1337
def button_release(self, widget, event)
Button Release.
Definition: grid.py:1365
__moving_both
moving both
Definition: grid.py:1296
__moving_left_cur
moving left cur
Definition: grid.py:1409
def output_png(self, filename)
Output PNG.
Definition: grid.py:1325
def __init__(self, data)
Initializer.
Definition: grid.py:1287
def expose(self, widget, event)
Expose.
Definition: grid.py:1471
MainWindow class.
Definition: grid.py:1521
def run(self, graphic)
Run function.
Definition: grid.py:1533
def __dialog_response_cb(self, widget, response)
Dialog Response Callback.
Definition: grid.py:1589
def __init__(self)
Initializer.
Definition: grid.py:1528
def __set_smaller_cb(self, widget)
Set Smaller Callback.
Definition: grid.py:1562
__dialog
dialog
Definition: grid.py:1584
__window
window
Definition: grid.py:1540
def __output_png_cb(self, widget)
Output PNG Callback.
Definition: grid.py:1576
def __set_bigger_cb(self, widget)
Set Bigger Callback.
Definition: grid.py:1569
__render
render
Definition: grid.py:1545
ScaleRenderer class.
Definition: grid.py:837
def layout(self, width)
Layout.
Definition: grid.py:887
def draw(self, ctx)
Draw.
Definition: grid.py:925
max_text_height
maximum text height
Definition: grid.py:915
def get_position(self, x)
Get Position.
Definition: grid.py:867
def set_bot(self)
Set Bottom.
Definition: grid.py:881
__height
height
Definition: grid.py:917
def set_top(self)
Set Top.
Definition: grid.py:875
def __init__(self)
Initializer.
Definition: grid.py:852
def get_height(self)
Get Height.
Definition: grid.py:919
def set_bounds(self, lo, hi)
Set Bounds.
Definition: grid.py:858
TimelineDataRange.
Definition: grid.py:87
def __init__(self, name='')
Initializer.
Definition: grid.py:92
def get_bounds(self)
Get bounds.
Definition: grid.py:171
def add_range(self, range)
Add range.
Definition: grid.py:118
def __search(self, key)
Search.
Definition: grid.py:100
def get_ranges_bounds(self, start, end)
Get ranges bounds.
Definition: grid.py:148
def get_ranges(self, start, end)
Get selected ranges.
Definition: grid.py:131
def sort(self)
Sort ranges.
Definition: grid.py:165
def get_all(self)
Get all ranges.
Definition: grid.py:125
TimelineEvent class.
Definition: grid.py:183
def add_event(self, event)
Add Event.
Definition: grid.py:213
def get_events(self, start, end)
Get Events.
Definition: grid.py:220
def __init__(self, name='')
Get ranges bounds.
Definition: grid.py:188
def get_events_bounds(self, start, end)
Get Events Bounds.
Definition: grid.py:230
def sort(self)
Sort function.
Definition: grid.py:240
def get_bounds(self)
Get Bounds.
Definition: grid.py:246
def __search(self, key)
Search function.
Definition: grid.py:195
events
events
Definition: grid.py:194
Timeline class.
Definition: grid.py:259
def get_ranges(self)
Get Ranges.
Definition: grid.py:313
def get_range(self, name)
Get range.
Definition: grid.py:277
def get_event_int(self, name)
Get Event Int.
Definition: grid.py:301
event_int
event int
Definition: grid.py:275
def get_events_int(self)
Get Events int.
Definition: grid.py:325
ranges
ranges
Definition: grid.py:273
def get_event_str(self, name)
Get Event String.
Definition: grid.py:289
def __init__(self, name='')
Initializer.
Definition: grid.py:268
event_str
event string
Definition: grid.py:274
def get_bounds(self)
Get Bounds.
Definition: grid.py:342
def get_events_str(self)
Get Events string.
Definition: grid.py:319
def sort(self)
Sort the ranges and events.
Definition: grid.py:331
name
name
Definition: grid.py:276
Timelines class.
Definition: grid.py:370
def get_bounds(self)
Get Bounds.
Definition: grid.py:403
def __init__(self)
Definition: grid.py:373
def get(self, name)
Get Timeline.
Definition: grid.py:378
timelines
timelines
Definition: grid.py:377
def get_all_range_values(self)
Get All Ranges.
Definition: grid.py:417
def get_all(self)
Get All Timeline.
Definition: grid.py:390
def sort(self)
Sort the timelines.
Definition: grid.py:396
TimelinesRenderer class.
Definition: grid.py:594
right_width
right width
Definition: grid.py:696
def set_timelines(self, timelines, colors)
Set Timelines.
Definition: grid.py:629
grey_background
grey background
Definition: grid.py:797
def draw_line(self, ctx, x, y, width, height)
Draw Line.
Definition: grid.py:700
def get_data_x_start(self)
Get Data X Start.
Definition: grid.py:647
def set_render_range(self, start, end)
Set Render Range.
Definition: grid.py:638
timelines
timelines
Definition: grid.py:636
def layout(self, width)
Get Data X Start.
Definition: grid.py:653
def draw(self, ctx)
Draw.
Definition: grid.py:780
max_text_height
maximum text height
Definition: grid.py:697
def draw_events(self, ctx, events, x, y, width, height)
Draw Event.
Definition: grid.py:717
def __init__(self)
Initializer.
Definition: grid.py:617
def get_height(self)
Get Height.
Definition: grid.py:623
def draw_ranges(self, ctx, ranges, x, y, width, height)
Draw Ranges.
Definition: grid.py:746
left_width
left width
Definition: grid.py:695
TopLegendRenderer class.
Definition: grid.py:491
def get_height(self)
Set padding.
Definition: grid.py:550
def layout(self, width)
Set padding.
Definition: grid.py:523
def __init__(self)
Initializer.
Definition: grid.py:502
def draw(self, ctx)
Set padding.
Definition: grid.py:556
def set_padding(self, padding)
Set padding.
Definition: grid.py:507
def set_legends(self, legends, colors)
Set padding.
Definition: grid.py:514
def ranges_cmp(a, b)
Definition: grid.py:70
def events_cmp(a, b)
Definition: grid.py:78
def read_data(filename)
read_data function
Definition: grid.py:1604
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.h:4023
def set_bounds(x1, y1, x2, y2)
Definition: core.py:1843