Mercurial > fife-parpg
changeset 249:1cc51d145af9
Further split up the containers.py; bugfix.
author | phoku@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Thu, 26 Mar 2009 16:36:21 +0000 |
parents | a2d5e2721489 |
children | 6527d53c7133 |
files | engine/extensions/pychan/widgets/common.py engine/extensions/pychan/widgets/containers.py engine/extensions/pychan/widgets/layout.py engine/extensions/pychan/widgets/radiobutton.py engine/extensions/pychan/widgets/widget.py |
diffstat | 5 files changed, 166 insertions(+), 173 deletions(-) [+] |
line wrap: on
line diff
--- a/engine/extensions/pychan/widgets/common.py Thu Mar 26 16:20:16 2009 +0000 +++ b/engine/extensions/pychan/widgets/common.py Thu Mar 26 16:36:21 2009 +0000 @@ -7,6 +7,7 @@ from pychan.attrs import Attr,UnicodeAttr, PointAttr,ColorAttr,BoolAttr,IntAttr,FloatAttr from pychan.properties import ColorProperty +AlignTop, AlignBottom, AlignLeft, AlignRight, AlignCenter = range(5) def get_manager(): import pychan @@ -31,7 +32,7 @@ return unicode(text,"utf8",*get_manager().unicodePolicy) def isLayouted(widget): - from containers import LayoutBase + from layout import LayoutBase return isinstance(widget,LayoutBase) class DummyImage(object):
--- a/engine/extensions/pychan/widgets/containers.py Thu Mar 26 16:20:16 2009 +0000 +++ b/engine/extensions/pychan/widgets/containers.py Thu Mar 26 16:36:21 2009 +0000 @@ -2,8 +2,7 @@ from common import * from widget import Widget - -### Containers + Layout code ### +from layout import VBoxLayoutMixin, HBoxLayoutMixin class Container(Widget): """ @@ -112,168 +111,6 @@ def _getOpaque(self): return self.real_widget.isOpaque() opaque = property(_getOpaque,_setOpaque) -AlignTop, AlignBottom, AlignLeft, AlignRight, AlignCenter = range(5) - -class LayoutBase(object): - """ - This class is at the core of the layout engine. The two MixIn classes L{VBoxLayoutMixin} - and L{HBoxLayoutMixin} specialise on this by reimplementing the C{resizeToContent} and - the C{expandContent} methods. - - Dynamic Layouting - ----------------- - - The layout is calculated in the L{Widget.show} method. Thus if you modify the layout, - by adding or removing child widgets for example, you have to call L{Widget.adaptLayout} - so that the changes ripple through the widget hierachy. - - Internals - --------- - - At the core the layout engine works in two passes: - - Before a root widget loaded by the XML code is shown, its resizeToContent method - is called recursively (walking the widget containment relation in post order). - This shrinks all HBoxes and VBoxes to their minimum heigt and width. - After that the expandContent method is called recursively in the same order, - which will re-align the widgets if there is space left AND if a Spacer is contained. - - Inside bare Container instances (without a Layout MixIn) absolute positioning - can be used. - """ - def __init__(self,align = (AlignLeft,AlignTop), **kwargs): - self.align = align - self.spacer = None - super(LayoutBase,self).__init__(**kwargs) - - def addSpacer(self,spacer): - if self.spacer: - raise RuntimeException("Already a Spacer in %s!" % str(self)) - self.spacer = spacer - spacer.index = len(self.children) - - def xdelta(self,widget):return 0 - def ydelta(self,widget):return 0 - - def _adjustHeight(self): - if self.align[1] == AlignTop:return #dy = 0 - if self.align[1] == AlignBottom: - y = self.height - self.childarea[1] - self.border_size - self.margins[1] - else: - y = (self.height - self.childarea[1] - self.border_size - self.margins[1])/2 - for widget in self.children: - widget.y = y - y += self.ydelta(widget) - - def _adjustHeightWithSpacer(self): - pass - - def _adjustWidth(self): - if self.align[0] == AlignLeft:return #dx = 0 - if self.align[0] == AlignRight: - x = self.width - self.childarea[0] - self.border_size - self.margins[0] - else: - x = (self.width - self.childarea[0] - self.border_size - self.margins[0])/2 - for widget in self.children: - widget.x = x - x += self.xdelta(widget) - - def _expandWidthSpacer(self): - x = self.border_size + self.margins[0] - xdelta = map(self.xdelta,self.children) - - for widget in self.children[:self.spacer.index]: - widget.x = x - x += xdelta.pop(0) - - x = self.width - sum(xdelta) - self.border_size - self.margins[0] - for widget in self.children[self.spacer.index:]: - widget.x = x - x += xdelta.pop(0) - - def _expandHeightSpacer(self): - y = self.border_size + self.margins[1] - ydelta = map(self.ydelta,self.children) - - for widget in self.children[:self.spacer.index]: - widget.y = y - y += ydelta.pop(0) - - y = self.height - sum(ydelta) - self.border_size - self.margins[1] - for widget in self.children[self.spacer.index:]: - widget.y = y - y += ydelta.pop(0) - - -class VBoxLayoutMixin(LayoutBase): - """ - A mixin class for a vertical layout. Do not use directly. - """ - def __init__(self,**kwargs): - super(VBoxLayoutMixin,self).__init__(**kwargs) - - def resizeToContent(self, recurse = True): - max_w = self.getMaxChildrenWidth() - x = self.margins[0] + self.border_size - y = self.margins[1] + self.border_size - for widget in self.children: - widget.x = x - widget.y = y - widget.width = max_w - y += widget.height + self.padding - - #Add the padding for the spacer. - if self.spacer: - y += self.padding - - self.height = y + self.margins[1] - self.padding - self.width = max_w + 2*x - self.childarea = max_w, y - self.padding - self.margins[1] - - self._adjustHeight() - self._adjustWidth() - - def expandContent(self): - if self.spacer: - self._expandHeightSpacer() - - def ydelta(self,widget):return widget.height + self.padding - -class HBoxLayoutMixin(LayoutBase): - """ - A mixin class for a horizontal layout. Do not use directly. - """ - def __init__(self,**kwargs): - super(HBoxLayoutMixin,self).__init__(**kwargs) - - def resizeToContent(self, recurse = True): - max_h = self.getMaxChildrenHeight() - x = self.margins[0] + self.border_size - y = self.margins[1] + self.border_size - for widget in self.children: - widget.x = x - widget.y = y - widget.height = max_h - x += widget.width + self.padding - - #Add the padding for the spacer. - if self.spacer: - x += self.padding - - self.width = x + self.margins[0] - self.padding - self.height = max_h + 2*y - self.childarea = x - self.margins[0] - self.padding, max_h - - self._adjustHeight() - self._adjustWidth() - - def expandContent(self): - if self.spacer: - self._expandWidthSpacer() - - def xdelta(self,widget):return widget.width + self.padding - - class VBox(VBoxLayoutMixin,Container): """ A vertically aligned box - for containement of child widgets.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/extensions/pychan/widgets/layout.py Thu Mar 26 16:36:21 2009 +0000 @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- + +from common import * + +class LayoutBase(object): + """ + This class is at the core of the layout engine. The two MixIn classes L{VBoxLayoutMixin} + and L{HBoxLayoutMixin} specialise on this by reimplementing the C{resizeToContent} and + the C{expandContent} methods. + + Dynamic Layouting + ----------------- + + The layout is calculated in the L{Widget.show} method. Thus if you modify the layout, + by adding or removing child widgets for example, you have to call L{Widget.adaptLayout} + so that the changes ripple through the widget hierachy. + + Internals + --------- + + At the core the layout engine works in two passes: + + Before a root widget loaded by the XML code is shown, its resizeToContent method + is called recursively (walking the widget containment relation in post order). + This shrinks all HBoxes and VBoxes to their minimum heigt and width. + After that the expandContent method is called recursively in the same order, + which will re-align the widgets if there is space left AND if a Spacer is contained. + + Inside bare Container instances (without a Layout MixIn) absolute positioning + can be used. + """ + def __init__(self,align = (AlignLeft,AlignTop), **kwargs): + self.align = align + self.spacer = None + super(LayoutBase,self).__init__(**kwargs) + + def addSpacer(self,spacer): + if self.spacer: + raise RuntimeException("Already a Spacer in %s!" % str(self)) + self.spacer = spacer + spacer.index = len(self.children) + + def xdelta(self,widget):return 0 + def ydelta(self,widget):return 0 + + def _adjustHeight(self): + if self.align[1] == AlignTop:return #dy = 0 + if self.align[1] == AlignBottom: + y = self.height - self.childarea[1] - self.border_size - self.margins[1] + else: + y = (self.height - self.childarea[1] - self.border_size - self.margins[1])/2 + for widget in self.children: + widget.y = y + y += self.ydelta(widget) + + def _adjustHeightWithSpacer(self): + pass + + def _adjustWidth(self): + if self.align[0] == AlignLeft:return #dx = 0 + if self.align[0] == AlignRight: + x = self.width - self.childarea[0] - self.border_size - self.margins[0] + else: + x = (self.width - self.childarea[0] - self.border_size - self.margins[0])/2 + for widget in self.children: + widget.x = x + x += self.xdelta(widget) + + def _expandWidthSpacer(self): + x = self.border_size + self.margins[0] + xdelta = map(self.xdelta,self.children) + + for widget in self.children[:self.spacer.index]: + widget.x = x + x += xdelta.pop(0) + + x = self.width - sum(xdelta) - self.border_size - self.margins[0] + for widget in self.children[self.spacer.index:]: + widget.x = x + x += xdelta.pop(0) + + def _expandHeightSpacer(self): + y = self.border_size + self.margins[1] + ydelta = map(self.ydelta,self.children) + + for widget in self.children[:self.spacer.index]: + widget.y = y + y += ydelta.pop(0) + + y = self.height - sum(ydelta) - self.border_size - self.margins[1] + for widget in self.children[self.spacer.index:]: + widget.y = y + y += ydelta.pop(0) + + +class VBoxLayoutMixin(LayoutBase): + """ + A mixin class for a vertical layout. Do not use directly. + """ + def __init__(self,**kwargs): + super(VBoxLayoutMixin,self).__init__(**kwargs) + + def resizeToContent(self, recurse = True): + max_w = self.getMaxChildrenWidth() + x = self.margins[0] + self.border_size + y = self.margins[1] + self.border_size + for widget in self.children: + widget.x = x + widget.y = y + widget.width = max_w + y += widget.height + self.padding + + #Add the padding for the spacer. + if self.spacer: + y += self.padding + + self.height = y + self.margins[1] - self.padding + self.width = max_w + 2*x + self.childarea = max_w, y - self.padding - self.margins[1] + + self._adjustHeight() + self._adjustWidth() + + def expandContent(self): + if self.spacer: + self._expandHeightSpacer() + + def ydelta(self,widget):return widget.height + self.padding + +class HBoxLayoutMixin(LayoutBase): + """ + A mixin class for a horizontal layout. Do not use directly. + """ + def __init__(self,**kwargs): + super(HBoxLayoutMixin,self).__init__(**kwargs) + + def resizeToContent(self, recurse = True): + max_h = self.getMaxChildrenHeight() + x = self.margins[0] + self.border_size + y = self.margins[1] + self.border_size + for widget in self.children: + widget.x = x + widget.y = y + widget.height = max_h + x += widget.width + self.padding + + #Add the padding for the spacer. + if self.spacer: + x += self.padding + + self.width = x + self.margins[0] - self.padding + self.height = max_h + 2*y + self.childarea = x - self.margins[0] - self.padding, max_h + + self._adjustHeight() + self._adjustWidth() + + def expandContent(self): + if self.spacer: + self._expandWidthSpacer() + + def xdelta(self,widget):return widget.width + self.padding
--- a/engine/extensions/pychan/widgets/radiobutton.py Thu Mar 26 16:20:16 2009 +0000 +++ b/engine/extensions/pychan/widgets/radiobutton.py Thu Mar 26 16:36:21 2009 +0000 @@ -43,5 +43,5 @@ group = property(_getGroup,_setGroup) def resizeToContent(self,recurse=True): - self.width = self.real_font.getWidth(_text2gui(self.text)) + 35# Size of the Checked box? + self.width = self.real_font.getWidth(text2gui(self.text)) + 35# Size of the Checked box? self.height = self.real_font.getHeight()
--- a/engine/extensions/pychan/widgets/widget.py Thu Mar 26 16:20:16 2009 +0000 +++ b/engine/extensions/pychan/widgets/widget.py Thu Mar 26 16:36:21 2009 +0000 @@ -1,12 +1,5 @@ # -*- coding: utf-8 -*- -import fife, pythonize -import pychan.tools as tools -import pychan.events as events -from pychan.exceptions import * -from pychan.attrs import Attr,UnicodeAttr, PointAttr,ColorAttr,BoolAttr,IntAttr,FloatAttr -from pychan.properties import ColorProperty - from pychan.widgets.common import * class Widget(object):