Esempio n. 1
0
class SpreadLayout(gobject.GObject, hippo.CanvasLayout):
    __gtype_name__ = 'SugarSpreadLayout'

    def __init__(self):
        gobject.GObject.__init__(self)
        self._box = None

        min_width, width = self.do_get_width_request()
        min_height, height = self.do_get_height_request(width)

        self._grid = Grid(int(width / _CELL_SIZE), int(height / _CELL_SIZE))
        self._grid.connect('child-changed', self._grid_child_changed_cb)

    def add(self, child):
        self._box.append(child)

        width, height = self._get_child_grid_size(child)
        self._grid.add(child, width, height)

    def remove(self, child):
        self._grid.remove(child)
        self._box.remove(child)

    def move(self, child, x, y):
        self._grid.move(child, x / _CELL_SIZE, y / _CELL_SIZE, locked=True)

    def do_set_box(self, box):
        self._box = box

    def do_get_height_request(self, for_width):
        return 0, gtk.gdk.screen_height() - style.GRID_CELL_SIZE

    def do_get_width_request(self):
        return 0, gtk.gdk.screen_width()

    def do_allocate(self, x, y, width, height,
                    req_width, req_height, origin_changed):
        for child in self._box.get_layout_children():
            # We need to always get  requests to not confuse hippo
            min_w, child_width = child.get_width_request()
            min_h, child_height = child.get_height_request(child_width)

            rect = self._grid.get_child_rect(child.item)
            child.allocate(int(round(rect.x * _CELL_SIZE)),
                           int(round(rect.y * _CELL_SIZE)),
                           child_width,
                           child_height,
                           origin_changed)

    def _get_child_grid_size(self, child):
        min_width, width = child.get_width_request()
        min_height, height = child.get_height_request(width)
        width = math.ceil(width / _CELL_SIZE)
        height = math.ceil(height / _CELL_SIZE)

        return int(width), int(height)

    def _grid_child_changed_cb(self, grid, child):
        child.emit_request_changed()
