+++ /dev/null
-"""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 :