Merge branch 'master' of git://dev.laptop.org/sugar

This commit is contained in:
Ian Bicking 2006-10-02 10:35:28 -05:00
commit 9a4cc50ee8
19 changed files with 602 additions and 172 deletions

View File

@ -66,6 +66,7 @@ sugar/activity/Makefile
sugar/canvas/Makefile sugar/canvas/Makefile
sugar/chat/Makefile sugar/chat/Makefile
sugar/chat/sketchpad/Makefile sugar/chat/sketchpad/Makefile
sugar/graphics/Makefile
sugar/p2p/Makefile sugar/p2p/Makefile
sugar/p2p/model/Makefile sugar/p2p/model/Makefile
sugar/presence/Makefile sugar/presence/Makefile

View File

@ -4,11 +4,12 @@ import logging
import pygtk import pygtk
pygtk.require('2.0') pygtk.require('2.0')
import gobject
import gtk import gtk
import dbus.glib import dbus.glib
# Work around for dbus mutex locking issue # Work around for dbus mutex locking issue
gtk.gdk.threads_init() gobject.threads_init()
dbus.glib.threads_init() dbus.glib.threads_init()
from sugar.activity import ActivityFactory from sugar.activity import ActivityFactory

View File

@ -1,26 +1,25 @@
import gtk import hippo
import goocanvas
import logging import logging
import conf import conf
from sugar.canvas.IconItem import IconItem from sugar.graphics.canvasicon import CanvasIcon
from sugar.canvas.IconColor import IconColor
from sugar.presence import PresenceService from sugar.presence import PresenceService
from sugar.canvas.CanvasBox import CanvasBox from sugar.graphics import style
class ActivityItem(IconItem): class ActivityItem(CanvasIcon):
def __init__(self, activity): def __init__(self, activity):
icon_name = activity.get_icon() icon_name = activity.get_icon()
IconItem.__init__(self, icon_name=icon_name, color=IconColor('white')) CanvasIcon.__init__(self, icon_name=icon_name)
style.apply_stylesheet(self, 'frame-activity-icon')
self._activity = activity self._activity = activity
def get_bundle_id(self): def get_bundle_id(self):
return self._activity.get_id() return self._activity.get_id()
class InviteItem(IconItem): class InviteItem(CanvasIcon):
def __init__(self, invite): def __init__(self, invite):
IconItem.__init__(self, icon_name=invite.get_icon(), CanvasIcon.__init__(self, icon_name=invite.get_icon(),
color=invite.get_color()) color=invite.get_color())
self._invite = invite self._invite = invite
def get_activity_id(self): def get_activity_id(self):
@ -32,9 +31,9 @@ class InviteItem(IconItem):
def get_invite(self): def get_invite(self):
return self._invite return self._invite
class BottomPanel(CanvasBox): class ActivitiesBox(hippo.CanvasBox):
def __init__(self, shell): def __init__(self, shell):
CanvasBox.__init__(self, shell.get_grid(), CanvasBox.HORIZONTAL) hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL)
self._shell = shell self._shell = shell
self._invite_to_item = {} self._invite_to_item = {}
@ -47,37 +46,35 @@ class BottomPanel(CanvasBox):
for invite in self._invites: for invite in self._invites:
self.add_invite(invite) self.add_invite(invite)
self._invites.connect('invite-added', self.__invite_added_cb) self._invites.connect('invite-added', self._invite_added_cb)
self._invites.connect('invite-removed', self.__invite_removed_cb) self._invites.connect('invite-removed', self._invite_removed_cb)
def __activity_clicked_cb(self, icon): def _activity_clicked_cb(self, icon):
self._shell.start_activity(icon.get_bundle_id()) self._shell.start_activity(icon.get_bundle_id())
def __invite_clicked_cb(self, icon): def _invite_clicked_cb(self, icon):
self._invites.remove_invite(icon.get_invite()) self._invites.remove_invite(icon.get_invite())
self._shell.join_activity(icon.get_bundle_id(), self._shell.join_activity(icon.get_bundle_id(),
icon.get_activity_id()) icon.get_activity_id())
def __invite_added_cb(self, invites, invite): def _invite_added_cb(self, invites, invite):
self.add_invite(invite) self.add_invite(invite)
def __invite_removed_cb(self, invites, invite): def _invite_removed_cb(self, invites, invite):
self.remove_invite(invite) self.remove_invite(invite)
def add_activity(self, activity): def add_activity(self, activity):
item = ActivityItem(activity) item = ActivityItem(activity)
item.connect('clicked', self.__activity_clicked_cb) item.connect('activated', self._activity_clicked_cb)
self.set_constraints(item, 5, 5) self.append(item, 0)
self.add_child(item)
def add_invite(self, invite): def add_invite(self, invite):
item = InviteItem(invite) item = InviteItem(invite)
item.connect('clicked', self.__invite_clicked_cb) item.connect('activated', self._invite_clicked_cb)
self.set_constraints(item, 5, 5) self.append(item, 0)
self.add_child(item, 0)
self._invite_to_item[invite] = item self._invite_to_item[invite] = item
def remove_invite(self, invite): def remove_invite(self, invite):
self.remove_child(self._invite_to_item[invite]) self.remove(self._invite_to_item[invite])
del self._invite_to_item[invite] del self._invite_to_item[invite]