Esempio n. 2
0
class ViewLayout(Layout):
    def __init__(self):
        self._grid = None
        self._width = 0
        self._height = 0

    def setup(self, allocation, owner_icon, activity_icon=None):
        if self._grid is not None:
            if self._width == allocation.width and \
                    self._height == allocation.height:
                return
        self._width = allocation.width
        self._height = allocation.height
        self._grid = Grid(int(allocation.width / _CELL_SIZE),
                          int(allocation.height / _CELL_SIZE))
        self._grid.connect('child-changed', self.__grid_child_changed_cb)
        self._allocate_owner_icon(allocation, owner_icon, activity_icon)

    def _allocate_owner_icon(self, allocation, owner_icon, activity_icon):
        # add owner icon to the grid, precisely centered on the screen
        # if not None, add an activity icon directly below the owner icon
        owner_request = owner_icon.size_request()
        owner_width, owner_height = owner_request.width, owner_request.height
        height = allocation.height + allocation.y
        width = allocation.width

        # Find vertical center point of screen
        y = height / 2

        # This container may be offset from the top by a certain amount
        # (e.g. for a toolbar at the top of the screen). Adjust the
        # center-point for that
        y -= allocation.y

        # Now subtract half of the owner height. This gives us the y
        # coordinate for the top of the owner icon.
        y -= owner_height / 2

        # calculate x coordinate and create allocation
        owner_icon_allocation = Gdk.Rectangle()
        owner_icon_allocation.x = (width - owner_width) / 2
        owner_icon_allocation.y = allocation.y + y
        owner_icon_allocation.width = owner_width
        owner_icon_allocation.height = owner_height
        owner_icon.size_allocate(owner_icon_allocation)

        # Determine grid coordinates and add to grid
        owner_grid_width, owner_grid_height = \
            self._get_child_grid_size(owner_icon)
        grid_x = int(owner_icon_allocation.x / float(_CELL_SIZE))
        grid_y = int(owner_icon_allocation.y / float(_CELL_SIZE))
        self._grid.add(owner_icon, owner_grid_width, owner_grid_height,
                       grid_x, grid_y, locked=True)

        if activity_icon is None:
            return

        # Position the current activity below the XO icon
        # FIXME must ensure we cross into next grid cell here..
        activity_request = activity_icon.size_request()
        activity_icon_allocation = Gdk.Rectangle()
        activity_icon_allocation.x = (width - activity_request.width) / 2
        activity_icon_allocation.y = owner_icon_allocation.y + owner_height
        activity_icon_allocation.width = activity_request.width
        activity_icon_allocation.height = activity_request.height
        activity_icon.size_allocate(activity_icon_allocation)

        # Determine grid coordinates and add to grid
        activity_grid_width, activity_grid_height = \
            self._get_child_grid_size(activity_icon)
        x = int(activity_icon_allocation.x / float(_CELL_SIZE))
        y = int(activity_icon_allocation.y / float(_CELL_SIZE))
        self._grid.add(activity_icon, activity_grid_width,
                       activity_grid_height, x, y, locked=True)

    def allocate_children(self, allocation, children):
        pass

    def move_icon(self, child, x, y, allocation):
        pass

    def move(self, child, x, y, allocation=None):
        self._grid.move(child, x / _CELL_SIZE, y / _CELL_SIZE, locked=True)
        child_request = child.size_request()
        rect = self._grid.get_child_rect(child)

        child_allocation = Gdk.Rectangle()
        child_allocation.x = int(round(rect.x * _CELL_SIZE))
        child_allocation.y = int(round(rect.y * _CELL_SIZE))
        child_allocation.width = child_request.width
        child_allocation.height = child_request.height
        child.size_allocate(child_allocation)

    def _get_child_grid_size(self, child):
        request = child.size_request()
        width = math.ceil(request.width / _CELL_SIZE)
        height = math.ceil(request.height / _CELL_SIZE)
        return int(width), int(height)

    def __grid_child_changed_cb(self, grid, child):
        request = child.size_request()
        rect = self._grid.get_child_rect(child)
        child_allocation = Gdk.Rectangle()
        child_allocation.x = int(round(rect.x * _CELL_SIZE))
        child_allocation.y = int(round(rect.y * _CELL_SIZE))
        child_allocation.width = request.width
        child_allocation.height = request.height
        child.size_allocate(child_allocation)
Esempio n. 3
0
class RandomActivityLayout(ActivityLayout):
    """Lay out icons randomly; try to nudge them around to resolve overlaps."""

    __gtype_name__ = 'RandomActivityLayout'

    icon_name = 'view-freeform'
    """Name of icon used in home view dropdown palette."""

    key = 'random-layout'
    """String used in profile to represent this view."""

    # TRANS: label for the freeform layout in the pathway view
    palette_name = _('Freeform')
    """String used to identify this layout in home view dropdown palette."""
    def __init__(self):
        ActivityLayout.__init__(self)

        min_width_, width = self.do_get_width_request()
        min_height_, height = self.do_get_height_request(width)

        self._grid = Grid(width / _CELL_SIZE, height / _CELL_SIZE)
        self._grid.connect('child-changed', self.__grid_child_changed_cb)

    def __grid_child_changed_cb(self, grid, child):
        child.emit_request_changed()

    def append(self, icon, locked=False):
        ActivityLayout.append(self, icon, locked)

        min_width_, child_width = icon.get_width_request()
        min_height_, child_height = icon.get_height_request(child_width)
        min_width_, width = self.box.get_width_request()
        min_height_, height = self.box.get_height_request(width)

        if icon in self.fixed_positions:
            x, y = self.fixed_positions[icon]
            x = min(x, width - child_width)
            y = min(y, height - child_height)
        elif hasattr(icon, 'get_bundle_id'):
            name_hash = hashlib.md5(icon.get_bundle_id())
            x = int(name_hash.hexdigest()[:5], 16) % (width - child_width)
            y = int(name_hash.hexdigest()[-5:], 16) % (height - child_height)
        else:
            x = None
            y = None

        if x is None or y is None:
            self._grid.add(icon, child_width / _CELL_SIZE,
                           child_height / _CELL_SIZE)
        else:
            self._grid.add(icon, child_width / _CELL_SIZE,
                           child_height / _CELL_SIZE, x / _CELL_SIZE,
                           y / _CELL_SIZE)

    def remove(self, icon):
        self._grid.remove(icon)
        ActivityLayout.remove(self, icon)

    def move_icon(self, icon, x, y, locked=False):
        self._grid.move(icon, x / _CELL_SIZE, y / _CELL_SIZE, locked)
        ActivityLayout.move_icon(self, icon, x, y, locked)

    def do_allocate(self, x, y, width, height, req_width, req_height,
                    origin_changed):
        for child in self.box.get_layout_children():
            # We need to always get requests to not confuse hippo
            min_w_, child_width = child.get_width_request()
            min_h_, child_height = child.get_height_request(child_width)

            rect = self._grid.get_child_rect(child.item)
            child.allocate(rect.x * _CELL_SIZE, rect.y * _CELL_SIZE,
                           child_width, child_height, origin_changed)

    def allow_dnd(self):
        return True
