A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
hud.py
Go to the documentation of this file.
1 import goocanvas
2 import core
3 import math
4 import pango
5 import gtk
6 
7 
8 class Axes(object):
9  def __init__(self, viz):
10  self.viz = viz
11  self.color = 0x8080C0FF
12  self.hlines = goocanvas.Path(parent=viz.canvas.get_root_item(), stroke_color_rgba=self.color)
13  self.hlines.lower(None)
14  self.vlines = goocanvas.Path(parent=viz.canvas.get_root_item(), stroke_color_rgba=self.color)
15  self.vlines.lower(None)
16  self.labels = []
17  hadj = self.viz.get_hadjustment()
18  vadj = self.viz.get_vadjustment()
19  def update(adj):
20  if self.visible:
21  self.update_view()
22  hadj.connect("value-changed", update)
23  vadj.connect("value-changed", update)
24  hadj.connect("changed", update)
25  vadj.connect("changed", update)
26  self.visible = True
27  self.update_view()
28 
29  def set_visible(self, visible):
30  self.visible = visible
31  if self.visible:
32  self.hlines.props.visibility = goocanvas.ITEM_VISIBLE
33  self.vlines.props.visibility = goocanvas.ITEM_VISIBLE
34  else:
35  self.hlines.props.visibility = goocanvas.ITEM_HIDDEN
36  self.vlines.props.visibility = goocanvas.ITEM_HIDDEN
37  for label in self.labels:
38  label.props.visibility = goocanvas.ITEM_HIDDEN
39 
40  def _compute_divisions(self, xi, xf):
41  assert xf > xi
42  dx = xf - xi
43  size = dx
44  ndiv = 5
45  text_width = dx/ndiv/2
46 
47  def rint(x):
48  return math.floor(x+0.5)
49 
50  dx_over_ndiv = dx / ndiv
51  for n in range(5): # iterate 5 times to find optimum division size
52  #/* div: length of each division */
53  tbe = math.log10(dx_over_ndiv)#; /* looking for approx. 'ndiv' divisions in a length 'dx' */
54  div = pow(10, rint(tbe))#; /* div: power of 10 closest to dx/ndiv */
55  if math.fabs(div/2 - dx_over_ndiv) < math.fabs(div - dx_over_ndiv): #/* test if div/2 is closer to dx/ndiv */
56  div /= 2
57  elif math.fabs(div*2 - dx_over_ndiv) < math.fabs(div - dx_over_ndiv):
58  div *= 2 # /* test if div*2 is closer to dx/ndiv */
59  x0 = div*math.ceil(xi / div) - div
60  if n > 1:
61  ndiv = rint(size / text_width)
62  return x0, div
63 
64 
65  def update_view(self):
66  if self.viz.zoom is None:
67  return
68 
69  unused_labels = self.labels
70  self.labels = []
71  for label in unused_labels:
72  label.set_property("visibility", goocanvas.ITEM_HIDDEN)
73  def get_label():
74  try:
75  label = unused_labels.pop(0)
76  except IndexError:
77  label = goocanvas.Text(parent=self.viz.canvas.get_root_item(), stroke_color_rgba=self.color)
78  else:
79  label.set_property("visibility", goocanvas.ITEM_VISIBLE)
80  label.lower(None)
81  self.labels.append(label)
82  return label
83 
84  hadj = self.viz.get_hadjustment()
85  vadj = self.viz.get_vadjustment()
86  zoom = self.viz.zoom.value
87  offset = 10/zoom
88 
89  x1, y1 = self.viz.canvas.convert_from_pixels(hadj.value, vadj.value)
90  x2, y2 = self.viz.canvas.convert_from_pixels(hadj.value + hadj.page_size, vadj.value + vadj.page_size)
91  line_width = 5.0/self.viz.zoom.value
92 
93  # draw the horizontal axis
94  self.hlines.set_property("line-width", line_width)
95  yc = y2 - line_width/2
96 
97  sim_x1 = x1/core.PIXELS_PER_METER
98  sim_x2 = x2/core.PIXELS_PER_METER
99  x0, xdiv = self._compute_divisions(sim_x1, sim_x2)
100  path = ["M %r %r L %r %r" % (x1, yc, x2, yc)]
101  x = x0
102  while x < sim_x2:
103  path.append("M %r %r L %r %r" % (core.PIXELS_PER_METER*x, yc - offset, core.PIXELS_PER_METER*x, yc))
104  label = get_label()
105  label.set_properties(font=("Sans Serif %f" % int(12/zoom)),
106  text=("%G" % x),
107  fill_color_rgba=self.color,
108  alignment=pango.ALIGN_CENTER,
109  anchor=gtk.ANCHOR_S,
110  x=core.PIXELS_PER_METER*x,
111  y=(yc - offset))
112  x += xdiv
113  del x
114 
115  self.hlines.set_property("data", " ".join(path))
116 
117  # draw the vertical axis
118  self.vlines.set_property("line-width", line_width)
119  xc = x1 + line_width/2
120 
121  sim_y1 = y1/core.PIXELS_PER_METER
122  sim_y2 = y2/core.PIXELS_PER_METER
123 
124 
125  y0, ydiv = self._compute_divisions(sim_y1, sim_y2)
126  path = ["M %r %r L %r %r" % (xc, y1, xc, y2)]
127  y = y0
128  while y < sim_y2:
129  path.append("M %r %r L %r %r" % (xc, core.PIXELS_PER_METER*y, xc + offset, core.PIXELS_PER_METER*y))
130  label = get_label()
131  label.set_properties(font=("Sans Serif %f" % int(12/zoom)),
132  text=("%G" % y),
133  fill_color_rgba=self.color,
134  alignment=pango.ALIGN_LEFT,
135  anchor=gtk.ANCHOR_W,
136  x=xc + offset,
137  y=core.PIXELS_PER_METER*y)
138  y += ydiv
139 
140  self.vlines.set_property("data", " ".join(path))
141 
142 
143 
144  self.labels.extend(unused_labels)
def __init__
Definition: hud.py:9
def update_view
Definition: hud.py:65
def _compute_divisions
Definition: hud.py:40
def set_visible
Definition: hud.py:29