View File

@ -1,15 +1,14 @@
import gtk import gtk
import gobject import gobject
import goocanvas import hippo
import wnck import wnck
from view.frame.BottomPanel import BottomPanel from view.frame.ActivitiesBox import ActivitiesBox
from view.frame.RightPanel import RightPanel from view.frame.ZoomBox import ZoomBox
from view.frame.TopPanel import TopPanel
from view.frame.PanelWindow import PanelWindow from view.frame.PanelWindow import PanelWindow
from sugar.canvas.Grid import Grid
from sugar.canvas.Timeline import Timeline from sugar.canvas.Timeline import Timeline
from sugar.canvas.MenuShell import MenuShell from sugar.canvas.MenuShell import MenuShell
from sugar.graphics.grid import Grid
class EventFrame(gobject.GObject): class EventFrame(gobject.GObject):
__gsignals__ = { __gsignals__ = {
@ -116,51 +115,52 @@ class Frame:
self._timeline.add_tag('before_slide_out', 36, 36) self._timeline.add_tag('before_slide_out', 36, 36)
self._timeline.add_tag('slide_out', 37, 42) self._timeline.add_tag('slide_out', 37, 42)
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
grid = shell.get_grid()
self._menu_shell = MenuShell(grid)
self._menu_shell.connect('activated', self._menu_shell_activated_cb)
self._menu_shell.connect('deactivated', self._menu_shell_deactivated_cb)
bg = goocanvas.Rect(fill_color="#4f4f4f", line_width=0)
grid.set_constraints(bg, 0, 0, 80, 60)
root.add_child(bg)
panel = BottomPanel(shell)
grid.set_constraints(panel, 5, 55)
root.add_child(panel)
self._add_panel(model, 0, 55, 80, 5)
panel = TopPanel(shell, self._menu_shell)
root.add_child(panel)
self._add_panel(model, 0, 0, 80, 5)
panel = RightPanel(shell, self._menu_shell)
grid.set_constraints(panel, 75, 5)
root.add_child(panel)
self._add_panel(model, 75, 5, 5, 50)
self._add_panel(model, 0, 5, 5, 50)
self._event_frame = EventFrame() self._event_frame = EventFrame()
self._event_frame.connect('enter-edge', self._enter_edge_cb) self._event_frame.connect('enter-edge', self._enter_edge_cb)
self._event_frame.connect('enter-corner', self._enter_corner_cb) self._event_frame.connect('enter-corner', self._enter_corner_cb)
self._event_frame.connect('leave', self._event_frame_leave_cb) self._event_frame.connect('leave', self._event_frame_leave_cb)
self._event_frame.show() self._event_frame.show()
def _add_panel(self, model, x, y, width, height): grid = Grid()
grid = self._shell.get_grid()
panel_window = PanelWindow(grid, model, x, y, width, height) self._menu_shell = MenuShell(grid)
panel_window.connect('enter-notify-event', self._enter_notify_cb) self._menu_shell.connect('activated', self._menu_shell_activated_cb)
panel_window.connect('leave-notify-event', self._leave_notify_cb) self._menu_shell.connect('deactivated', self._menu_shell_deactivated_cb)
self._windows.append(panel_window) top_panel = self._create_panel(grid, 0, 0, 16, 1)
box = ZoomBox(self._shell, self._menu_shell)
top_panel.append(box, hippo.PACK_FIXED)
[x, y] = grid.point(1, 0)
top_panel.move(box, x, y)
bottom_panel = self._create_panel(grid, 0, 11, 16, 1)
box = ActivitiesBox(self._shell)
bottom_panel.append(box, hippo.PACK_FIXED)
[x, y] = grid.point(1, 0)
bottom_panel.move(box, x, y)
left_panel = self._create_panel(grid, 0, 1, 1, 10)
right_panel = self._create_panel(grid, 15, 1, 1, 10)
def _create_panel(self, grid, x, y, width, height):
panel = PanelWindow()
panel.connect('enter-notify-event', self._enter_notify_cb)
panel.connect('leave-notify-event', self._leave_notify_cb)
[x, y, width, height] = grid.rectangle(x, y, width, height)
panel.move(x, y)
panel.resize(width, height)
self._windows.append(panel)
return panel.get_root()
def _menu_shell_activated_cb(self, menu_shell): def _menu_shell_activated_cb(self, menu_shell):
self._timeline.goto('slide_in', True) self._timeline.goto('slide_in', True)

View File

@ -1,28 +1,15 @@
from sugar.graphics.grid import Grid
class MenuStrategy: class MenuStrategy:
def get_menu_position(self, menu, grid_x1, grid_y1, grid_x2, grid_y2): def get_menu_position(self, menu, x, y, width, height):
grid = menu.get_grid() grid = Grid()
[x1, y1] = grid.micro_to_macro(grid_x1, grid_y1) [grid_x1, grid_y1] = grid.fit_point(x, y)
[x2, y2] = grid.micro_to_macro(grid_x2, grid_y2) [grid_x2, grid_y2] = grid.fit_point(x + width, y + height)
if x1 == 0: menu_grid_x = grid_x1
x = x2 menu_grid_y = grid_y2
y = y1
elif x2 == grid.get_macro_cols():
x = x1
y = y1
elif y2 == grid.get_macro_rows():
x = x1
y = y1
else:
x = x1
y = y2
[grid_x, grid_y] = grid.macro_to_micro(x, y) [menu_x, menu_y] = grid.point(menu_grid_x, menu_grid_y)
if x2 == grid.get_macro_cols(): return [menu_x, menu_y]
grid_x -= menu.get_width()
elif y2 == grid.get_macro_rows():
grid_y -= menu.get_height()
return [grid_x, grid_y]

View File

@ -1,27 +1,24 @@
import gtk import gtk
import goocanvas import hippo
from sugar.canvas.CanvasView import CanvasView
class PanelWindow(gtk.Window): class PanelWindow(gtk.Window):
def __init__(self, grid, model, x, y, width, height): def __init__(self):
gtk.Window.__init__(self) gtk.Window.__init__(self)
self._grid = grid
self.set_decorated(False) self.set_decorated(False)
self.connect('realize', self._realize_cb)
self.realize() canvas = hippo.Canvas()
self._bg = hippo.CanvasBox(background_color=0x4f4f4fff)
canvas.set_root(self._bg)
self.add(canvas)
canvas.show()
def get_root(self):
return self._bg
def _realize_cb(self, widget):
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
self.window.set_accept_focus(False) self.window.set_accept_focus(False)
screen = gtk.gdk.screen_get_default()
self.window.set_transient_for(screen.get_root_window())
view = CanvasView()
view.show()
self.add(view)
view.set_model(model)
self._grid.set_constraints(self, x, y, width, height)
self._grid.set_constraints(view, x, y, width, height)

View File

@ -1,16 +1,15 @@
import goocanvas import hippo
from sugar.canvas.IconItem import IconItem from sugar.graphics.CanvasIcon import CanvasIcon
from sugar.canvas.IconColor import IconColor from sugar.canvas.IconColor import IconColor
from sugar.canvas.CanvasBox import CanvasBox
from sugar.presence import PresenceService from sugar.presence import PresenceService
from view.BuddyIcon import BuddyIcon from view.BuddyIcon import BuddyIcon
from model.BuddyModel import BuddyModel from model.BuddyModel import BuddyModel
from view.frame.MenuStrategy import MenuStrategy from view.frame.MenuStrategy import MenuStrategy
class RightPanel(CanvasBox): class RightPanel(hippo.CanvasBox):
def __init__(self, shell, menu_shell): def __init__(self, shell, menu_shell):
CanvasBox.__init__(self, shell.get_grid(), CanvasBox.VERTICAL) CanvasBox.__init__(self)
self._shell = shell self._shell = shell
self._menu_shell = menu_shell self._menu_shell = menu_shell
self._activity_ps = None self._activity_ps = None
@ -28,8 +27,7 @@ class RightPanel(CanvasBox):
model = BuddyModel(buddy=buddy) model = BuddyModel(buddy=buddy)
icon = BuddyIcon(self._shell, self._menu_shell, model) icon = BuddyIcon(self._shell, self._menu_shell, model)
icon.set_menu_strategy(MenuStrategy()) icon.set_menu_strategy(MenuStrategy())
self.set_constraints(icon, 5, 5) self.append(icon, 0)
self.add_child(icon)
self._buddies[buddy.get_name()] = icon self._buddies[buddy.get_name()] = icon

View File

@ -1,9 +1,10 @@
import goocanvas import goocanvas
import hippo
from sugar.canvas.CanvasBox import CanvasBox from sugar.graphics.canvasicon import CanvasIcon
from sugar.canvas.IconItem import IconItem from sugar.graphics.menuicon import MenuIcon
from sugar.canvas.MenuIcon import MenuIcon from sugar.graphics.menu import Menu
from sugar.canvas.Menu import Menu from sugar.graphics import style
from view.frame.MenuStrategy import MenuStrategy from view.frame.MenuStrategy import MenuStrategy
import sugar import sugar
@ -12,13 +13,14 @@ class ActivityMenu(Menu):
ACTION_CLOSE = 2 ACTION_CLOSE = 2
def __init__(self, grid, activity_host): def __init__(self, grid, activity_host):
title = activity_host.get_title() Menu.__init__(self, activity_host.get_title())
Menu.__init__(self, grid, title)
icon = IconItem(icon_name='stock-share-mesh') icon = CanvasIcon(icon_name='stock-share-mesh')
style.apply_stylesheet(icon, 'menu-action-icon')
self.add_action(icon, ActivityMenu.ACTION_SHARE) self.add_action(icon, ActivityMenu.ACTION_SHARE)
icon = IconItem(icon_name='stock-close') icon = CanvasIcon(icon_name='stock-close')
style.apply_stylesheet(icon, 'menu-action-icon')
self.add_action(icon, ActivityMenu.ACTION_CLOSE) self.add_action(icon, ActivityMenu.ACTION_CLOSE)
class ActivityIcon(MenuIcon): class ActivityIcon(MenuIcon):
@ -51,53 +53,45 @@ class ActivityIcon(MenuIcon):
if action == ActivityMenu.ACTION_CLOSE: if action == ActivityMenu.ACTION_CLOSE:
activity.close() activity.close()
class TopPanel(goocanvas.Group): class ZoomBox(hippo.CanvasBox):
def __init__(self, shell, menu_shell): def __init__(self, shell, menu_shell):
goocanvas.Group.__init__(self) hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL)
self._shell = shell self._shell = shell
self._menu_shell = menu_shell self._menu_shell = menu_shell
self._activity_icon = None self._activity_icon = None
grid = shell.get_grid() icon = CanvasIcon(icon_name='stock-zoom-mesh')
style.apply_stylesheet(icon, 'frame-zoom-icon')
icon.connect('activated', self._level_clicked_cb, sugar.ZOOM_MESH)
self.append(icon)
box = CanvasBox(grid, CanvasBox.HORIZONTAL) icon = CanvasIcon(icon_name='stock-zoom-friends')
grid.set_constraints(box, 5, 0) style.apply_stylesheet(icon, 'frame-zoom-icon')
self.add_child(box) icon.connect('activated', self._level_clicked_cb, sugar.ZOOM_FRIENDS)
self.append(icon)
icon = IconItem(icon_name='stock-zoom-mesh') icon = CanvasIcon(icon_name='stock-zoom-home')
icon.connect('clicked', self._level_clicked_cb, sugar.ZOOM_MESH) style.apply_stylesheet(icon, 'frame-zoom-icon')
box.set_constraints(icon, 5, 5) icon.connect('activated', self._level_clicked_cb, sugar.ZOOM_HOME)
box.add_child(icon) self.append(icon)
icon = IconItem(icon_name='stock-zoom-friends') icon = CanvasIcon(icon_name='stock-zoom-activity')
icon.connect('clicked', self._level_clicked_cb, sugar.ZOOM_FRIENDS) style.apply_stylesheet(icon, 'frame-zoom-icon')
box.set_constraints(icon, 5, 5) icon.connect('activated', self._level_clicked_cb, sugar.ZOOM_ACTIVITY)
box.add_child(icon) self.append(icon)
icon = IconItem(icon_name='stock-zoom-home')
icon.connect('clicked', self._level_clicked_cb, sugar.ZOOM_HOME)
box.set_constraints(icon, 5, 5)
box.add_child(icon)
icon = IconItem(icon_name='stock-zoom-activity')
icon.connect('clicked', self._level_clicked_cb, sugar.ZOOM_ACTIVITY)
box.set_constraints(icon, 5, 5)
box.add_child(icon)
self._box = box
shell.connect('activity-changed', self._activity_changed_cb) shell.connect('activity-changed', self._activity_changed_cb)
self._set_current_activity(shell.get_current_activity()) self._set_current_activity(shell.get_current_activity())
def _set_current_activity(self, activity): def _set_current_activity(self, activity):
if self._activity_icon: if self._activity_icon:
self._box.remove_child(self._activity_icon) self.remove(self._activity_icon)
if activity: if activity:
icon = ActivityIcon(self._shell, self._menu_shell, activity) icon = ActivityIcon(self._shell, self._menu_shell, activity)
self._box.set_constraints(icon, 5, 5) style.apply_stylesheet(icon, 'frame-zoom-icon')
self._box.add_child(icon) self.append(icon, 0)
self._activity_icon = icon self._activity_icon = icon
else: else:
self._activity_icon = None self._activity_icon = None

View File

@ -1,4 +1,4 @@
SUBDIRS = activity canvas chat p2p presence session SUBDIRS = activity canvas chat graphics p2p presence session
sugardir = $(pythondir)/sugar sugardir = $(pythondir)/sugar
sugar_PYTHON = \ sugar_PYTHON = \

View File

@ -0,0 +1,5 @@
sugardir = $(pythondir)/sugar/graphics
sugar_PYTHON = \
__init__.py \
canvasicon.py \
grid.py

View File

@ -0,0 +1,25 @@
import gtk
from sugar.graphics import style
from sugar.canvas.IconColor import IconColor
if gtk.gdk.screen_width() == 1200:
_medium_icon_size = 75
else:
_medium_icon_size = 50
_stylesheet = {
'color' : IconColor('white'),
'size' : _medium_icon_size
}
style.register_stylesheet('frame-activity-icon', _stylesheet)
_stylesheet = {
'size' : _medium_icon_size
}
style.register_stylesheet('frame-zoom-icon', _stylesheet)
_stylesheet = {
'size' : _medium_icon_size
}
style.register_stylesheet('menu-action-icon', _stylesheet)

View File

@ -0,0 +1,139 @@
import re
import gobject
import gtk
import hippo
import rsvg
import cairo
from sugar.canvas.IconColor import IconColor
class _IconCache:
def __init__(self):
self._icons = {}
self._theme = gtk.icon_theme_get_default()
def _read_icon(self, filename, color):
icon_file = open(filename, 'r')
if color == None:
return rsvg.Handle(file=filename)
else:
data = icon_file.read()
icon_file.close()
fill = color.get_fill_color()
stroke = color.get_stroke_color()
entity = '<!ENTITY fill_color "%s">' % fill
data = re.sub('<!ENTITY fill_color .*>', entity, data)
entity = '<!ENTITY stroke_color "%s">' % stroke
data = re.sub('<!ENTITY stroke_color .*>', entity, data)
return rsvg.Handle(data=data)
def get_handle(self, name, color, size):
info = self._theme.lookup_icon(name, int(size), 0)
if color:
key = (info.get_filename(), color.to_string())
else:
key = info.get_filename()
if self._icons.has_key(key):
icon = self._icons[key]
else:
icon = self._read_icon(info.get_filename(), color)
self._icons[key] = icon
return icon
class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'CanvasIcon'
__gproperties__ = {
'icon-name': (str, None, None, None,
gobject.PARAM_READWRITE),
'color' : (object, None, None,
gobject.PARAM_READWRITE),
'size' : (int, None, None,
0, 1024, 24,
gobject.PARAM_READWRITE)
}
_cache = _IconCache()
def __init__(self, **kwargs):
self._size = 24
self._color = None
self._icon_name = None
hippo.CanvasBox.__init__(self, **kwargs)
self._buffer = None
self._buffer_size = 0.0
self.connect('button-press-event', self._button_press_event_cb)
def do_set_property(self, pspec, value):
if pspec.name == 'icon-name':
self._icon_name = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'color':
self._color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'size':
self._size = value
self.emit_request_changed()
def do_get_property(self, pspec):
if pspec.name == 'size':
return self._size
elif pspec.name == 'icon-name':
return self._icon_name
elif pspec.name == 'color':
return self._color
def _get_buffer(self, cr, handle, size):
if self._buffer and self._buffer_size != size:
del self._buffer
self._buffer = None
if self._buffer == None:
target = cr.get_target()
surface = target.create_similar(cairo.CONTENT_COLOR_ALPHA,
int(size) + 1, int(size) + 1)
dimensions = handle.get_dimension_data()
scale = float(size) / float(dimensions[0])
ctx = cairo.Context(surface)
ctx.scale(scale, scale)
handle.render_cairo(ctx)
del ctx
self._buffer = surface
self._buffer_scale = scale
return self._buffer
def do_paint_below_children(self, cr, damaged_box):
icon_name = self._icon_name
if icon_name == None:
icon_name = 'stock-missing'
handle = CanvasIcon._cache.get_handle(
icon_name, self._color, self._size)
buf = self._get_buffer(cr, handle, self._size)
cr.set_source_surface(buf, 0.0, 0.0)
cr.paint()
def do_get_width_request(self):
return self._size
def do_get_height_request(self, for_width):
return self._size
def _button_press_event_cb(self, item, event):
item.emit_activated()

19
sugar/graphics/grid.py Normal file
View File

@ -0,0 +1,19 @@
import gtk
COLS = 16
ROWS = 12
class Grid(object):
def __init__(self):
self._factor = gtk.gdk.screen_width() / COLS
def point(self, grid_x, grid_y):
return [grid_x * self._factor, grid_y * self._factor]
def rectangle(self, grid_x, grid_y, grid_w, grid_h):
return [grid_x * self._factor, grid_y * self._factor,
grid_w * self._factor, grid_h * self._factor]
def fit_point(self, x, y):
return [int(x / self._factor), int(y / self._factor)]

50
sugar/graphics/menu.py Normal file
View File

@ -0,0 +1,50 @@
import gtk
import hippo
import gobject
from sugar.graphics.canvasicon import CanvasIcon
class Menu(gtk.Window):
__gsignals__ = {
'action': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int])),
}
def __init__(self, title, content_box=None):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
canvas = hippo.Canvas()
self.add(canvas)
canvas.show()
self._root = hippo.CanvasBox(background_color=0x000000FF,
spacing=6)
canvas.set_root(self._root)
text = hippo.CanvasText(text=title, color=0xFFFFFFFF)
self._root.append(text)
if content_box:
separator = self._create_separator()
self._root.append(separator)
self._root.append(content_box)
separator = self._create_separator()
self._root.append(separator)
self._action_box = hippo.CanvasBox(
orientation=hippo.ORIENTATION_HORIZONTAL)
self._root.append(self._action_box)
def _create_separator(self):
separator = hippo.CanvasBox(background_color=0xFFFFFFFF,
border_left=6, border_right=6,
box_height=2)
return separator
def add_action(self, icon, action_id):
icon.connect('activated', self._action_clicked_cb, action_id)
self._action_box.append(icon)
def _action_clicked_cb(self, icon, action):
self.emit('action', action)

