Пример #1
0
    def __init__(self, manager: Manager):
        self.manager = manager
        self.zero_point_dot = ZeroPointWidget(parent=self.manager.core, manager=self.manager)

        self.zero_point_dot.setGeometry(
            self.manager.core.width() // 2, self.manager.core.height() // 2, 1, 1)

        self.grid = Grid(
            show=True, core_size=(self.manager.core.width(), self.manager.core.height()),
            zero_pos=self.zero_point_dot)

        self.magnet_lines = []
Пример #2
0
    def __init__(self, application):
        BaseCanvas.__init__(self, application)
        self.origin = Origin()
        self.grid = Grid()
        self.guides = Guides()
        self.selection = Selection()

        #        self.gradients = []
        #        grad = Gradient(type=LINEAR, name="1", x=0, y=0, x1=0, y1=0)
        #        grad.clear()
        #        grad.add_new_color(GradientColor(1.0, 0.0, 0.0, 1.0, 0.142))
        #        grad.add_new_color(GradientColor(1.0, 1.0, 0.0, 1.0, 0.285))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 0.0, 1.0, 0.428))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 1.0, 1.0, 0.571))
        #        grad.add_new_color(GradientColor(0.0, 0.0, 1.0, 1.0, 0.714))
        #        grad.add_new_color(GradientColor(1.0, 0.0, 1.0, 1.0, 0.857))
        #        grad.update()
        #        self.gradients.append(grad)

        self.document = Document()
        #self.document.pages[0].children = list()
        #self.document.pages = list()

        page = Page()
        self.total = Size()

        self.document.pages.append(page)
        self.zoom = 1.0
        self.origin.x = 0 # XXX
        self.origin.y = 0 # XXX
        self.border = 25

        self.pick = False
        self.updated = False
        #self.get_child() = None
        self.child = None
        self.stop_cursor_change = False

        self.horizontal_ruler = None
        self.vertical_ruler = None
        self.clipboard = None

        self.hints = False

        self.motions = 0
Пример #3
0
class PlayScene(Scene):
    
    def __init__(self):
        super().__init__()
    
    def load(self):
        self.grid = Grid()
            
    def input(self):
        self.event = pygame.event.poll()
    
    def process(self):
        self.grid.update(self.event)
        if self.event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    def render(self):
        #self.buffer.fill((0,0,0))
        self.buffer.blit(self.grid.surface, (0,0))
Пример #4
0
    def __init__(self, application):
        BaseCanvas.__init__(self, application)
        self.origin = Origin()
        self.grid = Grid()
        self.guides = Guides()
        self.selection = Selection()

        #        self.gradients = []
        #        grad = Gradient(type=LINEAR, name="1", x=0, y=0, x1=0, y1=0)
        #        grad.clear()
        #        grad.add_new_color(GradientColor(1.0, 0.0, 0.0, 1.0, 0.142))
        #        grad.add_new_color(GradientColor(1.0, 1.0, 0.0, 1.0, 0.285))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 0.0, 1.0, 0.428))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 1.0, 1.0, 0.571))
        #        grad.add_new_color(GradientColor(0.0, 0.0, 1.0, 1.0, 0.714))
        #        grad.add_new_color(GradientColor(1.0, 0.0, 1.0, 1.0, 0.857))
        #        grad.update()
        #        self.gradients.append(grad)

        self.document = Document()
        #self.document.pages[0].children = list()
        #self.document.pages = list()

        page = Page()
        self.total = Size()

        self.document.pages.append(page)
        self.zoom = 1.0
        self.origin.x = 0 # XXX
        self.origin.y = 0 # XXX
        self.border = 25

        self.pick = False
        self.updated = False
        self.child = None
        self.stop_cursor_change = False

        self.horizontal_ruler = None
        self.vertical_ruler = None
        self.clipboard = None

        self.hints = False

        self.motions = 0
Пример #5
0
class CanvasImplementation(BaseCanvas):
    """This class represents a high level canvas implementation"""

    #    def initialize(self):
    #        BaseCanvas.initialize(self)
    def __init__(self, application):
        BaseCanvas.__init__(self, application)
        self.origin = Origin()
        self.grid = Grid()
        self.guides = Guides()
        self.selection = Selection()

        #        self.gradients = []
        #        grad = Gradient(type=LINEAR, name="1", x=0, y=0, x1=0, y1=0)
        #        grad.clear()
        #        grad.add_new_color(GradientColor(1.0, 0.0, 0.0, 1.0, 0.142))
        #        grad.add_new_color(GradientColor(1.0, 1.0, 0.0, 1.0, 0.285))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 0.0, 1.0, 0.428))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 1.0, 1.0, 0.571))
        #        grad.add_new_color(GradientColor(0.0, 0.0, 1.0, 1.0, 0.714))
        #        grad.add_new_color(GradientColor(1.0, 0.0, 1.0, 1.0, 0.857))
        #        grad.update()
        #        self.gradients.append(grad)

        self.document = Document()
        #self.document.pages[0].children = list()
        #self.document.pages = list()

        page = Page()
        self.total = Size()

        self.document.pages.append(page)
        self.zoom = 1.0
        self.origin.x = 0 # XXX
        self.origin.y = 0 # XXX
        self.border = 25

        self.pick = False
        self.updated = False
        #self.get_child() = None
        self.child = None
        self.stop_cursor_change = False

        self.horizontal_ruler = None
        self.vertical_ruler = None
        self.clipboard = None

        self.hints = False

        self.motions = 0

    def release(self, widget, event):
        """
        This code is executed when you release the mouse button
        """
        if self.selection.active:
            self.unselect_all()
            for child in self.document.pages[0].children:
                if child.in_selection(self.selection):
                    child.selected = True
                    self.emit("select", child)
                    #elif child.resizing:
                    #    child.resizing ^= 1
            self.selection.active = False
        else:
            for child in self.document.pages[0].children:
                if child.selected:
                    self.emit("finalize", child)
                if child.resizing:
                    child.resizing ^= 1
                    child.direction = NONE
                    child.handler.pivot.active = False
                    self.emit("finalize", child)

        self.pick = False
        #widget.bin_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))
        widget.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))

        self.updated = False
        self.update()
        self.stop_cursor_change = False
        return True

    def motion(self, widget, event):
        """
        This code is executed when move the mouse pointer
        """
        self.statics.motion += 1
        #self.consume(Gdk.MOTION_NOTIFY, event.get_state())
        self.disconnect(self.motion_id)
        if self.horizontal_ruler:
            self.horizontal_ruler.motion(self.horizontal_ruler, event, True)
        if self.vertical_ruler:
            self.vertical_ruler.motion(self.vertical_ruler, event, True)
        x = event.x / self.zoom
        y = event.y / self.zoom

        if not self.stop_cursor_change:
            def get_direction_for_child_at_position(x, y, children):
                for child in children:
                    if child.selected and child.handler.at_position(x, y):
                        direction = child.handler.get_direction(x, y)
                        #widget.bin_window.set_cursor(child.get_cursor(direction))
                        widget.get_window().set_cursor(child.get_cursor(direction))
                        return direction
                return NONE

            direction = get_direction_for_child_at_position(x, y, self.document.pages[0].children)

            if direction == NONE:
                if self.pick:
                    #widget.bin_window.set_cursor(Gdk.Cursor.new(Gdk.PENCIL))
                    widget.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.PENCIL))
                else:
                    #widget.bin_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))
                    widget.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))

        if self.selection.active:
            self.selection.width = x - self.selection.x
            self.selection.height = y - self.selection.y
            self.updated = False
            self.update() # XXX
        elif event.get_state() & Gdk.ModifierType.BUTTON1_MASK:
            for child in self.document.pages[0].children: # TODO
                if child.selected:
                    target = Point()
                    if child.resizing:
                        target.x = self.grid.nearest(x)
                        target.y = self.grid.nearest(y)
                        target = self.guides.nearest(target)
                        if child.direction < ANONIMOUS:
                            child.resize(target.x, target.y)
                        else:
                            child.transform(target.x, target.y)
                    else:
                        #widget.bin_window.set_cursor(Gdk.Cursor.new(Gdk.FLEUR))
                        widget.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.FLEUR))
                        target.x = self.grid.nearest(x - child.offset.x)
                        target.y = self.grid.nearest(y - child.offset.y)
                        target = self.guides.nearest(target)
                        # XXX-TEST
                        if self.is_testing:
                            def magnetize(target, children):
                                for child in children:
                                    if not child.selected and child.magnetos.is_magnetized(target):
                                        return child.magnetos.get_magnetized(target)
                                return target

                            target = magnetize(target, self.document.pages[0].children)
                        # XXX-TEST
                        child.move(target.x, target.y)
                    self.emit("edit-child", child)
                    self.update()
        self.motion_id = self.connect("motion-notify-event", self.motion)
        return True

    def press(self, widget, event):
        """
        This code is executed when you press the mouse button
        """
        self.emit("focus", Gtk.DirectionType.TAB_FORWARD)

        x = event.x / self.zoom
        y = event.y / self.zoom

        def start_resize(child):
            self.unselect_all()
            child.selected = True
            child.resizing = True
            if child.direction < ANONIMOUS:
                control = child.handler.control[opposite(child.direction)]
                child.pivot.x = self.grid.nearest(control.x)
                child.pivot.y = self.grid.nearest(control.y)
                child.pivot = self.guides.nearest(child.pivot)
                child.handler.pivot.x = control.x
                child.handler.pivot.y = control.y
                child.handler.pivot.active = True

        if self.pick:
            self.unselect_all()
            #x, y = self.get_pointer()
            target = Point()
            #child = self.get_child()
            child = self.child
            self.add(child)
            child.selected = True
            target.x = self.grid.nearest(x)
            target.y = self.grid.nearest(y)
            target = self.guides.nearest(target)
            child.x = target.x
            child.y = target.y
            child.width = 0
            child.height = 0
            child.direction = SOUTHEAST
            child.handler.control[opposite(child.direction)].y = child.y
            child.handler.control[opposite(child.direction)].x = child.x
            start_resize(child)
            #widget.bin_window.set_cursor(Gdk.Cursor.new(Gdk.BOTTOM_RIGHT_CORNER))
            widget.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.BOTTOM_RIGHT_CORNER))
            self.emit("select", child)
            return True

        selection = True

        def start_move(child, x, y):
            child.offset.x = x - child.x
            child.offset.y = y - child.y
            child.press(x, y)

        def select(child):
            if not event.get_state() & Gdk.ModifierType.CONTROL_MASK:
                self.unselect_all()
            child.selected = True

        for child in sorted(self.document.pages[0].children, key=lambda child: child.z):
            if child.selected:
                if child.handler.at_position(x, y):
                    child.direction = child.handler.get_direction(x, y)
                    selection = False
                    start_resize(child)
                elif child.at_position(x, y):
                    #start_move(child, x, y)
                    start_move(child, x, y)
                    selection = False
                else:
                    continue
            elif child.at_position(x, y):
                selection = False
                select(child)
                start_move(child, x, y)
            else:
                continue

        if selection:
            self.selection.x = x
            self.selection.y = y
            self.selection.width = 0
            self.selection.height = 0
            self.selection.active = True
            #widget.bin_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.CROSSHAIR))
            widget.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.CROSSHAIR))
        else:
            self.stop_cursor_change = True
            #self.updated = False
        self.update() # XXX

        return True

    def expose(self, widget, context):
        self.statics.expose += 1
        self.disconnect(self.expose_id)
        #context = widget.bin_window.cairo_create()
        #context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
        #context.clip()
        context.scale(self.zoom, self.zoom)
        self.total.width = int(self.document.pages[0].width * self.zoom + 2 * self.border)
        self.total.height = int(
            len(self.document.pages) * self.document.pages[0].height * self.zoom +
            (len(self.document.pages) + 1) * self.border)
        self.set_size_request(self.total.width, self.total.height)
        context.set_source_rgb(0.55, 0.55, 0.55) #background
        context.paint()

        page = self.document.pages[0]

        self.document.draw(context, self.border, self.zoom, self.hints)

        self.origin.x = page.x + page.left # + self.border
        self.origin.y = page.y + page.top # + self.border

        if self.grid.active:
            self.grid.x = self.origin.x
            self.grid.y = self.origin.y
            self.grid.width = page.width - page.left - page.right
            self.grid.height = page.height - page.top - page.bottom
            self.grid.draw(context)

        if self.guides.active:
            self.guides.x = self.origin.x
            self.guides.y = self.origin.y
            self.guides.width = page.width - page.left - page.right
            self.guides.height = page.height - page.top - page.bottom
            self.guides.draw(context)

        if self.selection.active:
            self.selection.draw(context)
        self.updated = True
        self.expose_id = self.connect("draw", self.expose)
        return True

    add = lambda self, child: self.document.pages[0].children.append(child)

    #update = lambda self: self.queue_draw()
    def update(self):
        if not self.updated:
            pass
        self.queue_draw()
