diff options
-rw-r--r-- | lvc/widgets/cellpack.py | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/lvc/widgets/cellpack.py b/lvc/widgets/cellpack.py index 1347f56..4f4f8bf 100644 --- a/lvc/widgets/cellpack.py +++ b/lvc/widgets/cellpack.py @@ -7,10 +7,11 @@ state around inside the cell renderers, so we just set up the objects at the start, then use them to calculate info. """ + class Margin(object): """Helper object used to calculate margins. """ - def __init__(self , margin): + def __init__(self, margin): if margin is None: margin = (0, 0, 0, 0) self.margin_left = margin[3] @@ -38,7 +39,8 @@ class Margin(object): margins. """ return ((0 <= x - self.margin_left < width - self.margin_width) and - (0 <= y - self.margin_top < height - self.margin_height)) + (0 <= y - self.margin_top < height - self.margin_height)) + class Packing(object): """Helper object used to layout Boxes. @@ -53,6 +55,7 @@ class Packing(object): def draw(self, context, x, y, width, height): self.child.draw(context, x, y, width, height) + class WhitespacePacking(object): """Helper object used to layout Boxes. """ @@ -66,6 +69,7 @@ class WhitespacePacking(object): def draw(self, context, x, y, width, height): pass + class Packer(object): """Base class packing objects. Packer objects work similarly to widgets, but they only used in custom cell renderers so there's a couple @@ -121,9 +125,9 @@ class Packer(object): child, child_x, child_y, child_width, child_height = child_pos try: return child.find_hotspot(x - child_x, y - child_y, - child_width, child_height) + child_width, child_height) except AttributeError: - pass # child is a TextBox, Button or something like that + pass # child is a TextBox, Button or something like that return None def _layout(self, context, x, y, width, height): @@ -137,6 +141,7 @@ class Packer(object): """ raise NotImplementedError() + class Box(Packer): """Box is the base class for VBox and HBox. Box objects lay out children linearly either left to right or top to bottom. @@ -199,7 +204,7 @@ class Box(Packer): def _calc_size(self): length = 0 - breadth = 0 + breadth = 0 for packing in self.children + self.children_end: child_length, child_breadth = packing.calc_size(self._translate) length += child_length @@ -213,15 +218,15 @@ class Box(Packer): if total_extra_space <= 0: while True: yield 0 - average_extra_space, leftover = \ - divmod(total_extra_space, self.expand_count) + (average_extra_space, leftover) = divmod(total_extra_space, + self.expand_count) while leftover > 1: # expand_count doesn't divide equally into total_extra_space, # yield average_extra_space+1 for each extra pixel yield average_extra_space + 1 leftover -= 1 # if there's a fraction of a pixel leftover, add that in - yield average_extra_space + leftover + yield average_extra_space + leftover while True: # no more leftover space yield average_extra_space @@ -277,14 +282,17 @@ class Box(Packer): """ raise NotImplementedError() + class HBox(Box): def _translate(self, x, y): return x, y + class VBox(Box): def _translate(self, x, y): return y, x + class Table(Packer): def __init__(self, row_length=1, col_length=1, row_spacing=0, col_spacing=0): @@ -316,7 +324,7 @@ class Table(Packer): # possibly throw a special exception if outside the range. # For now, just allowing an IndexError to be thrown. self.table_multiarray[row][column] = Packing(child, expand) - + def _get_grid_sizes(self): """Get the width and eights for both rows and columns """ @@ -342,8 +350,8 @@ class Table(Packer): for col_count, packing in enumerate(row): child_width, child_height = packing.calc_size(self._translate) if packing.child: - if (col_distance <= x < col_distance + child_width - and row_distance <= y < row_distance + child_height): + if (col_distance <= x < col_distance + child_width and + row_distance <= y < row_distance + child_height): return (packing.child, col_distance, row_distance, child_width, child_height) @@ -382,7 +390,7 @@ class Alignment(Packer): """Positions a child inside a larger space. """ def __init__(self, child, xscale=1.0, yscale=1.0, xalign=0.0, yalign=0.0, - min_width=0, min_height=0): + min_width=0, min_height=0): self.child = child self.xscale = xscale self.yscale = yscale @@ -407,7 +415,7 @@ class Alignment(Packer): child_x, child_y, child_width, child_height = \ self._calc_child_position(width, height) self.child.draw(context, x + child_x, y + child_y, child_width, - child_height) + child_height) def _find_child_at(self, x, y, width, height): child_x, child_y, child_width, child_height = \ @@ -416,7 +424,8 @@ class Alignment(Packer): (child_y <= y < child_y + child_height)): return self.child, child_x, child_y, child_width, child_height else: - return None # (x, y) is in the empty space around child + return None # (x, y) is in the empty space around child + class DrawingArea(Packer): """Area that uses custom drawing code. @@ -436,6 +445,7 @@ class DrawingArea(Packer): def _find_child_at(self, x, y, width, height): return None + class Background(Packer): """Draws a background behind a child element. """ @@ -466,6 +476,7 @@ class Background(Packer): return None return (self.child,) + self.margin.inner_rect(0, 0, width, height) + class Padding(Packer): """Adds padding to the edges of a packer. """ @@ -484,6 +495,7 @@ class Padding(Packer): return None return (self.child,) + self.margin.inner_rect(0, 0, width, height) + class TextBoxPacker(Packer): """Base class for ClippedTextLine and ClippedTextBox. """ @@ -491,9 +503,10 @@ class TextBoxPacker(Packer): self.textbox.draw(context, x, y, width, height) def _find_child_at(self, x, y, width, height): - # We could return the TextBox here, but we know it doesn't have a + # We could return the TextBox here, but we know it doesn't have a # find_hotspot() method - return None + return None + class ClippedTextBox(TextBoxPacker): """A TextBox that gets clipped if it's larger than it's allocated @@ -508,6 +521,7 @@ class ClippedTextBox(TextBoxPacker): height = max(self.min_height, self.textbox.font.line_height()) return self.min_width, height + class ClippedTextLine(TextBoxPacker): """A single line of text that gets clipped if it's larger than the space allocated to it. By default the clipping will happen at character @@ -521,11 +535,13 @@ class ClippedTextLine(TextBoxPacker): def _calc_size(self): return self.min_width, self.textbox.font.line_height() + class TruncatedTextLine(ClippedTextLine): def __init__(self, textbox, min_width=0): ClippedTextLine.__init__(self, textbox, min_width) self.textbox.set_wrap_style('truncated-char') + class Hotspot(Packer): """A Hotspot handles mouse click tracking. It's only purpose is to store a name to return from ``find_hotspot()``. In terms of @@ -544,6 +560,7 @@ class Hotspot(Packer): def find_hotspot(self, x, y, width, height): return self.name, x, y, width, height + class Stack(Packer): """Packer that stacks other packers on top of each other. """ @@ -580,34 +597,42 @@ class Stack(Packer): else: return top._find_child_at(x, y, width, height) + def align_left(packer): """Align a packer to the left side of it's allocated space.""" return Alignment(packer, xalign=0.0, xscale=0.0) + def align_right(packer): """Align a packer to the right side of it's allocated space.""" return Alignment(packer, xalign=1.0, xscale=0.0) + def align_top(packer): """Align a packer to the top side of it's allocated space.""" return Alignment(packer, yalign=0.0, yscale=0.0) + def align_bottom(packer): """Align a packer to the bottom side of it's allocated space.""" return Alignment(packer, yalign=1.0, yscale=0.0) + def align_middle(packer): """Align a packer to the middle of it's allocated space.""" return Alignment(packer, yalign=0.5, yscale=0.0) + def align_center(packer): """Align a packer to the center of it's allocated space.""" return Alignment(packer, xalign=0.5, xscale=0.0) + def pad(packer, top=0, left=0, bottom=0, right=0): """Add padding to a packer.""" return Padding(packer, top, right, bottom, left) + class LayoutRect(object): """Lightweight object use to track rectangles inside a layout @@ -625,7 +650,7 @@ class LayoutRect(object): def __str__(self): return "LayoutRect(%s, %s, %s, %s)" % (self.x, self.y, self.width, - self.height) + self.height) def __eq__(self, other): my_values = (self.x, self.y, self.width, self.height) @@ -638,7 +663,8 @@ class LayoutRect(object): def subsection(self, left, right, top, bottom): """Create a new LayoutRect from inside this one.""" return LayoutRect(self.x + left, self.y + top, - self.width - left - right, self.height - top - bottom) + self.width - left - right, + self.height - top - bottom) def right_side(self, width): """Create a new LayoutRect from the right side of this one.""" @@ -673,21 +699,24 @@ class LayoutRect(object): return LayoutRect(self.x, self.bottom, self.width, height) def is_point_inside(self, x, y): - return (self.x <= x < self.x + self.width - and self.y <= y < self.y + self.height) + return (self.x <= x < self.x + self.width and + self.y <= y < self.y + self.height) def get_right(self): return self.x + self.width + def set_right(self, right): self.width = right - self.x right = property(get_right, set_right) def get_bottom(self): return self.y + self.height + def set_bottom(self, bottom): self.height = bottom - self.y bottom = property(get_bottom, set_bottom) + class Layout(object): """Store the layout for a cell @@ -720,7 +749,7 @@ class Layout(object): :returns: LayoutRect of the added element """ return self.add_rect(LayoutRect(x, y, width, height), - drawing_function, hotspot) + drawing_function, hotspot) def add_rect(self, layout_rect, drawing_function=None, hotspot=None): """Add a new element to this Layout using a LayoutRect @@ -744,7 +773,7 @@ class Layout(object): hotspot) """ return self.add(x, y, width, textbox.font.line_height(), textbox.draw, - hotspot) + hotspot) def add_image(self, image, x, y, hotspot=None): """Add an ImageSurface to the layout @@ -840,4 +869,4 @@ class Layout(object): for rect, drawing_function, hotspot in self._rects: if drawing_function is not None: drawing_function(context, rect.x, rect.y, rect.width, - rect.height) + rect.height) |