1
by Jan Jokela
Hi, Glitter here |
1 |
# !/usr/bin/python
|
2 |
# -*- coding: utf-8 -*-
|
|
3 |
||
4 |
# Glitter Toolkit
|
|
5 |
||
6 |
__authors__ = ["Jan Jokela <janjokela@gmail.com>"] |
|
7 |
__licenses__ = ["LICENSE.LGPL"] |
|
8 |
__description__ = "Horizontal and vertical box widgets" |
|
9 |
||
10 |
import gobject |
|
11 |
import pango |
|
12 |
import clutter |
|
13 |
||
14 |
from container import Container |
|
15 |
||
16 |
class Box(Container): |
|
17 |
"""
|
|
18 |
A box is a special type of container for displaying multiple children in
|
|
19 |
an horizontal or vertical layout.
|
|
20 |
|
|
7.1.14
by Jan Jokela
(glitter/box.py) API changes to the box widget |
21 |
The 'Box' base widgets offers a common interface to all box widgets
|
22 |
|
|
1
by Jan Jokela
Hi, Glitter here |
23 |
"""
|
24 |
||
7.1.13
by Jan Jokela
(Commit FIX) |
25 |
def __init__(self): |
1
by Jan Jokela
Hi, Glitter here |
26 |
""" Initialize box """
|
27 |
||
28 |
super(Box, self).__init__() |
|
29 |
||
7.1.13
by Jan Jokela
(Commit FIX) |
30 |
self._spacing = 0.0 |
1
by Jan Jokela
Hi, Glitter here |
31 |
self._alignment = 1 |
32 |
self.packed_children = [] |
|
33 |
||
34 |
self._update_style(self.style) |
|
35 |
||
36 |
def _update_style(self, props=None): |
|
37 |
""" Updates style """
|
|
38 |
||
39 |
super(Box, self)._update_style(props) |
|
40 |
||
41 |
for key, value in props: |
|
42 |
if key == 'spacing': |
|
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
43 |
self._spacing = value |
1
by Jan Jokela
Hi, Glitter here |
44 |
elif key == 'alignment': |
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
45 |
self._alignment = value |
1
by Jan Jokela
Hi, Glitter here |
46 |
|
47 |
def _update_layout(self): |
|
48 |
""" Update layout """
|
|
49 |
||
7.1.6
by Jan Jokela
(glitter/box.py) Added clipping to the box widgets |
50 |
super(Box, self)._update_layout() |
51 |
||
52 |
self.set_clip(0, 0, self.get_width(), self.get_height()) |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
53 |
|
54 |
def _update_fixed_widgets(self, child): |
|
55 |
""" Update list of fixed width/height children """
|
|
56 |
||
57 |
pass
|
|
1
by Jan Jokela
Hi, Glitter here |
58 |
|
7.1.14
by Jan Jokela
(glitter/box.py) API changes to the box widget |
59 |
def pack(self, child, order='after'): |
60 |
""" Packs a child into the box after or before current items
|
|
61 |
|
|
62 |
child -- (glitter.Widget) A Glitter widget
|
|
63 |
order -- (str) 'after' or 'before' currently packed items
|
|
64 |
"""
|
|
65 |
||
66 |
if order == 'after': |
|
67 |
self.packed_children.append(child) |
|
68 |
elif order == 'before': |
|
69 |
self.packed_children.insert(0, child) |
|
1
by Jan Jokela
Hi, Glitter here |
70 |
self.add(child) |
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
71 |
self._update_fixed_widgets(child) |
7.1.4
by Jan Jokela
(glitter/box.py) Fixed bug where packing a widget wouldn't refresh the layout |
72 |
self._update_layout() |
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
73 |
|
7.1.14
by Jan Jokela
(glitter/box.py) API changes to the box widget |
74 |
def unpack(self, child): |
75 |
""" Unpacks a child from a box
|
|
76 |
|
|
77 |
child -- (glitter.Widget) A Glitter widget
|
|
78 |
"""
|
|
79 |
||
80 |
self.packed_children.remove(child) |
|
81 |
self.remove(child) |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
82 |
self._update_fixed_widgets(child) |
7.1.14
by Jan Jokela
(glitter/box.py) API changes to the box widget |
83 |
self._update_layout() |
84 |
||
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
85 |
def get_packed_children(self): |
86 |
""" Retrieve packed children """
|
|
87 |
||
88 |
return self.packed_children |
|
1
by Jan Jokela
Hi, Glitter here |
89 |
|
90 |
def get_spacing(self): |
|
91 |
""" Retrieve child spacing """
|
|
92 |
||
93 |
return self._spacing |
|
94 |
||
95 |
def set_spacing(self, value): |
|
96 |
""" Sets child spacing
|
|
97 |
|
|
98 |
value -- (float) Spacing between children
|
|
99 |
"""
|
|
100 |
||
101 |
self._spacing = value |
|
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
102 |
self._update_layout() |
1
by Jan Jokela
Hi, Glitter here |
103 |
|
104 |
spacing = property(get_spacing, set_spacing) |
|
105 |
||
106 |
def get_alignment(self): |
|
107 |
""" Retrieve alignment """
|
|
108 |
||
109 |
return self._alignment |
|
110 |
||
111 |
def set_alignment(self, value): |
|
112 |
""" Sets children alignment
|
|
113 |
|
|
114 |
value -- (str) [ALINGMENT.START, ALIGNMENT.END, ALIGNMENT.CENTER]
|
|
115 |
"""
|
|
116 |
||
117 |
self._alignment = value |
|
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
118 |
self._update_layout() |
1
by Jan Jokela
Hi, Glitter here |
119 |
|
120 |
alignment = property(get_alignment, set_alignment) |
|
121 |
||
122 |
||
123 |
class HBox(Box): |
|
7.1.14
by Jan Jokela
(glitter/box.py) API changes to the box widget |
124 |
""" A HBox layouts children in an horizontal fashion """
|
1
by Jan Jokela
Hi, Glitter here |
125 |
|
7.1.13
by Jan Jokela
(Commit FIX) |
126 |
def __init__(self): |
1
by Jan Jokela
Hi, Glitter here |
127 |
""" Initialize horizontal box """
|
128 |
||
7.1.13
by Jan Jokela
(Commit FIX) |
129 |
super(HBox, self).__init__() |
1
by Jan Jokela
Hi, Glitter here |
130 |
|
131 |
self._update_style(self.style) |
|
132 |
||
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
133 |
self.fixed_width_children = [] |
134 |
||
1
by Jan Jokela
Hi, Glitter here |
135 |
def _update_style(self, props=None): |
136 |
""" Updates style """
|
|
7.1.12
by Jan Jokela
(glitter/box.py) Box widget spacing? |
137 |
|
1
by Jan Jokela
Hi, Glitter here |
138 |
super(HBox, self)._update_style(props) |
139 |
||
140 |
def _update_layout(self): |
|
141 |
""" Updates layout """
|
|
142 |
||
143 |
super(HBox, self)._update_layout() |
|
144 |
||
18.1.4
by Jan Jokela
(/glitter/container.py) Minor fixes; (/glitter/box.py) Fixes in box layout algorithm; (glitter/test_hbox.py) n.a.; (glitter/test_image.py) Sanitized imports so no warnings appear now |
145 |
if len(self.packed_children) > 0: |
26.1.4
by Jan Jokela
Minimum width buttons work again |
146 |
# Reserved width for spacing between widgets
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
147 |
reserved_width = self.spacing * (len(self.packed_children) - 1) * \ |
148 |
self.get_widthu() |
|
149 |
else: |
|
150 |
reserved_width = 0.0 |
|
151 |
||
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
152 |
# Update the reserved width given our fixed width children
|
153 |
for child in self.fixed_width_children: |
|
154 |
child._update_layout() |
|
155 |
# Increment reserved width by child height and horizontal
|
|
156 |
# offset
|
|
157 |
reserved_width += child.get_widthu() + \ |
|
158 |
child.h_offset * child.get_widthu() * 2.0 |
|
26.1.4
by Jan Jokela
Minimum width buttons work again |
159 |
self.minimum_width = reserved_width |
160 |
super(HBox, self)._update_layout() |
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
161 |
|
162 |
# Total width excluding reserved width
|
|
163 |
free_width = self.get_widthu() - reserved_width |
|
164 |
# Width for variable width children
|
|
165 |
var_width_child_count = len(self.packed_children) - \ |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
166 |
len(self.fixed_width_children) |
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
167 |
var_child_width = free_width |
168 |
if var_width_child_count > 0: |
|
169 |
var_child_width /= var_width_child_count |
|
170 |
||
171 |
# Position all children
|
|
172 |
current_x = 0.0 |
|
173 |
for child in self.packed_children: |
|
26.1.7
by Jan Jokela
(glitter/box.py) Improved code documentation |
174 |
# Calculate child offset width and add that to the current x pos
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
175 |
if child not in self.fixed_width_children: |
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
176 |
offset_width = var_child_width * child.h_offset |
177 |
else: |
|
178 |
offset_width = child.h_offset * child.get_widthu() |
|
179 |
current_x += offset_width |
|
26.1.7
by Jan Jokela
(glitter/box.py) Improved code documentation |
180 |
# Position children
|
18.1.6
by Jan Jokela
(glitter/data/themes/nublo/styles/button.json) @.@ |
181 |
if self.get_widthu() > 0: |
182 |
child.natural_x = current_x / self.get_widthu() |
|
26.1.7
by Jan Jokela
(glitter/box.py) Improved code documentation |
183 |
# Size variable width children
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
184 |
if child not in self.fixed_width_children: |
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
185 |
child.natural_width = (var_child_width - 2 * offset_width) \ |
186 |
/ self.get_widthu() |
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
187 |
child._update_layout() |
26.1.7
by Jan Jokela
(glitter/box.py) Improved code documentation |
188 |
# Add child width, horizontal offset and box spacing to current x
|
18.1.5
by Jan Jokela
(glitter/box.py) Huge improvements in horizontal box algorithm; (glitter/tests/test_hbox.py) Tests clean; (glitter/container.py) Position now set in device independent units, again |
189 |
current_x += child.get_widthu() |
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
190 |
current_x += child.get_widthu() * child.h_offset |
191 |
current_x += self.get_widthu() * self.spacing |
|
26.1.9
by Jan Jokela
(glitter/button.py) Button layout code |
192 |
self.set_clipu(0, 0, self.get_widthu(), self.get_heightu()) |
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
193 |
|
194 |
def _update_fixed_widgets(self, child): |
|
195 |
""" Updates fixed width children list """
|
|
196 |
||
197 |
super(HBox, self)._update_fixed_widgets(child) |
|
198 |
||
199 |
if child in self.fixed_width_children: |
|
200 |
self.fixed_width_children.remove(child) |
|
201 |
elif child.size_ratio > 0 or child.natural_width == 0: |
|
202 |
self.fixed_width_children.append(child) |
|
203 |
||
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
204 |
class VBox(Box): |
205 |
""" A VBox layouts children in a vertical fashion """
|
|
206 |
||
207 |
def __init__(self): |
|
208 |
""" Initialize vertical box """
|
|
209 |
||
210 |
super(VBox, self).__init__() |
|
211 |
||
212 |
self._update_style(self.style) |
|
213 |
||
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
214 |
self.fixed_height_children = [] |
215 |
||
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
216 |
def _update_style(self, props=None): |
217 |
""" Updates style """
|
|
218 |
||
219 |
super(VBox, self)._update_style(props) |
|
220 |
||
221 |
def _update_layout(self): |
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
222 |
""" Updates layout
|
223 |
|
|
224 |
Fixed height children are flagged and will be offered the space they
|
|
225 |
need. Other children will share the remaining space.
|
|
226 |
|
|
227 |
Children with minimum height and width->height size ratios qualify as
|
|
228 |
fixed height.
|
|
229 |
"""
|
|
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
230 |
|
231 |
super(VBox, self)._update_layout() |
|
232 |
||
18.1.7
by Jan Jokela
(glitter/box.py) Fixed vertical box; (glitter/tests/test_vbox.py) Sanitized imports and improved test |
233 |
if len(self.packed_children) > 0: |
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
234 |
# Reserved height for spacing between widgets
|
18.1.7
by Jan Jokela
(glitter/box.py) Fixed vertical box; (glitter/tests/test_vbox.py) Sanitized imports and improved test |
235 |
reserved_height = self.spacing * (len(self.packed_children) - 1) * \ |
236 |
self.get_heightu() |
|
237 |
else: |
|
238 |
reserved_height = 0.0 |
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
239 |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
240 |
# Update the reserved height given our fixed height children
|
241 |
for child in self.fixed_height_children: |
|
242 |
child._update_layout() |
|
243 |
# Increment reserved height by child height and horizontal
|
|
244 |
# offset
|
|
245 |
reserved_height += child.get_heightu() + \ |
|
246 |
child.v_offset * child.get_heightu() * 2.0 |
|
247 |
self.minimum_height = reserved_height |
|
248 |
super(VBox, self)._update_layout() |
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
249 |
|
250 |
# Total height excluding reserved height
|
|
251 |
free_height = self.get_heightu() - reserved_height |
|
18.1.7
by Jan Jokela
(glitter/box.py) Fixed vertical box; (glitter/tests/test_vbox.py) Sanitized imports and improved test |
252 |
# Height for variable width children
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
253 |
var_height_child_count = len(self.packed_children) - \ |
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
254 |
len(self.fixed_height_children) |
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
255 |
var_child_height = free_height |
256 |
if var_height_child_count > 0: |
|
257 |
var_child_height /= var_height_child_count |
|
258 |
||
259 |
# Position all children
|
|
260 |
current_y = 0.0 |
|
261 |
for child in self.packed_children: |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
262 |
# Calculate child offset height and add that to the current y pos
|
263 |
if child not in self.fixed_height_children: |
|
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
264 |
offset_height = var_child_height * child.v_offset |
265 |
else: |
|
266 |
offset_height = child.v_offset * child.get_heightu() |
|
267 |
current_y += offset_height |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
268 |
# Position children
|
18.1.7
by Jan Jokela
(glitter/box.py) Fixed vertical box; (glitter/tests/test_vbox.py) Sanitized imports and improved test |
269 |
if self.get_heightu() > 0: |
270 |
child.natural_y = current_y / self.get_heightu() |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
271 |
# Size variable height children
|
272 |
if child not in self.fixed_height_children: |
|
18.1.12
by Jan Jokela
(glitter/tests/*) Added and improved a bunch of tests; (glitter/data/themes/nublo/styles/label.json) Fixes in label widget style; (glitter/box.py) Layout code fixes |
273 |
child.natural_height = (var_child_height - 2 * offset_height) \ |
274 |
/ self.get_heightu() |
|
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
275 |
child._update_layout() |
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
276 |
# Add child height, vertical offset and box spacing to current y
|
18.1.7
by Jan Jokela
(glitter/box.py) Fixed vertical box; (glitter/tests/test_vbox.py) Sanitized imports and improved test |
277 |
current_y += child.get_heightu() |
18.1.3
by Jan Jokela
(glitter/box.py) Algorithm improvements |
278 |
current_y += child.get_heightu() * child.v_offset |
279 |
current_y += self.get_heightu() * self.spacing |
|
18.1.7
by Jan Jokela
(glitter/box.py) Fixed vertical box; (glitter/tests/test_vbox.py) Sanitized imports and improved test |
280 |
|
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
281 |
def get_item(self, i): |
282 |
""" Retrieve natural y for packed item i """
|
|
283 |
||
284 |
if len(self.packed_children) > i: |
|
285 |
return self.packed_children[i] |
|
286 |
else: |
|
287 |
return None |
|
288 |
||
289 |
def get_item_natural_height(self, i): |
|
290 |
""" Retrieve natural height for packed item i """
|
|
291 |
||
292 |
if len(self.packed_children) > i: |
|
293 |
return self.packed_children[i].natural_height |
|
294 |
else: |
|
295 |
return -1 |
|
26.1.8
by Jan Jokela
(glitter/box.py) Improved algorithms for box widgets; (glitter/test_vbox.py) Fix |
296 |
|
297 |
def _update_fixed_widgets(self, child): |
|
298 |
""" Updates fixed height children list """
|
|
299 |
||
300 |
super(VBox, self)._update_fixed_widgets(child) |
|
301 |
||
302 |
if child in self.fixed_height_children: |
|
303 |
self.fixed_height_children.remove(child) |
|
304 |
elif child.size_ratio < 0 or child.natural_height == 0: |
|
305 |
self.fixed_height_children.append(child) |
|
306 |
||
5.1.1
by Jan Jokela
Added list widget, 'Scrollable' interface |
307 |