View File

@ -0,0 +1,93 @@
import hippo
import gobject
from sugar.graphics.canvasicon import CanvasIcon
class _MenuStrategy:
def get_menu_position(self, menu, x1, y1, x2, y2):
return [x1, y1]
class MenuIcon(CanvasIcon):
def __init__(self, menu_shell, **kwargs):
CanvasIcon.__init__(self, **kwargs)
self._menu_shell = menu_shell
self._menu = None
self._hover_menu = False
self._popdown_on_leave = False
self._popdown_sid = 0
self._menu_strategy = _MenuStrategy()
self.connect('motion-notify-event', self._motion_notify_event_cb)
def popdown(self):
if self._menu:
self._menu.destroy()
self._menu = None
self._menu_shell.set_active(None)
def set_menu_strategy(self, strategy):
self._menu_strategy = strategy
def _popup(self, x1, y1, x2, y2):
self.popdown()
self._menu_shell.set_active(None)
self._menu = self.create_menu()
self._menu.connect('enter-notify-event',
self._menu_enter_notify_event_cb)
self._menu.connect('leave-notify-event',
self._menu_leave_notify_event_cb)
strategy = self._menu_strategy
[x, y] = strategy.get_menu_position(self._menu, x1, y1, x2, y2)
self._menu.move(x, y)
self._menu.show()
self._menu_shell.set_active(self)
def _menu_enter_notify_event_cb(self, widget, event):
self._hover_menu = True
def _menu_leave_notify_event_cb(self, widget, event):
self._hover_menu = False
if self._popdown_on_leave:
self.popdown()
def _start_popdown_timeout(self):
self._stop_popdown_timeout()
self._popdown_sid = gobject.timeout_add(1000, self._popdown_timeout_cb)
def _stop_popdown_timeout(self):
if self._popdown_sid > 0:
gobject.source_remove(self._popdown_sid)
self._popdown_sid = 0
def _motion_notify_event_cb(self, item, event):
if event.detail == hippo.MOTION_DETAIL_ENTER:
self._motion_notify_enter()
elif event.detail == hippo.MOTION_DETAIL_LEAVE:
self._motion_notify_leave()
def _motion_notify_enter(self):
self._stop_popdown_timeout()
[x, y] = self.get_context().translate_to_widget(self)
[width, height] = self.get_allocation()
self._popup(x, y, width, height)
def _motion_notify_leave(self):
self._start_popdown_timeout()
def _popdown_timeout_cb(self):
self._popdown_sid = 0
if not self._hover_menu:
self.popdown()
else:
self._popdown_on_leave = True
return False

