diff options
author | Sin Nombre <sin@ubuntu.(none)> | 2010-05-28 20:45:29 (GMT) |
---|---|---|
committer | Sin Nombre <sin@ubuntu.(none)> | 2010-05-28 20:45:29 (GMT) |
commit | 9e93d1b9802385900b6f833f81f84c0ac50f91ef (patch) | |
tree | f2c16599bde31b31e5d44bae4a87e7e4093f3cab /pgu/gui/layout.py | |
parent | ac8cbb6691ba3de1c7c42f4362edbe11270f4506 (diff) |
Diffstat (limited to 'pgu/gui/layout.py')
-rw-r--r-- | pgu/gui/layout.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/pgu/gui/layout.py b/pgu/gui/layout.py new file mode 100644 index 0000000..01fe0cb --- /dev/null +++ b/pgu/gui/layout.py @@ -0,0 +1,172 @@ +"""document layout engine.""" +class Layout: + """the document layout engine + + .widgets -- elements are kept in this list. read-only, use add to add items to it. + """ + + def __init__(self,rect=None): + """initialize the object with the size of the box.""" + self._widgets = [] + self.rect = rect + + def add(self,e): + """add a document element to the layout. + + a document element may be + - a tuple (w,h) if it is a whitespace element + - a tuple (0,h) if it is a linebreak element + - an integer -1,0,1 if it is a command to start a new block of elements that are aligned either left,center, or right. + - an object with a .rect (for size) -- such as a word element + - an object with a .rect (for size) and .align -- such as an image element + """ + + self._widgets.append(e) + + + def resize(self): + """resize the layout + this method recalculates the position of all document elements + after they have been added to the document. .rect.x,y will be updated for all + objects. + """ + self.init() + self.widgets = [] + for e in self._widgets: + if type(e) is tuple and e[0] != 0: + self.do_space(e) + elif type(e) is tuple and e[0] == 0: + self.do_br(e[1]) + elif type(e) is int: + self.do_block(align=e) + elif hasattr(e,'align'): + self.do_align(e) + else: + self.do_item(e) + self.line() + self.rect.h = max(self.y,self.left_bottom,self.right_bottom) + + def init(self): + self.x,self.y = self.rect.x,self.rect.y + self.left = self.rect.left + self.right = self.rect.right + self.left_bottom = 0 + self.right_bottom = 0 + self.y = self.rect.y + self.x = self.rect.x + self.h = 0 + + self.items = [] + self.align = -1 + + def getleft(self): + if self.y > self.left_bottom: + self.left = self.rect.left + return self.left + + def getright(self): + if self.y > self.right_bottom: + self.right = self.rect.right + return self.right + + def do_br(self,h): + self.line() + self.h = h + + def do_block(self,align=-1): + self.line() + self.align = align + + def do_align(self,e): + align = e.align + ox,oy,oh = self.x,self.y,self.h + w,h = e.rect.w,e.rect.h + + if align == 0: + self.line() + self.x = self.rect.left + (self.rect.width-w)/2 + self.fit = 0 + elif align == -1: + self.line() + self.y = max(self.left_bottom,self.y + self.h) + self.h = 0 + self.x = self.rect.left + elif align == 1: + self.line() + self.y = max(self.right_bottom,self.y + self.h) + self.h = 0 + self.x = self.rect.left + (self.rect.width-w) + + e.rect.x,e.rect.y = self.x,self.y + + self.x = self.x + w + self.y = self.y + + if align == 0: + self.h = max(self.h,h) + self.y = self.y + self.h + self.x = self.getleft() + self.h = 0 + elif align == -1: + self.left = self.x + self.left_bottom = self.y + h + self.x,self.y,self.h = ox + w,oy,oh + elif align == 1: + self.right = self.x - w + self.right_bottom = self.y + h + self.x,self.y,self.h = ox,oy,oh + + self.widgets.append(e) + + def do_space(self,e): + w,h = e + if self.x+w >= self.getright(): + self.line() + else: + self.items.append(e) + self.h = max(self.h,h) + self.x += w + + def do_item(self,e): + w,h = e.rect.w,e.rect.h + if self.x+w >= self.getright(): + self.line() + self.items.append(e) + self.h = max(self.h,h) + self.x += w + + def line(self): + x1 = self.getleft() + x2 = self.getright() + align = self.align + y = self.y + + if len(self.items) != 0 and type(self.items[-1]) == tuple: + del self.items[-1] + + w = 0 + for e in self.items: + if type(e) == tuple: w += e[0] + else: w += e.rect.w + + if align == -1: x = x1 + elif align == 0: + x = x1 + ((x2-x1)-w)/2 + self.fit = 0 + elif align == 1: x = x2 - w + + for e in self.items: + if type(e) == tuple: x += e[0] + else: + e.rect.x,e.rect.y = x,y + self.widgets.append(e) + x += e.rect.w + + self.items = [] + self.y = self.y + self.h + self.x = self.getleft() + self.h = 0 + + + +# vim: set filetype=python sts=4 sw=4 noet si : |