Esempio n. 4
0
class ViewLayout(Layout):
    def __init__(self):
        self._grid = None
        self._width = 0
        self._height = 0

    def setup(self, allocation, owner_icon, activity_icon=None):
        if self._grid is not None:
            if self._width == allocation.width and \
                    self._height == allocation.height:
                return
        self._width = allocation.width
        self._height = allocation.height
        self._grid = Grid(int(allocation.width / _CELL_SIZE),
                          int(allocation.height / _CELL_SIZE))
        self._grid.connect('child-changed', self.__grid_child_changed_cb)
        self._allocate_owner_icon(allocation, owner_icon, activity_icon)

    def _allocate_owner_icon(self, allocation, owner_icon, activity_icon):
        # add owner icon to the grid, precisely centered on the screen
        # if not None, add an activity icon directly below the owner icon
        owner_request = owner_icon.size_request()
        owner_width, owner_height = owner_request.width, owner_request.height
        height = allocation.height + allocation.y
        width = allocation.width

        # Find vertical center point of screen
        y = height / 2

        # This container may be offset from the top by a certain amount
        # (e.g. for a toolbar at the top of the screen). Adjust the
        # center-point for that
        y -= allocation.y

        # Now subtract half of the owner height. This gives us the y
        # coordinate for the top of the owner icon.
        y -= owner_height / 2

        # calculate x coordinate and create allocation
        owner_icon_allocation = Gdk.Rectangle()
        owner_icon_allocation.x = (width - owner_width) / 2
        owner_icon_allocation.y = allocation.y + y
        owner_icon_allocation.width = owner_width
        owner_icon_allocation.height = owner_height
        owner_icon.size_allocate(owner_icon_allocation)

        # Determine grid coordinates and add to grid
        owner_grid_width, owner_grid_height = \
            self._get_child_grid_size(owner_icon)
        grid_x = int(owner_icon_allocation.x / float(_CELL_SIZE))
        grid_y = int(owner_icon_allocation.y / float(_CELL_SIZE))
        self._grid.add(owner_icon,
                       owner_grid_width,
                       owner_grid_height,
                       grid_x,
                       grid_y,
                       locked=True)

        if activity_icon is None:
            return

        # Position the current activity below the XO icon
        # FIXME must ensure we cross into next grid cell here..
        activity_request = activity_icon.size_request()
        activity_icon_allocation = Gdk.Rectangle()
        activity_icon_allocation.x = (width - activity_request.width) / 2
        activity_icon_allocation.y = owner_icon_allocation.y + owner_height
        activity_icon_allocation.width = activity_request.width
        activity_icon_allocation.height = activity_request.height
        activity_icon.size_allocate(activity_icon_allocation)

        # Determine grid coordinates and add to grid
        activity_grid_width, activity_grid_height = \
            self._get_child_grid_size(activity_icon)
        x = int(activity_icon_allocation.x / float(_CELL_SIZE))
        y = int(activity_icon_allocation.y / float(_CELL_SIZE))
        self._grid.add(activity_icon,
                       activity_grid_width,
                       activity_grid_height,
                       x,
                       y,
                       locked=True)

    def allocate_children(self, allocation, children):
        pass

    def move_icon(self, child, x, y, allocation):
        pass

    def move(self, child, x, y, allocation=None):
        self._grid.move(child, x / _CELL_SIZE, y / _CELL_SIZE, locked=True)
        child_request = child.size_request()
        rect = self._grid.get_child_rect(child)

        child_allocation = Gdk.Rectangle()
        child_allocation.x = int(round(rect.x * _CELL_SIZE))
        child_allocation.y = int(round(rect.y * _CELL_SIZE))
        child_allocation.width = child_request.width
        child_allocation.height = child_request.height
        child.size_allocate(child_allocation)

    def _get_child_grid_size(self, child):
        request = child.size_request()
        width = math.ceil(request.width / _CELL_SIZE)
        height = math.ceil(request.height / _CELL_SIZE)
        return int(width), int(height)

    def __grid_child_changed_cb(self, grid, child):
        request = child.size_request()
        rect = self._grid.get_child_rect(child)
        child_allocation = Gdk.Rectangle()
        child_allocation.x = int(round(rect.x * _CELL_SIZE))
        child_allocation.y = int(round(rect.y * _CELL_SIZE))
        child_allocation.width = request.width
        child_allocation.height = request.height
        child.size_allocate(child_allocation)