10
sugar/graphics/style.py Normal file
View File

@ -0,0 +1,10 @@
_styles = {}
def register_stylesheet(name, style):
_styles[name] = style
def apply_stylesheet(item, stylesheet_name):
if _styles.has_key(stylesheet_name):
style_sheet = _styles[stylesheet_name]
for name in style_sheet.keys():
item.set_property(name, style_sheet[name])

View File

@ -11,42 +11,35 @@ import sys
import random import random
import gtk import gtk
import goocanvas import hippo
from sugar.canvas import IconColor from sugar.canvas import IconColor
from sugar.canvas.IconItem import IconItem from sugar.canvas.CanvasIcon import CanvasIcon
from sugar.canvas.CanvasView import CanvasView from sugar.canvas.CanvasView import CanvasView
window = gtk.Window() window = gtk.Window()
window.connect("destroy", lambda w: gtk.main_quit()) window.connect("destroy", lambda w: gtk.main_quit())
window.show() window.show()
canvas = CanvasView() canvas = hippo.Canvas()
canvas.show() canvas.show()
window.add(canvas) window.add(canvas)
canvas_model = goocanvas.CanvasModelSimple() box = hippo.CanvasBox(background_color=0x4f4f4fff)
root = canvas_model.get_root_item() canvas.set_root(box)
item = goocanvas.Rect(x=0, y=0, width=1200, height=900,
line_width=0.0, fill_color="#4f4f4f")
root.add_child(item)
icon_names = [ 'stock-buddy', 'activity-groupchat', 'activity-web'] icon_names = [ 'stock-buddy', 'activity-groupchat', 'activity-web']
k = 0 k = 0
while k < 12: while k < 1:
i = 0 i = 0
while i < 16: while i < 10:
color = IconColor.IconColor() color = IconColor.IconColor()
icon_name_n = int(random.random() * len(icon_names)) icon_name_n = int(random.random() * len(icon_names))
icon = IconItem(x=i * 75, y=k * 75, icon = CanvasIcon(icon_name=icon_names[icon_name_n],
size=75, color=color, size=75, color=color)
icon_name=icon_names[icon_name_n]) box.append(icon, 0)
root.add_child(icon)
i += 1 i += 1
k += 1 k += 1
canvas.set_model(canvas_model)
gtk.main() gtk.main()

