Switch to the new layout manager for the mesh view

This commit is contained in:
Marco Pesenti Gritti 2007-07-05 21:22:37 +02:00
parent c5ab58ed6c
commit 61b8811a42
4 changed files with 37 additions and 204 deletions

View File

@ -20,7 +20,7 @@ import hippo
import gobject import gobject
from gettext import gettext as _ from gettext import gettext as _
from sugar.graphics.spreadbox import SpreadBox from sugar.graphics.spreadlayout import SpreadLayout
from sugar.graphics.canvasicon import CanvasIcon from sugar.graphics.canvasicon import CanvasIcon
from sugar.graphics import color from sugar.graphics import color
from sugar.graphics import xocolor from sugar.graphics import xocolor
@ -202,9 +202,9 @@ class ActivityView(hippo.CanvasBox):
bundle_id = self._model.get_service_name() bundle_id = self._model.get_service_name()
self._shell.join_activity(bundle_id, self._model.get_id()) self._shell.join_activity(bundle_id, self._model.get_id())
class MeshBox(SpreadBox): class MeshBox(hippo.CanvasBox):
def __init__(self, shell): def __init__(self, shell):
SpreadBox.__init__(self, background_color=0xe2e2e2ff) hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff)
self._shell = shell self._shell = shell
self._model = shell.get_model().get_mesh() self._model = shell.get_model().get_mesh()
@ -215,6 +215,9 @@ class MeshBox(SpreadBox):
self._buddy_to_activity = {} self._buddy_to_activity = {}
self._suspended = True self._suspended = True
self.layout = SpreadLayout()
self.set_layout(self.layout)
for buddy_model in self._model.get_buddies(): for buddy_model in self._model.get_buddies():
self._add_alone_buddy(buddy_model) self._add_alone_buddy(buddy_model)
@ -277,26 +280,26 @@ class MeshBox(SpreadBox):
if not mesh: if not mesh:
return return
self._mesh = MeshDeviceView(mesh) self._mesh = MeshDeviceView(mesh)
self.add_item(self._mesh) self.layout.add(self._mesh)
def _remove_mesh(self): def _remove_mesh(self):
if not self._mesh: if not self._mesh:
return return
self.remove_item(self._mesh) self.layout.remove(self._mesh)
self._mesh = None self._mesh = None
def _add_alone_buddy(self, buddy_model): def _add_alone_buddy(self, buddy_model):
icon = BuddyIcon(self._shell, buddy_model) icon = BuddyIcon(self._shell, buddy_model)
if buddy_model.is_owner(): if buddy_model.is_owner():
self.set_center_item(icon) self.layout.add_center(icon)
else: else:
self.add_item(icon) self.layout.add(icon)
self._buddies[buddy_model.get_key()] = icon self._buddies[buddy_model.get_key()] = icon
def _remove_alone_buddy(self, buddy_model): def _remove_alone_buddy(self, buddy_model):
icon = self._buddies[buddy_model.get_key()] icon = self._buddies[buddy_model.get_key()]
self.remove_item(icon) self.layout.remove(icon)
del self._buddies[buddy_model.get_key()] del self._buddies[buddy_model.get_key()]
def _remove_buddy(self, buddy_model): def _remove_buddy(self, buddy_model):
@ -323,24 +326,24 @@ class MeshBox(SpreadBox):
def _add_activity(self, activity_model): def _add_activity(self, activity_model):
icon = ActivityView(self._shell, activity_model) icon = ActivityView(self._shell, activity_model)
self.add_item(icon) self.layout.add(icon)
self._activities[activity_model.get_id()] = icon self._activities[activity_model.get_id()] = icon
def _remove_activity(self, activity_model): def _remove_activity(self, activity_model):
icon = self._activities[activity_model.get_id()] icon = self._activities[activity_model.get_id()]
self.remove_item(icon) self.layout.remove(icon)
del self._activities[activity_model.get_id()] del self._activities[activity_model.get_id()]
def _add_access_point(self, ap_model): def _add_access_point(self, ap_model):
icon = AccessPointView(ap_model) icon = AccessPointView(ap_model)
self.add_item(icon) self.layout.add(icon)
self._access_points[ap_model.get_id()] = icon self._access_points[ap_model.get_id()] = icon
def _remove_access_point(self, ap_model): def _remove_access_point(self, ap_model):
icon = self._access_points[ap_model.get_id()] icon = self._access_points[ap_model.get_id()]
self.remove_item(icon) self.layout.remove(icon)
del self._access_points[ap_model.get_id()] del self._access_points[ap_model.get_id()]
def suspend(self): def suspend(self):

View File

@ -16,7 +16,7 @@ sugar_PYTHON = \
roundbox.py \ roundbox.py \
palette.py \ palette.py \
panel.py \ panel.py \
spreadbox.py \ spreadlayout.py \
toggletoolbutton.py \ toggletoolbutton.py \
toolbox.py \ toolbox.py \
toolbutton.py \ toolbutton.py \

View File