class RandomLayout(FavoritesLayout):
    """Lay out icons randomly; try to nudge them around to resolve overlaps."""

    __gtype_name__ = 'RandomLayout'

    icon_name = 'view-freeform'
    """Name of icon used in home view dropdown palette."""

    key = 'random-layout'
    """String used in profile to represent this view."""

    # TRANS: label for the freeform layout in the favorites view
    palette_name = _('Freeform')
    """String used to identify this layout in home view dropdown palette."""

    def __init__(self):
        FavoritesLayout.__init__(self)

        min_width_, width = self.do_get_width_request()
        min_height_, height = self.do_get_height_request(width)

        self._grid = Grid(width / _CELL_SIZE, height / _CELL_SIZE)
        self._grid.connect('child-changed', self.__grid_child_changed_cb)

    def __grid_child_changed_cb(self, grid, child):
        child.emit_request_changed()

    def append(self, icon, locked=False):
        FavoritesLayout.append(self, icon, locked)

        min_width_, child_width = icon.get_width_request()
        min_height_, child_height = icon.get_height_request(child_width)
        min_width_, width = self.box.get_width_request()
        min_height_, height = self.box.get_height_request(width)

        if icon in self.fixed_positions:
            x, y = self.fixed_positions[icon]
            x = min(x, width - child_width)
            y = min(y, height - child_height)
        elif hasattr(icon, 'get_bundle_id'):
            name_hash = hashlib.md5(icon.get_bundle_id())
            x = int(name_hash.hexdigest()[:5], 16) % (width - child_width)
            y = int(name_hash.hexdigest()[-5:], 16) % (height - child_height)
        else:
            x = None
            y = None

        if x is None or y is None:
            self._grid.add(icon,
                           child_width / _CELL_SIZE, child_height / _CELL_SIZE)
        else:
            self._grid.add(icon,
                           child_width / _CELL_SIZE, child_height / _CELL_SIZE,
                           x / _CELL_SIZE, y / _CELL_SIZE)

    def remove(self, icon):
        self._grid.remove(icon)
        FavoritesLayout.remove(self, icon)

    def move_icon(self, icon, x, y, locked=False):
        self._grid.move(icon, x / _CELL_SIZE, y / _CELL_SIZE, locked)
        FavoritesLayout.move_icon(self, icon, x, y, locked)

    def do_allocate(self, x, y, width, height, req_width, req_height,
                    origin_changed):
        for child in self.box.get_layout_children():
            # We need to always get requests to not confuse hippo
            min_w_, child_width = child.get_width_request()
            min_h_, child_height = child.get_height_request(child_width)

            rect = self._grid.get_child_rect(child.item)
            child.allocate(rect.x * _CELL_SIZE,
                           rect.y * _CELL_SIZE,
                           child_width,
                           child_height,
                           origin_changed)

    def allow_dnd(self):
        return True