View File

@ -14,8 +14,101 @@ from sugar.canvas import IconColor
from sugar.canvas.IconItem import IconItem from sugar.canvas.IconItem import IconItem
from sugar.canvas.CanvasView import CanvasView from sugar.canvas.CanvasView import CanvasView
# Main window
window = gtk.Window() window = gtk.Window()
window.connect("destroy", lambda w: gtk.main_quit()) window.connect("destroy", lambda w: gtk.main_quit())
window.show() #window.set_border_width(10)
# Main VBox
main_vbox = gtk.VBox(homogeneous=False, spacing=0)
window.add(main_vbox)
############################### ##############################
############################### Menus ##############################
############################### ##############################
menu = gtk.Menu()
file_menu = gtk.Menu() # Don't need to show menus
edit_menu = gtk.Menu()
# Create the menu items
dummy_item_1 = gtk.MenuItem("Dummy Item 1")
dummy_item_2 = gtk.MenuItem("Dummy Item 2")
quit_item = gtk.MenuItem("Quit")
dummy_item_3 = gtk.MenuItem("Dummy Item 3")
dummy_item_4 = gtk.MenuItem("Dummy Item 4")
dummy_item_5 = gtk.MenuItem("Dummy Item 5")
# Add them to the menu
file_menu.append(dummy_item_1)
file_menu.append(dummy_item_2)
file_menu.append(quit_item)
edit_menu.append(dummy_item_3)
edit_menu.append(dummy_item_4)
edit_menu.append(dummy_item_5)
# We can attach the Quit menu item to our exit function
quit_item.connect_object ("activate", lambda w: gtk.main_quit (), "file.quit")
# We do need to show menu items
dummy_item_1.show()
dummy_item_2.show()
quit_item.show()
dummy_item_3.show()
dummy_item_4.show()
dummy_item_5.show()
# Pack the menu into the menubar
menu_bar = gtk.MenuBar()
main_vbox.pack_start(menu_bar, False, False, 0)
menu_bar.show()
file_item = gtk.MenuItem("File")
file_item.show()
menu_bar.append(file_item)
file_item.set_submenu(file_menu)
edit_item = gtk.MenuItem("Edit")
edit_item.show()
menu_bar.append(edit_item)
edit_item.set_submenu(edit_menu)
# Scrolled window
scrolled_window = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
#scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
scrolled_window.set_border_width(10)
main_vbox.pack_start(scrolled_window, True, True, 0)
# Vbox inside the scrolled window
vbox = gtk.VBox(homogeneous=False, spacing=10)
scrolled_window.add_with_viewport(vbox)
vbox.set_border_width (10)
# Label
label = gtk.Label("This is a label")
vbox.pack_start(label, False, False, 0)
# Entry
entry = gtk.Entry ()
entry.set_text("Type some text here")
vbox.pack_start(entry, False, False, 0)
# Buttons
buttons_hbox = gtk.HBox(homogeneous=False, spacing=5)
vbox.pack_start(buttons_hbox, False, False, 0)
button_1 = gtk.Button ("Button 1")
buttons_hbox.pack_start(button_1, False, False, 0)
button_2 = gtk.Button ("Button 2")
buttons_hbox.pack_start(button_2, False, False, 0)
button_3 = gtk.Button ("Button 3")
buttons_hbox.pack_start(button_3, False, False, 0)
window.show_all()
gtk.main() gtk.main()

28
tests/test-window-manager.py Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/python
import pygtk
pygtk.require('2.0')
from sugar.session.UITestSession import UITestSession
session = UITestSession()
session.start()
import gtk
def _show_dialog(window):
dialog = gtk.Dialog(title='No Unviewed Media',
parent=window, flags=gtk.DIALOG_MODAL,
buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
label = gtk.Label('There is no unviewed media to download.')
dialog.vbox.pack_start(label, True, True, 0)
label.show()
response = dialog.run()
dialog.hide()
del dialog
window = gtk.Window()
window.show()
_show_dialog(window)
gtk.main()