@ -1,190 +0,0 @@
# Copyright (C) 2006-2007 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
from array import array
from random import random
import gobject
import hippo
_X_TILES = 120
_NUM_TRIALS = 20
_MAX_WEIGHT = 255
class _Grid(object):
def __init__(self, x_tiles, y_tiles, cell_size):
self._array = array('B')
self.x_tiles = x_tiles
self.y_tiles = y_tiles
self.cell_size = cell_size
for i in range(self.y_tiles * self.x_tiles):
self._array.append(0)
def __getitem__(self, (row, col)):
return self._array[col + row * self.x_tiles]
def __setitem__(self, (row, col), value):
self._array[col + row * self.x_tiles] = value
def compute_weight_at(self, x, y, width, height):
weight = 0
for i in range(x, x + width):
for j in range(y, y + height):
weight += self[j, i]
return weight
def add_weight_at(self, x, y, width, height):
for i in range(x, x + width):
for j in range(y, y + height):
self[j, i] += 1
def remove_weight_at(self, x, y, width, height):
for i in range(x, x + width):
for j in range(y, y + height):
self[j, i] -= 1
def from_canvas(self, dim):
return dim / self.cell_size
def to_canvas(self, dim):
return dim * self.cell_size
class _ItemInfo(gobject.GObject):
def __init__(self):
gobject.GObject.__init__(self)
self.x = -1
self.y = -1
self.width = -1
self.height = -1
def add_weight(self, grid):
grid.add_weight_at(self.x, self.y, self.width, self.height)
def remove_weight(self, grid):
grid.remove_weight_at(self.x, self.y, self.width, self.height)
def compute_weight(self, grid, x=-1, y=-1):
if x < 0:
x = self.x
if y < 0:
y = self.y
grid.compute_weight_at(x, y, self.width, self.height)
class SpreadBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarSpreadBox'
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
self._grid = None
self._center = None
self._width = -1
self._height = -1
def set_center_item(self, item):
if self._center:
self.remove(self._center)
self.append(item, hippo.PACK_FIXED)
self._center = item
self._layout_center()
def add_item(self, item):
item.set_data('item-info', _ItemInfo())
self.append(item, hippo.PACK_FIXED)
self._layout_item(item)
def remove_item(self, item):
if self._grid:
info = item.get_data('item-info')
info.remove_weight(self._grid)
self.remove(item)
def _place_item(self, item, x, y):
info = item.get_data('item-info')
info.x = x
info.y = y
info.add_weight(self._grid)
self.set_position(item, self._grid.to_canvas(x),
self._grid.to_canvas(y))
def _layout_item(self, item):
if not self._grid:
return
info = item.get_data('item-info')
[width, height] = item.get_allocation()
info.width = self._grid.from_canvas(width)
info.height = self._grid.from_canvas(height)
trials = _NUM_TRIALS
placed = False
best_weight = _MAX_WEIGHT
while trials > 0 and not placed:
x = int(random() * (self._grid.x_tiles - info.width))
y = int(random() * (self._grid.y_tiles - info.height))
weight = info.compute_weight(self._grid, x, y)
if weight == 0:
self._place_item(item, x, y)
placed = True
elif weight < best_weight:
best_x = x
best_y = y
trials -= 1
if not placed:
self._place_item(item, best_x, best_y)
def _layout(self):
for item in self.get_children():
if item != self._center:
self._layout_item(item)
def _layout_center(self):
if not self._center or not self._grid:
return
[width, height] = self._center.get_allocation()
x = (self._width - width) / 2
y = (self._height - height) / 2
self.set_position(self._center, x, y)
def do_allocate(self, width, height, origin_changed):
hippo.CanvasBox.do_allocate(self, width, height, origin_changed)
if width != self._width or height != self._height:
cell_size = width / _X_TILES
y_tiles = height / cell_size
self._grid = _Grid(_X_TILES, y_tiles, cell_size)
self._width = width
self._height = height
self._layout()
self._layout_center()

View File

@ -35,6 +35,14 @@ class _Grid(object):
for i in range(width * height): for i in range(width * height):
self._array.append(0) self._array.append(0)
def add_locked(self, child, x, y, width, height):
rect = gtk.gdk.Rectangle(x, y, width, height)
child.locked = True
child.grid_rect = rect
self._add_weight(rect)
def add(self, child, width, height): def add(self, child, width, height):
trials = _PLACE_TRIALS trials = _PLACE_TRIALS
weight = _MAX_WEIGHT weight = _MAX_WEIGHT
@ -50,10 +58,12 @@ class _Grid(object):
trials -= 1 trials -= 1
child.grid_rect = rect child.grid_rect = rect
child.locked = False
self._add_weight(rect) self._add_weight(rect)
def remove(self, child): def remove(self, child):
self._remove_weight(box_child.grid_rect) self._remove_weight(child.grid_rect)
child.grid_rect = None child.grid_rect = None
def _add_weight(self, rect): def _add_weight(self, rect):
@ -92,6 +102,16 @@ class SpreadLayout(gobject.GObject,hippo.CanvasLayout):
self._grid = _Grid(width / _CELL_SIZE, height / _CELL_SIZE) self._grid = _Grid(width / _CELL_SIZE, height / _CELL_SIZE)
def add_center(self, child):
self._box.append(child)
width, height = self._get_child_grid_size(child)
box_child = self._box.find_box_child(child)
self._grid.add_locked(box_child,
int((self._grid.width - width) / 2),
int((self._grid.height - height) / 2),
width, height)
def add(self, child): def add(self, child):
self._box.append(child) self._box.append(child)