Пример #6
0
 def load(self):
     self.grid = Grid()
Пример #7
0
class GridManager:
    def __init__(self, manager: Manager):
        self.manager = manager
        self.zero_point_dot = ZeroPointWidget(parent=self.manager.core, manager=self.manager)

        self.zero_point_dot.setGeometry(
            self.manager.core.width() // 2, self.manager.core.height() // 2, 1, 1)

        self.grid = Grid(
            show=True, core_size=(self.manager.core.width(), self.manager.core.height()),
            zero_pos=self.zero_point_dot)

        self.magnet_lines = []

    # TODO doc for this
    def check_and_set_grid_magnet_lines_for_resizing(
            self, obj: TextWidget,
            x: int,
            y: int,
            x_mod: bool = False,
            y_mod: bool = False,
            widgets: dict = None
    ) -> (int, int, dict):
        """
        I don't know what it does
        :param obj:
        :param x:
        :param y:
        :param x_mod:
        :param y_mod:
        :param widgets:
        :return:
        """
        if widgets is None:
            widgets = {}
        x_left = self.grid.get_nearest_y_line_by_offset(obj.x())
        x_center = self.grid.get_nearest_y_line_by_offset(obj.x() + obj.width() // 2)
        x_right = self.grid.get_nearest_y_line_by_offset(obj.x() + obj.width())
        y_left = self.grid.get_nearest_x_line_by_offset(obj.y())

        y_center = self.grid.get_nearest_x_line_by_offset(
            obj.y() + obj.height() // 2)

        y_right = self.grid.get_nearest_x_line_by_offset(obj.y() + obj.height())
        self.grid.clear_special_lines()
        if x_left or x_center or x_right:

            x_t = (x_left.x1() if x_left else False) or \
                  (x_center.x1() - obj.width() // 2 if x_center else False) or \
                  (x_right.x1() - obj.width() if x_right else False)

            x = x_t or x
            if y_mod:
                for widget in widgets:
                    v = widgets[widget]
                    if v[0] and v[0] != x:
                        widgets[widget] = (None, v[1])

            if x_left and x == x_left.x1():
                self.grid.add_line_to_special_lines(x_left)
            if x_center and x + obj.width() // 2 == x_center.x1():
                self.grid.add_line_to_special_lines(x_center)
            if x_right and x + obj.width() == x_right.x1():
                self.grid.add_line_to_special_lines(x_right)
        if y_left or y_center or y_right:

            y_t = (y_left.y1() if y_left else False) or (
                y_center.y1() - obj.height() // 2 if y_center else False) or \
                  (y_right.y1() - obj.height() if y_right else False)

            y = y_t or y
            if x_mod:
                for widget in widgets:
                    v = widgets[widget]
                    if v[1] and v[1] != y:
                        widgets[widget] = (v[0], 0)

            if y_left and y == y_left.y1():
                self.grid.add_line_to_special_lines(y_left)
            if y_center and y + obj.height() // 2 == y_center.y1():
                self.grid.add_line_to_special_lines(y_center)
            if y_right and y + obj.height() == y_right.y1():
                self.grid.add_line_to_special_lines(y_right)

        return x, y, widgets

    def get_magnet_lines(self) -> list:
        """
        :return: all magnet lines
        """
        return self.magnet_lines

    def drop_magnet_lines(self):
        """
        drops all magnet lines
        """
        self.magnet_lines.clear()

    def set_new_zero_point_pos(self, x: int, y: int):
        """
        sets new zero point's position to (x, y)
        """
        self.zero_point_dot.set_zero(x, y)
Пример #8
0
class CanvasImplementation(BaseCanvas):
    """This class represents a high level canvas implementation"""

    #    def initialize(self):
    #        BaseCanvas.initialize(self)
    def __init__(self, application):
        BaseCanvas.__init__(self, application)
        self.origin = Origin()
        self.grid = Grid()
        self.guides = Guides()
        self.selection = Selection()

        #        self.gradients = []
        #        grad = Gradient(type=LINEAR, name="1", x=0, y=0, x1=0, y1=0)
        #        grad.clear()
        #        grad.add_new_color(GradientColor(1.0, 0.0, 0.0, 1.0, 0.142))
        #        grad.add_new_color(GradientColor(1.0, 1.0, 0.0, 1.0, 0.285))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 0.0, 1.0, 0.428))
        #        grad.add_new_color(GradientColor(0.0, 1.0, 1.0, 1.0, 0.571))
        #        grad.add_new_color(GradientColor(0.0, 0.0, 1.0, 1.0, 0.714))
        #        grad.add_new_color(GradientColor(1.0, 0.0, 1.0, 1.0, 0.857))
        #        grad.update()
        #        self.gradients.append(grad)

        self.document = Document()
        #self.document.pages[0].children = list()
        #self.document.pages = list()

        page = Page()
        self.total = Size()

        self.document.pages.append(page)
        self.zoom = 1.0
        self.origin.x = 0 # XXX
        self.origin.y = 0 # XXX
        self.border = 25

        self.pick = False
        self.updated = False
        self.child = None
        self.stop_cursor_change = False

        self.horizontal_ruler = None
        self.vertical_ruler = None
        self.clipboard = None

        self.hints = False

        self.motions = 0

    def release(self, widget, event):
        """
        This code is executed when you release the mouse button
        """
        if self.selection.active:
            self.unselect_all()
            for child in self.document.pages[0].children:
                if child.in_selection(self.selection):
                    child.selected = True
                    self.emit("select", child)
                    #elif child.resizing:
                    #    child.resizing ^= 1
            self.selection.active = False
        else:
            for child in self.document.pages[0].children:
                if child.selected:
                    self.emit("finalize", child)
                if child.resizing:
                    child.resizing ^= 1
                    child.direction = NONE
                    child.handler.pivot.active = False
                    self.emit("finalize", child)

        self.pick = False
        widget.bin_window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))

        self.updated = False
        self.update()
        self.stop_cursor_change = False
        return True

    def motion(self, widget, event):
        """
        This code is executed when move the mouse pointer
        """
        self.statics.motion += 1
        #self.consume(gtk.gdk.MOTION_NOTIFY, event.state)
        self.disconnect(self.motion_id)
        if self.horizontal_ruler:
            self.horizontal_ruler.motion(self.horizontal_ruler, event, True)
        if self.vertical_ruler:
            self.vertical_ruler.motion(self.vertical_ruler, event, True)
        x = event.x / self.zoom
        y = event.y / self.zoom

        if not self.stop_cursor_change:
            def get_direction_for_child_at_position(x, y, children):
                for child in children:
                    if child.selected and child.handler.at_position(x, y):
                        direction = child.handler.get_direction(x, y)
                        widget.bin_window.set_cursor(child.get_cursor(direction))
                        return direction
                return NONE

            direction = get_direction_for_child_at_position(x, y, self.document.pages[0].children)

            if direction == NONE:
                if self.pick:
                    widget.bin_window.set_cursor(gtk.gdk.Cursor(gtk.gdk.PENCIL))
                else:
                    widget.bin_window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))

        if self.selection.active:
            self.selection.width = x - self.selection.x
            self.selection.height = y - self.selection.y
            self.updated = False
            self.update() # XXX
        elif event.state & gtk.gdk.BUTTON1_MASK:
            for child in self.document.pages[0].children: # TODO
                if child.selected:
                    target = Point()
                    if child.resizing:
                        target.x = self.grid.nearest(x)
                        target.y = self.grid.nearest(y)
                        target = self.guides.nearest(target)
                        if child.direction < ANONIMOUS:
                            child.resize(target.x, target.y)
                        else:
                            child.transform(target.x, target.y)
                    else:
                        widget.bin_window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
                        target.x = self.grid.nearest(x - child.offset.x)
                        target.y = self.grid.nearest(y - child.offset.y)
                        target = self.guides.nearest(target)
                        # XXX-TEST
                        if self.is_testing:
                            def magnetize(target, children):
                                for child in children:
                                    if not child.selected and child.magnetos.is_magnetized(target):
                                        return child.magnetos.get_magnetized(target)
                                return target

                            target = magnetize(target, self.document.pages[0].children)
                        # XXX-TEST
                        child.move(target.x, target.y)
                    self.emit("edit-child", child)
                    self.update()
        self.motion_id = self.connect("motion-notify-event", self.motion)
        return True

    def press(self, widget, event):
        """
        This code is executed when you press the mouse button
        """
        self.emit("focus", gtk.DIR_TAB_FORWARD)

        x = event.x / self.zoom
        y = event.y / self.zoom

        def start_resize(child):
            self.unselect_all()
            child.selected = True
            child.resizing = True
            if child.direction < ANONIMOUS:
                control = child.handler.control[opposite(child.direction)]
                child.pivot.x = self.grid.nearest(control.x)
                child.pivot.y = self.grid.nearest(control.y)
                child.pivot = self.guides.nearest(child.pivot)
                child.handler.pivot.x = control.x
                child.handler.pivot.y = control.y
                child.handler.pivot.active = True

        if self.pick:
            self.unselect_all()
            #x, y = self.get_pointer()
            target = Point()
            child = self.child
            self.add(child)
            child.selected = True
            target.x = self.grid.nearest(x)
            target.y = self.grid.nearest(y)
            target = self.guides.nearest(target)
            child.x = target.x
            child.y = target.y
            child.width = 0
            child.height = 0
            child.direction = SOUTHEAST
            child.handler.control[opposite(child.direction)].y = child.y
            child.handler.control[opposite(child.direction)].x = child.x
            start_resize(child)
            widget.bin_window.set_cursor(gtk.gdk.Cursor(gtk.gdk.BOTTOM_RIGHT_CORNER))
            self.emit("select", child)
            return True

        selection = True

        def start_move(child, x, y):
            child.offset.x = x - child.x
            child.offset.y = y - child.y
            child.press(x, y)

        def select(child):
            if not event.state & gtk.gdk.CONTROL_MASK:
                self.unselect_all()
            child.selected = True

        for child in sorted(self.document.pages[0].children, key=lambda child: child.z):
            if child.selected:
                if child.handler.at_position(x, y):
                    child.direction = child.handler.get_direction(x, y)
                    selection = False
                    start_resize(child)
                elif child.at_position(x, y):
                    #start_move(child, x, y)
                    start_move(child, x, y)
                    selection = False
                else:
                    continue
            elif child.at_position(x, y):
                selection = False
                select(child)
                start_move(child, x, y)
            else:
                continue

        if selection:
            self.selection.x = x
            self.selection.y = y
            self.selection.width = 0
            self.selection.height = 0
            self.selection.active = True
            widget.bin_window.set_cursor(gtk.gdk.Cursor(gtk.gdk.CROSSHAIR))
        else:
            self.stop_cursor_change = True
            #self.updated = False
        self.update() # XXX

        return True

    def expose(self, widget, event):
        self.statics.expose += 1
        self.disconnect(self.expose_id)
        context = widget.bin_window.cairo_create()
        context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
        context.clip()
        context.scale(self.zoom, self.zoom)
        self.total.width = int(self.document.pages[0].width * self.zoom + 2 * self.border)
        self.total.height = int(
            len(self.document.pages) * self.document.pages[0].height * self.zoom +
            (len(self.document.pages) + 1) * self.border)
        self.set_size_request(self.total.width, self.total.height)
        context.set_source_rgb(0.55, 0.55, 0.55) #background
        context.paint()

        page = self.document.pages[0]

        self.document.draw(context, self.border, self.zoom, self.hints)

        self.origin.x = page.x + page.left # + self.border
        self.origin.y = page.y + page.top # + self.border

        if self.grid.active:
            self.grid.x = self.origin.x
            self.grid.y = self.origin.y
            self.grid.width = page.width - page.left - page.right
            self.grid.height = page.height - page.top - page.bottom
            self.grid.draw(context)

        if self.guides.active:
            self.guides.x = self.origin.x
            self.guides.y = self.origin.y
            self.guides.width = page.width - page.left - page.right
            self.guides.height = page.height - page.top - page.bottom
            self.guides.draw(context)

        if self.selection.active:
            self.selection.draw(context)
        self.updated = True
        self.expose_id = self.connect("expose-event", self.expose)
        return True

    add = lambda self, child: self.document.pages[0].children.append(child)

    #update = lambda self: self.queue_draw()
    def update(self):
        if not self.updated:
            pass
        self.queue_draw()