1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from common import *
25 from widget import Widget
26 from layout import VBoxLayoutMixin, HBoxLayoutMixin
27
29 """
30 This is the basic container class. It provides space in which child widgets can
31 be position via the position attribute. If you want to use the layout engine,
32 you have to use derived containers with vertical or horizontal orientation
33 (L{VBox} or L{HBox})
34
35 New Attributes
36 ==============
37
38 - padding - Integer: Not used in the Container class istelf, distance between child widgets.
39 - background_image - Set this to a GuiImage or a resource location (simply a filename).
40 The image will be tiled over the background area.
41 - opaque - Boolean: Whether the background should be drawn at all. Set this to False
42 to make the widget transparent.
43 - children - Just contains the list of contained child widgets. Do NOT modify.
44 """
45
46 ATTRIBUTES = Widget.ATTRIBUTES + [ IntAttr('padding'),
47 Attr('background_image'),
48 BoolAttr('opaque'),
49 PointAttr('margins')
50 ]
51
52 DEFAULT_OPAQUE = True
53 DEFAULT_MARGINS = 5,5
54 DEFAULT_PADDING = 5
55 DEFAULT_BACKGROUND = None
56
57 - def __init__(self,
58 parent = None,
59 name = None,
60 size = None,
61 min_size = None,
62 max_size = None,
63 helptext = None,
64 position = None,
65 style = None,
66 hexpand = None,
67 vexpand = None,
68 font = None,
69 base_color = None,
70 background_color = None,
71 foreground_color = None,
72 selection_color = None,
73 border_size = None,
74 position_technique = None,
75 is_focusable = None,
76 comment = None,
77 padding = None,
78 background_image = None,
79 opaque = None,
80 margins = None,
81 _real_widget = None):
82
83 self.real_widget = _real_widget or fife.Container()
84 self.children = []
85 self.children_position_cache = []
86 self.hidden_children = []
87 self._background = []
88 self._background_image = None
89 self.background_image = self.DEFAULT_BACKGROUND
90 self.margins = self.DEFAULT_MARGINS
91 self.padding = self.DEFAULT_PADDING
92 self.opaque = self.DEFAULT_OPAQUE
93
94 super(Container,self).__init__(parent=parent,
95 name=name,
96 size=size,
97 min_size=min_size,
98 max_size=max_size,
99 helptext=helptext,
100 position=position,
101 style=style,
102 hexpand=hexpand,
103 vexpand=vexpand,
104 font=font,
105 base_color=base_color,
106 background_color=background_color,
107 foreground_color=foreground_color,
108 selection_color=selection_color,
109 border_size=border_size,
110 position_technique=position_technique,
111 is_focusable=is_focusable,
112 comment=comment)
113
114 if margins is not None: self.margins = margins
115 if padding is not None: self.padding = padding
116 if opaque is not None: self.opaque = opaque
117 if background_image is not None: self.background_image = background_image
118
119 - def clone(self, prefix):
120 containerClone = Container(None,
121 self._createNameWithPrefix(prefix),
122 self.size,
123 self.min_size,
124 self.max_size,
125 self.helptext,
126 self.position,
127 self.style,
128 self.hexpand,
129 self.vexpand,
130 self.font,
131 self.base_color,
132 self.background_color,
133 self.foreground_color,
134 self.selection_color,
135 self.border_size,
136 self.position_technique,
137 self.is_focusable,
138 self.comment,
139 self.padding,
140 self.background_image,
141 self.opaque,
142 self.margins)
143
144 containerClone.addChildren(self._cloneChildren(prefix))
145
146 return containerClone
147
148
150 """
151 Adds a child widget to the container.
152
153 This makes the childs widgets visible state the same as the containers.
154 i.e. if the containter is visible the child will be as well and if the
155 container widget is hidden so will the child. The child however WILL
156 be shown when you show the container widget. If you want the child to
157 be hidden when you show the container widget you must call child.hide().
158 """
159
160 widget.parent = self
161 widget._visible = self._visible
162 self.children.append(widget)
163 self.children_position_cache.append(widget)
164 self.real_widget.add(widget.real_widget)
165
166
167
168 if self._visible:
169 def _show(shown_widget):
170 shown_widget._visible = True
171
172 self.deepApply(_show, shown_only=True)
173 else:
174 def _hide(hidden_widget):
175 hidden_widget._visible = False
176
177 self.deepApply(_hide)
178
196
198 if before not in self.children:
199 raise RuntimeError("Couldn't find widget %s as child of %s - in insertChildBefore" % (str(widget),str(before)))
200 self.insertChild(widget, self.children.index(before))
201
217
219 if not child in self.children:
220 raise RuntimeError("%s does not have %s as direct child widget." % (str(self), str(child)))
221
222 self.hidden_children.append(child)
223 self.children.remove(child)
224
225 self.real_widget.remove(child.real_widget)
226 child._visible = False
227
229 if not child in self.hidden_children:
230 return
231
232 self.hidden_children.remove(child)
233
234 children = self.children[:]
235 children_position_cache = self.children_position_cache[:]
236 hidden_children = self.hidden_children[:]
237
238 for widget in children:
239 self.removeChild(widget)
240
241 for child_widget in children_position_cache:
242 if not child_widget in hidden_children:
243 self.addChild(child_widget)
244
245 self.children_position_cache = children_position_cache[:]
246 self.hidden_children = hidden_children[:]
247
248 - def add(self,*widgets):
249 print "PyChan: Deprecation warning: Please use 'addChild' or 'addChildren' instead."
250 self.addChildren(*widgets)
251
255
259
260 - def deepApply(self,visitorFunc, leaves_first = True, shown_only = False):
261 if not shown_only:
262 children = self.children + self.hidden_children
263 else:
264 children = self.children
265
266 if leaves_first:
267 for child in children:
268 child.deepApply(visitorFunc, leaves_first = leaves_first, shown_only = shown_only)
269 visitorFunc(self)
270 if not leaves_first:
271 for child in children:
272 child.deepApply(visitorFunc, leaves_first = leaves_first, shown_only = shown_only)
273
276
278 image = self._background_image
279 if image is None:
280 return
281
282 back_w,back_h = self.width, self.height
283 image_w, image_h = image.getWidth(), image.getHeight()
284
285 map(self.real_widget.remove,self._background)
286
287
288 self._background = []
289 icon = fife.Icon(image)
290 x, w = 0, image_w
291 while x < back_w:
292 y, h = 0, image_h
293 while y < self.height:
294 icon = fife.Icon(image)
295 icon.setPosition(x,y)
296 self._background.append(icon)
297 y += h
298 x += w
299 map(self.real_widget.add,self._background)
300 for tile in self._background:
301 tile.requestMoveToBottom()
302
304 self._background = getattr(self,'_background',None)
305 if image is None:
306 self._background_image = None
307 map(self.real_widget.remove,self._background)
308 self._background = []
309 return
310
311
312 if not isinstance(image, fife.GuiImage):
313 image = get_manager().loadImage(image)
314 self._background_image = image
315
317 background_image = property(getBackgroundImage,setBackgroundImage)
318
321 opaque = property(_getOpaque,_setOpaque)
322
324 """
325 Clones each child and return the clones in a list.
326 """
327 cloneList = []
328
329 for child in self.children:
330 cloneList.append(child.clone(prefix))
331
332 return cloneList
333
334 -class VBox(VBoxLayoutMixin,Container):
335 """
336 A vertically aligned box - for containement of child widgets.
337
338 Widgets added to this container widget, will layout on top of each other.
339 Also the minimal width of the container will be the maximum of the minimal
340 widths of the contained widgets.
341
342 The default alignment is to the top. This can be changed by adding a Spacer
343 to the widget at any point (but only one!). The spacer will expand, so that
344 widgets above the spacer are aligned to the top, while widgets below the spacer
345 are aligned to the bottom.
346 """
347 DEFAULT_HEXPAND = 0
348 DEFAULT_VEXPAND = 1
349
350 - def __init__(self,
351 parent = None,
352 name = None,
353 size = None,
354 min_size = None,
355 max_size = None,
356 helptext = None,
357 position = None,
358 style = None,
359 hexpand = None,
360 vexpand = None,
361 font = None,
362 base_color = None,
363 background_color = None,
364 foreground_color = None,
365 selection_color = None,
366 border_size = None,
367 position_technique = None,
368 is_focusable = None,
369 comment = None,
370 padding = None,
371 background_image = None,
372 opaque = None,
373 margins = None,
374 _real_widget = None):
375
376 super(VBox,self).__init__(parent=parent,
377 name=name,
378 size=size,
379 min_size=min_size,
380 max_size=max_size,
381 helptext=helptext,
382 position=position,
383 style=style,
384 hexpand=hexpand,
385 vexpand=vexpand,
386 font=font,
387 base_color=base_color,
388 background_color=background_color,
389 foreground_color=foreground_color,
390 selection_color=selection_color,
391 border_size=border_size,
392 position_technique=position_technique,
393 is_focusable=is_focusable,
394 comment=comment,
395 padding=padding,
396 background_image=background_image,
397 opaque=opaque,
398 margins=margins,
399 _real_widget=_real_widget)
400 - def clone(self, prefix):
401 vboxClone = VBox(None,
402 self._createNameWithPrefix(prefix),
403 self.size,
404 self.min_size,
405 self.max_size,
406 self.helptext,
407 self.position,
408 self.style,
409 self.hexpand,
410 self.vexpand,
411 self.font,
412 self.base_color,
413 self.background_color,
414 self.foreground_color,
415 self.selection_color,
416 self.border_size,
417 self.position_technique,
418 self.is_focusable,
419 self.comment,
420 self.padding,
421 self.background_image,
422 self.opaque,
423 self.margins)
424
425 vboxClone.addChildren(self._cloneChildren(prefix))
426
427 return vboxClone
428
429
430 -class HBox(HBoxLayoutMixin,Container):
431 """
432 A horizontally aligned box - for containement of child widgets.
433
434 Please see L{VBox} for details - just change the directions :-).
435 """
436 DEFAULT_HEXPAND = 1
437 DEFAULT_VEXPAND = 0
438
439 - def __init__(self,
440 parent = None,
441 name = None,
442 size = None,
443 min_size = None,
444 max_size = None,
445 helptext = None,
446 position = None,
447 style = None,
448 hexpand = None,
449 vexpand = None,
450 font = None,
451 base_color = None,
452 background_color = None,
453 foreground_color = None,
454 selection_color = None,
455 border_size = None,
456 position_technique = None,
457 is_focusable = None,
458 comment = None,
459 padding = None,
460 background_image = None,
461 opaque = None,
462 margins = None,
463 _real_widget = None):
464
465 super(HBox,self).__init__(parent=parent,
466 name=name,
467 size=size,
468 min_size=min_size,
469 max_size=max_size,
470 helptext=helptext,
471 position=position,
472 style=style,
473 hexpand=hexpand,
474 vexpand=vexpand,
475 font=font,
476 base_color=base_color,
477 background_color=background_color,
478 foreground_color=foreground_color,
479 selection_color=selection_color,
480 border_size=border_size,
481 position_technique=position_technique,
482 is_focusable=is_focusable,
483 comment=comment,
484 padding=padding,
485 background_image=background_image,
486 opaque=opaque,
487 margins=margins,
488 _real_widget=_real_widget)
489
490 - def clone(self, prefix):
491 hboxClone = HBox(None,
492 self._createNameWithPrefix(prefix),
493 self.size,
494 self.min_size,
495 self.max_size,
496 self.helptext,
497 self.position,
498 self.style,
499 self.hexpand,
500 self.vexpand,
501 self.font,
502 self.base_color,
503 self.background_color,
504 self.foreground_color,
505 self.selection_color,
506 self.border_size,
507 self.position_technique,
508 self.is_focusable,
509 self.comment,
510 self.padding,
511 self.background_image,
512 self.opaque,
513 self.margins)
514
515 hboxClone.addChildren(self._cloneChildren(prefix))
516
517 return hboxClone
518
519
520 -class Window(VBoxLayoutMixin,Container):
521 """
522 A L{VBox} with a draggable title bar aka a window
523
524 New Attributes
525 ==============
526
527 - title: The Caption of the window
528 - titlebar_height: The height of the window title bar
529 """
530
531 ATTRIBUTES = Container.ATTRIBUTES + [ UnicodeAttr('title'),
532 IntAttr('titlebar_height')
533 ]
534
535 DEFAULT_TITLE = u"title"
536 DEFAULT_TITLE_HEIGHT = 0
537 DEFAULT_POSITION_TECHNIQUE = "automatic"
538
539 - def __init__(self,
540 parent = None,
541 name = None,
542 size = None,
543 min_size = None,
544 max_size = None,
545 helptext = None,
546 position = None,
547 style = None,
548 hexpand = None,
549 vexpand = None,
550 font = None,
551 base_color = None,
552 background_color = None,
553 foreground_color = None,
554 selection_color = None,
555 border_size = None,
556 position_technique = None,
557 is_focusable = None,
558 comment = None,
559 padding = None,
560 background_image = None,
561 opaque = None,
562 margins = None,
563 _real_widget = None,
564 title = None,
565 titlebar_height = None):
566
567 super(Window,self).__init__(parent=parent,
568 name=name,
569 size=size,
570 min_size=min_size,
571 max_size=max_size,
572 helptext=helptext,
573 position=position,
574 style=style,
575 hexpand=hexpand,
576 vexpand=vexpand,
577 font=font,
578 base_color=base_color,
579 background_color=background_color,
580 foreground_color=foreground_color,
581 selection_color=selection_color,
582 border_size=border_size,
583 position_technique=position_technique,
584 is_focusable=is_focusable,
585 comment=comment,
586 padding=padding,
587 background_image=background_image,
588 opaque=opaque,
589 margins=margins,
590 _real_widget= fife.Window())
591
592 if titlebar_height is not None:
593 if titlebar_height == 0:
594 titlebar_height = self.real_font.getHeight() + 4
595 self.titlebar_height = titlebar_height
596 else:
597 self.titlebar_height = self.real_font.getHeight() + 4
598
599 if title is not None:
600 self.title = title
601 else:
602 self.title = self.DEFAULT_TITLE
603
604 - def clone(self, prefix):
605
606 windowClone = Window(None,
607 self._createNameWithPrefix(prefix),
608 self.size,
609 self.min_size,
610 self.max_size,
611 self.helptext,
612 self.position,
613 self.style,
614 self.hexpand,
615 self.vexpand,
616 self.font,
617 self.base_color,
618 self.background_color,
619 self.foreground_color,
620 self.selection_color,
621 self.border_size,
622 self.position_technique,
623 self.is_focusable,
624 self.comment,
625 self.padding,
626 self.background_image,
627 self.opaque,
628 self.margins,
629 None,
630 self.title,
631 self.titlebar_height
632 )
633
634 windowClone.addChildren(self._cloneChildren(prefix))
635
636 return windowClone
637
640 title = property(_getTitle,_setTitle)
641
644 titlebar_height = property(_getTitleBarHeight,_setTitleBarHeight)
645
646
647
653 height = property(_getHeight,_setHeight)
654