4 # Orientation refers to orientation of bar, which is perpendicular to panel
5 HORIZ
= g
.ORIENTATION_HORIZONTAL
6 VERT
= g
.ORIENTATION_VERTICAL
8 class BarWidget(g
.DrawingArea
):
9 def __init__(self
, desc
, orient
, caption
, overlap
= False,
10 pfd
= None, length
= -1):
14 self
.total_width
= desc
.width
15 self
.period
= desc
.min_period
16 self
.reading
= 0 # reading is scaled to window coords
18 self
.caption_gc
= None
20 self
.overlap
= overlap
22 g
.DrawingArea
.__init
__(self
)
24 self
.connect("size-allocate", self
.size_allocate_cb
)
25 self
.connect("expose-event", self
.expose_event_cb
)
27 self
.connect("style-set", self
.style_set_cb
)
28 self
.connect("direction-changed", self
.change_caption
)
31 self
.set_caption(caption
)
34 self
.change_length(length
)
35 gobject
.timeout_add(int(self
.period
* 1000), self
.tick_cb
)
37 def set_caption(self
, caption
):
38 self
.caption
= caption
41 def style_set_cb(self
, *args
):
43 self
.caption_gc
= None
46 def change_caption(self
, *args
):
47 self
.caption_layout
= self
.create_pango_layout(self
.caption
)
48 extent
= self
.caption_layout
.get_pixel_extents()[0]
49 self
.caption_x
= -extent
[0]
50 self
.caption_y
= -extent
[1]
51 self
.caption_w
= extent
[2]
52 self
.caption_h
= extent
[3]
53 if self
.orient
== HORIZ
:
54 if self
.total_width
> self
.caption_h
:
55 width
= self
.total_width
57 width
= self
.caption_h
59 if self
.total_width
> self
.caption_w
:
60 width
= self
.total_width
62 width
= self
.caption_w
63 self
.cache_caption_offsets()
64 self
.change_width(width
)
66 def cache_caption_offsets(self
, allocation
= None):
67 if self
.orient
== HORIZ
:
68 self
.caption_x0
= self
.caption_x
+ 1
69 if self
.total_width
> self
.caption_h
:
70 self
.caption_y0
= self
.caption_y
+ \
71 int((self
.total_width
- self
.caption_h
) / 2)
73 self
.caption_y0
= self
.caption_y
76 allocation
= self
.get_allocation()
77 self
.caption_y0
= allocation
.height
- self
.caption_h
+ \
79 if self
.total_width
> self
.caption_w
:
80 self
.caption_x0
= self
.caption_x
+ \
81 int((self
.total_width
- self
.caption_w
) / 2)
83 self
.caption_x0
= self
.caption_x
85 def size_allocate_cb(self
, widget
, allocation
):
86 if self
.orient
== HORIZ
:
87 self
.length
= allocation
.width
89 self
.total_width
= allocation
.height
91 self
.length
= allocation
.height
93 self
.total_width
= allocation
.width
95 self
.length
-= cap
+ 3
96 self
.cache_caption_offsets(allocation
)
98 def update_overlap(self
, overlap
):
99 self
.overlap
= overlap
100 self
.size_allocate_cb(self
, self
.get_allocation())
103 def scale_reading(self
, reading
):
104 min, max = self
.desc
.get_range()
109 return int(self
.length
* (reading
- min) / (max - min))
112 return int((self
.total_width
- self
.desc
.width
) / 2)
114 def mark_for_redraw(self
, min_scaled
, max_scaled
):
115 if self
.orient
== HORIZ
:
117 min_scaled
+= self
.caption_x
+ 3
118 self
.queue_draw_area(min_scaled
, self
.bar_edge(),
119 max_scaled
- min_scaled
, self
.desc
.width
)
121 self
.queue_draw_area(self
.bar_edge(), self
.length
- max_scaled
,
122 self
.desc
.width
, max_scaled
- min_scaled
)
126 reading
= self
.scale_reading(self
.desc
.get_reading())
130 # Hopefully this should be equivalent to returning False
131 # so we won't get any more ticks for this gauge, but use
135 if reading
== self
.reading
:
136 period
= self
.period
* 2
137 if period
> self
.desc
.max_period
:
138 period
= self
.desc
.max_period
140 if self
.window
and self
.length
> 0:
141 min_scaled
= min(reading
, self
.reading
)
142 max_scaled
= max(reading
, self
.reading
)
143 self
.mark_for_redraw(min_scaled
, max_scaled
)
144 self
.reading
= reading
145 period
= self
.desc
.min_period
148 if period
== self
.period
:
152 gobject
.timeout_add(int(period
* 1000), self
.tick_cb
)
155 def expose_event_cb(self
, widget
, event
):
156 if not self
.caption_gc
:
157 self
.caption_gc
= self
.window
.new_gc()
158 self
.caption_gc
.copy(self
.get_style().fg_gc
[g
.STATE_NORMAL
])
159 self
.window
.draw_layout(self
.caption_gc
,
160 self
.caption_x0
, self
.caption_y0
, self
.caption_layout
)
161 if self
.orient
== HORIZ
:
165 x
= self
.caption_w
+ 3
166 filled_rect
= g
.gdk
.Rectangle(x
, self
.bar_edge(),
167 self
.reading
, self
.desc
.width
)
169 filled_rect
= g
.gdk
.Rectangle(self
.bar_edge(),
170 self
.length
- self
.reading
,
171 self
.desc
.width
, self
.reading
)
172 filled_rect
= filled_rect
.intersect(event
.area
)
174 self
.gc
= self
.window
.new_gc()
175 style
= self
.get_style()
176 self
.gc
.copy(style
.fg_gc
[g
.STATE_NORMAL
])
177 self
.__update
_gc
_colour
()
178 self
.gc
.set_function(g
.gdk
.XOR
)
179 self
.window
.draw_rectangle(self
.gc
, True, *filled_rect
)
182 def __update_gc_colour(self
):
183 style
= self
.get_style()
184 c1
= self
.desc
.colour
185 c2
= style
.bg
[g
.STATE_NORMAL
]
186 self
.gc
.set_rgb_fg_color(g
.gdk
.Color( \
187 c1
.red ^ c2
.red
, c1
.green ^ c2
.green
, c1
.blue ^ c2
.blue
))
189 def change_colour(self
, colour
):
191 self
.__update
_gc
_colour
()
194 def change_width(self
, width
):
195 if self
.orient
== HORIZ
:
196 self
.set_size_request(self
.length
, width
)
198 self
.set_size_request(width
, self
.length
)
200 def change_length(self
, length
):
202 if self
.orient
== HORIZ
:
203 self
.set_size_request(length
, self
.total_width
)
205 self
.set_size_request(self
.total_width
, length
)
206 self
.cache_caption_offsets()