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

This commit is contained in:
Dan Williams 2006-10-19 09:52:55 -04:00
commit 4f54f7921f
18 changed files with 190 additions and 117 deletions

View File

@ -17,16 +17,31 @@
import gtk import gtk
import hippo import hippo
from sugar.graphics.bubble import Bubble from sugar.graphics.menu import Menu
from sugar.graphics.menushell import MenuShell
from sugar.graphics.menuicon import MenuIcon
from sugar.graphics.iconcolor import IconColor from sugar.graphics.iconcolor import IconColor
from sugar.graphics import style from sugar.graphics import style
class LinkIcon(MenuIcon):
def __init__(self, menu_shell, link):
color = IconColor(link.buddy.get_color())
MenuIcon.__init__(self, menu_shell, color=color,
icon_name='activity-web')
self._link = link
def create_menu(self):
menu = Menu(self._link.title)
return menu
class LinksView(hippo.Canvas): class LinksView(hippo.Canvas):
def __init__(self, model, browser): def __init__(self, model, browser):
hippo.Canvas.__init__(self) hippo.Canvas.__init__(self)
self._bubbles = {} self._icons = {}
self._browser = browser self._browser = browser
self._menu_shell = MenuShell(self)
self._box = hippo.CanvasBox() self._box = hippo.CanvasBox()
style.apply_stylesheet(self._box, 'links.Box') style.apply_stylesheet(self._box, 'links.Box')
@ -39,36 +54,30 @@ class LinksView(hippo.Canvas):
model.connect('link_removed', self._link_removed_cb) model.connect('link_removed', self._link_removed_cb)
def _add_link(self, link): def _add_link(self, link):
if len(self._bubbles) == 0: if len(self._icons) == 0:
self.show() self.show()
color = IconColor(link.buddy.get_color()) icon = LinkIcon(self._menu_shell, link)
icon.connect('activated', self._link_activated_cb, link)
style.apply_stylesheet(icon, 'links.Icon')
self._box.append(icon)
bubble = Bubble(color=color) self._icons[link] = icon
style.apply_stylesheet(bubble, 'links.Bubble')
self._box.append(bubble)
text = hippo.CanvasLink(text=link.title)
text.connect('activated', self._link_activated_cb, link)
style.apply_stylesheet(text, 'links.Text')
bubble.append(text, hippo.PACK_EXPAND)
self._bubbles[link] = bubble
def _remove_link(self, link): def _remove_link(self, link):
bubble = self._bubbles[link] icon = self._icons[link]
self._box.remove(bubble) self._box.remove(icon)
del self._bubbles[link] del self._icons[link]
if len(self._bubbles) == 0: if len(self._icons) == 0:
self.hide() self.hide()
def _link_added_cb(self, model, link): def _link_added_cb(self, model, link):
self._add_link(link) self._add_link(link)
def _link_removed_cb(self, model, link): def _link_removed_cb(self, model, link):
self._removed_link(link) self._remove_link(link)
def _link_activated_cb(self, link_item, link): def _link_activated_cb(self, link_item, link):
self._browser.load_url(link.url) self._browser.load_url(link.url)

View File

@ -16,19 +16,12 @@
import gtk import gtk
_screen_factor = gtk.gdk.screen_width() / 1200.0 from sugar.graphics import style
links_Bubble = { links_Icon = {
'box-width' : int(250.0 * _screen_factor) 'size' : style.standard_icon_size
}
links_Text = {
'color' : 0x000000FF,
'font' : '14px',
'padding' : 6
} }
links_Box = { links_Box = {
'background_color' : 0x646464ff, 'background_color' : 0x414141ff,
'padding' : 4
} }

View File

@ -1,4 +1,4 @@
AC_INIT([Sugar],[0.36],[],[sugar]) AC_INIT([Sugar],[0.37],[],[sugar])
AC_PREREQ([2.59]) AC_PREREQ([2.59])

View File

@ -139,7 +139,4 @@ class BuddyModel(gobject.GObject):
def __buddy_current_activity_changed_cb(self, buddy, activity=None): def __buddy_current_activity_changed_cb(self, buddy, activity=None):
if not self._buddy: if not self._buddy:
return return
if activity: self.emit('current-activity-changed', activity)
self.emit('current-activity-changed', activity)
else:
self.emit('current-activity-changed')

View File

@ -86,7 +86,7 @@ class MeshModel(gobject.GObject):
if cur_activity == None: if cur_activity == None:
self.emit('buddy-moved', buddy_model, None) self.emit('buddy-moved', buddy_model, None)
else: elif self._activities.has_key(cur_activity.get_id()):
activity_model = self._activities[cur_activity.get_id()] activity_model = self._activities[cur_activity.get_id()]
self.emit('buddy-moved', buddy_model, activity_model) self.emit('buddy-moved', buddy_model, activity_model)
@ -121,6 +121,12 @@ class MeshModel(gobject.GObject):
self._activities[model.get_id()] = model self._activities[model.get_id()] = model
self.emit('activity-added', model) self.emit('activity-added', model)
for buddy in self._pservice.get_buddies():
cur_activity = buddy.get_current_activity()
if cur_activity == activity:
buddy_model = self._buddies[buddy.get_name()]
self.emit('buddy-moved', buddy, model)
def _activity_disappeared_cb(self, pservice, activity): def _activity_disappeared_cb(self, pservice, activity):
if self._activities.has_key(activity.get_id()): if self._activities.has_key(activity.get_id()):
activity_model = self._activities[activity.get_id()] activity_model = self._activities[activity.get_id()]

View File

@ -42,9 +42,7 @@ class ActivityChatWindow(gtk.Window):
self.add(chat_widget) self.add(chat_widget)
class ActivityHost: class ActivityHost:
def __init__(self, shell, window): def __init__(self, window):
self._shell = shell
self._window = window self._window = window
self._xid = window.get_xid() self._xid = window.get_xid()
self._pservice = PresenceService.get_instance() self._pservice = PresenceService.get_instance()
@ -73,8 +71,6 @@ class ActivityHost:
self._chat_window = ActivityChatWindow(win, self._chat_widget) self._chat_window = ActivityChatWindow(win, self._chat_widget)
self._frame_was_visible = False self._frame_was_visible = False
self._shell.connect('activity-changed', self._activity_changed_cb)
self._shell.connect('activity-closed', self._activity_closed_cb)
def get_id(self): def get_id(self):
return self._id return self._id
@ -143,13 +139,11 @@ class ActivityHost:
def is_chat_visible(self): def is_chat_visible(self):
return self._chat_window.get_property('visible') return self._chat_window.get_property('visible')
def _activity_changed_cb(self, shell, activity): def set_active(self, active):
if activity != self: if not active:
self.chat_hide()
self._frame_was_visible = False
def _activity_closed_cb(self, shell, activity):
if activity == self:
self.chat_hide() self.chat_hide()
self._frame_was_visible = False self._frame_was_visible = False
def destroy(self):
self._chat_window.destroy()
self._frame_was_visible = False

View File

@ -45,6 +45,7 @@ class Shell(gobject.GObject):
self._model = model self._model = model
self._hosts = {} self._hosts = {}
self._screen = wnck.screen_get_default() self._screen = wnck.screen_get_default()
self._current_host = None
style.load_stylesheet(view.stylesheet) style.load_stylesheet(view.stylesheet)
@ -95,7 +96,7 @@ class Shell(gobject.GObject):
def __window_opened_cb(self, screen, window): def __window_opened_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL: if window.get_window_type() == wnck.WINDOW_NORMAL:
activity_host = ActivityHost(self, window) activity_host = ActivityHost(window)
self._hosts[activity_host.get_xid()] = activity_host self._hosts[activity_host.get_xid()] = activity_host
self.emit('activity-opened', activity_host) self.emit('activity-opened', activity_host)
@ -104,24 +105,39 @@ class Shell(gobject.GObject):
if window and window.get_window_type() == wnck.WINDOW_NORMAL: if window and window.get_window_type() == wnck.WINDOW_NORMAL:
activity_host = self._hosts[window.get_xid()] activity_host = self._hosts[window.get_xid()]
current = self._model.get_current_activity() current = self._model.get_current_activity()
if activity_host.get_id() == current: if activity_host.get_id() == current:
return return
self._model.set_current_activity(activity_host.get_id()) self._set_current_activity(activity_host)
self.emit('activity-changed', activity_host)
def __window_closed_cb(self, screen, window): def __window_closed_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL: if window.get_window_type() == wnck.WINDOW_NORMAL:
if self._hosts.has_key(window.get_xid()): if self._hosts.has_key(window.get_xid()):
host = self._hosts[window.get_xid()] host = self._hosts[window.get_xid()]
host.destroy()
self.emit('activity-closed', host) self.emit('activity-closed', host)
del self._hosts[window.get_xid()] del self._hosts[window.get_xid()]
if len(self._hosts) == 0: if len(self._hosts) == 0:
self._set_current_activity(None)
def _set_current_activity(self, host):
if host:
self._model.set_current_activity(host.get_id())
else:
self._model.set_current_activity(None) self._model.set_current_activity(None)
self.emit('activity-changed', None)
if self._current_host:
self._current_host.set_active(False)
self._current_host = host
if self._current_host:
self._current_host.set_active(True)
self.emit('activity-changed', host)
def get_model(self): def get_model(self):
return self._model return self._model

View File

@ -26,6 +26,7 @@ from view.frame.PanelWindow import PanelWindow
from view.frame.notificationtray import NotificationTray from view.frame.notificationtray import NotificationTray
from sugar.graphics.timeline import Timeline from sugar.graphics.timeline import Timeline
from sugar.graphics.grid import Grid from sugar.graphics.grid import Grid
from sugar.graphics.menushell import MenuShell
class EventFrame(gobject.GObject): class EventFrame(gobject.GObject):
__gsignals__ = { __gsignals__ = {
@ -151,6 +152,7 @@ class Frame:
# Top panel # Top panel
[menu_shell, root] = self._create_panel(grid, 0, 0, 16, 1) [menu_shell, root] = self._create_panel(grid, 0, 0, 16, 1)
menu_shell.set_position(MenuShell.BOTTOM)
box = ZoomBox(self._shell, menu_shell) box = ZoomBox(self._shell, menu_shell)
@ -173,6 +175,7 @@ class Frame:
# Bottom panel # Bottom panel
[menu_shell, root] = self._create_panel(grid, 0, 11, 16, 1) [menu_shell, root] = self._create_panel(grid, 0, 11, 16, 1)
menu_shell.set_position(MenuShell.TOP)
box = ActivitiesBox(self._shell) box = ActivitiesBox(self._shell)
root.append(box, hippo.PACK_FIXED) root.append(box, hippo.PACK_FIXED)
@ -182,6 +185,7 @@ class Frame:
# Right panel # Right panel
[menu_shell, root] = self._create_panel(grid, 15, 1, 1, 10) [menu_shell, root] = self._create_panel(grid, 15, 1, 1, 10)
menu_shell.set_position(MenuShell.LEFT)
box = FriendsBox(self._shell, menu_shell) box = FriendsBox(self._shell, menu_shell)
root.append(box) root.append(box)

View File

@ -39,7 +39,7 @@ class FriendsBox(hippo.CanvasBox):
shell.connect('activity-changed', self.__activity_changed_cb) shell.connect('activity-changed', self.__activity_changed_cb)
def add(self, buddy): def add_buddy(self, buddy):
model = BuddyModel(buddy=buddy) model = BuddyModel(buddy=buddy)
icon = BuddyIcon(self._shell, self._menu_shell, model) icon = BuddyIcon(self._shell, self._menu_shell, model)
style.apply_stylesheet(icon, 'frame.BuddyIcon') style.apply_stylesheet(icon, 'frame.BuddyIcon')
@ -47,7 +47,7 @@ class FriendsBox(hippo.CanvasBox):
self._buddies[buddy.get_name()] = icon self._buddies[buddy.get_name()] = icon
def remove(self, buddy): def remove_buddy(self, buddy):
self.remove(self._buddies[buddy.get_name()]) self.remove(self._buddies[buddy.get_name()])
def clear(self): def clear(self):
@ -77,7 +77,7 @@ class FriendsBox(hippo.CanvasBox):
if activity_ps != None: if activity_ps != None:
for buddy in activity_ps.get_joined_buddies(): for buddy in activity_ps.get_joined_buddies():
self.add(buddy) self.add_buddy(buddy)
self._joined_hid = activity_ps.connect( self._joined_hid = activity_ps.connect(
'buddy-joined', self.__buddy_joined_cb) 'buddy-joined', self.__buddy_joined_cb)
@ -92,7 +92,7 @@ class FriendsBox(hippo.CanvasBox):
self._set_activity_ps(None) self._set_activity_ps(None)
def __buddy_joined_cb(self, activity, buddy): def __buddy_joined_cb(self, activity, buddy):
self.add(buddy) self.add_buddy(buddy)
def __buddy_left_cb(self, activity, buddy): def __buddy_left_cb(self, activity, buddy):
self.remove(buddy) self.remove_buddy(buddy)

View File

@ -29,9 +29,16 @@ class ActivityMenu(Menu):
def __init__(self, activity_host): def __init__(self, activity_host):
Menu.__init__(self, activity_host.get_title()) Menu.__init__(self, activity_host.get_title())
if not activity_host.get_shared():
self._add_mesh_action()
self._add_close_action()
def _add_mesh_action(self):
icon = CanvasIcon(icon_name='stock-share-mesh') icon = CanvasIcon(icon_name='stock-share-mesh')
self.add_action(icon, ActivityMenu.ACTION_SHARE) self.add_action(icon, ActivityMenu.ACTION_SHARE)
def _add_close_action(self):
icon = CanvasIcon(icon_name='stock-close') icon = CanvasIcon(icon_name='stock-close')
self.add_action(icon, ActivityMenu.ACTION_CLOSE) self.add_action(icon, ActivityMenu.ACTION_CLOSE)

View File

@ -75,7 +75,7 @@ class FriendView(hippo.CanvasBox):
self._activity_icon.props.icon_name = name self._activity_icon.props.icon_name = name
self._activity_icon.props.color = buddy.get_color() self._activity_icon.props.color = buddy.get_color()
if not self._activity_icon_visible: if not self._activity_icon_visible:
self.append(self._activity_icon) self.append(self._activity_icon, hippo.PACK_EXPAND)
self._activity_icon_visible = True self._activity_icon_visible = True
else: else:
self._remove_activity_icon() self._remove_activity_icon()

View File

@ -18,71 +18,37 @@ import gtk
import hippo import hippo
from sugar.graphics.iconcolor import IconColor from sugar.graphics.iconcolor import IconColor
from sugar.graphics import style
_screen_factor = gtk.gdk.screen_width() / 1200.0
_standard_icon_size = int(75.0 * _screen_factor)
_small_icon_size = _standard_icon_size * 0.5
_medium_icon_size = _standard_icon_size * 1.5
_large_icon_size = _standard_icon_size * 2.0
_xlarge_icon_size = _standard_icon_size * 3.0
_space_unit = 9 * _screen_factor
_separator_thickness = 3 * _screen_factor
def _font_description(style, relative_size):
base_size = 18 * _screen_factor
return '%s %dpx' % (style, int(base_size * relative_size))
frame_ActivityIcon = { frame_ActivityIcon = {
'color' : IconColor('white'), 'color' : IconColor('white'),
'size' : _standard_icon_size 'size' : style.standard_icon_size
} }
frame_ZoomIcon = { frame_ZoomIcon = {
'size' : _standard_icon_size 'size' : style.standard_icon_size
} }
frame_BuddyIcon = { frame_BuddyIcon = {
'size' : _standard_icon_size 'size' : style.standard_icon_size
}
menu = {
'background_color' : 0x000000FF,
'spacing' : _space_unit,
'padding' : _space_unit
}
menu_Title = {
'color' : 0xFFFFFFFF,
'font' : _font_description('Bold', 1.2)
}
menu_Separator = {
'background_color' : 0xFFFFFFFF,
'box_height' : _separator_thickness
}
menu_ActionIcon = {
'size' : _standard_icon_size
} }
home_MyIcon = { home_MyIcon = {
'size' : _xlarge_icon_size 'size' : style.xlarge_icon_size
} }
ring_ActivityIcon = { ring_ActivityIcon = {
'size' : _medium_icon_size 'size' : style.medium_icon_size
} }
friends_MyIcon = { friends_MyIcon = {
'size' : _large_icon_size 'size' : style.large_icon_size
} }
friends_FriendIcon = { friends_FriendIcon = {
'size' : _large_icon_size 'size' : style.large_icon_size
} }
friends_ActivityIcon = { friends_ActivityIcon = {
'size' : _standard_icon_size 'size' : style.standard_icon_size
} }

View File

@ -26,6 +26,8 @@ class ActivityChat(GroupChat):
GroupChat.__init__(self) GroupChat.__init__(self)
self._chat_service = None self._chat_service = None
self.connect('destroy', self._destroy_cb)
self._activity = activity self._activity = activity
self._pservice.register_service_type(ActivityChat.SERVICE_TYPE) self._pservice.register_service_type(ActivityChat.SERVICE_TYPE)
self._pservice.connect('service-appeared', self._service_appeared_cb) self._pservice.connect('service-appeared', self._service_appeared_cb)
@ -59,3 +61,7 @@ class ActivityChat(GroupChat):
self._chat_service = self._pservice.share_activity(self._activity, self._chat_service = self._pservice.share_activity(self._activity,
stype=ActivityChat.SERVICE_TYPE) stype=ActivityChat.SERVICE_TYPE)
self._setup_stream(self._chat_service) self._setup_stream(self._chat_service)
def _destroy_cb(self, widget):
if self._chat_service:
self._pservice.unregister_service(self._chat_service)

View File

@ -0,0 +1,4 @@
from sugar.graphics import style
from sugar.graphics import stylesheet
style.load_stylesheet(stylesheet)

View File

@ -143,7 +143,11 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
icon_name, self._color, self._size) icon_name, self._color, self._size)
buf = self._get_buffer(cr, handle, self._size) buf = self._get_buffer(cr, handle, self._size)
cr.set_source_surface(buf, 0.0, 0.0) [width, height] = self.get_allocation()
x = (width - self._size) / 2
y = (height - self._size) / 2
cr.set_source_surface(buf, x, y)
cr.paint() cr.paint()
def do_get_width_request(self): def do_get_width_request(self):

View File

@ -16,6 +16,7 @@
# Boston, MA 02111-1307, USA. # Boston, MA 02111-1307, USA.
import gobject import gobject
import gtk
class MenuShell(gobject.GObject): class MenuShell(gobject.GObject):
__gsignals__ = { __gsignals__ = {
@ -25,11 +26,21 @@ class MenuShell(gobject.GObject):
gobject.TYPE_NONE, ([])), gobject.TYPE_NONE, ([])),
} }
AUTO = 0
LEFT = 1
RIGHT = 2
TOP = 3
BOTTOM = 4
def __init__(self, parent_canvas): def __init__(self, parent_canvas):
gobject.GObject.__init__(self) gobject.GObject.__init__(self)
self._parent_canvas = parent_canvas self._parent_canvas = parent_canvas
self._menu_controller = None self._menu_controller = None
self._position = MenuShell.AUTO
def set_position(self, position):
self._position = position
def is_active(self): def is_active(self):
return (self._menu_controller != None) return (self._menu_controller != None)
@ -44,29 +55,47 @@ class MenuShell(gobject.GObject):
self._menu_controller.popdown() self._menu_controller.popdown()
self._menu_controller = controller self._menu_controller = controller
def _get_item_origin(self, item): def _get_item_rect(self, item):
[x, y] = item.get_context().translate_to_widget(item) [x, y] = item.get_context().translate_to_widget(item)
[origin_x, origin_y] = self._parent_canvas.window.get_origin() [origin_x, origin_y] = self._parent_canvas.window.get_origin()
x += origin_x x += origin_x
y += origin_y y += origin_y
return [x, y] [w, h] = item.get_allocation()
return [x, y, w, h]
def get_position(self, menu, item): def get_position(self, menu, item):
[x, y] = self._get_item_origin(item) [item_x, item_y, item_w, item_h] = self._get_item_rect(item)
[width, height] = item.get_allocation()
[canvas_x, canvas_y] = self._parent_canvas.window.get_origin()
canvas_rect = self._parent_canvas.get_allocation()
[menu_w, menu_h] = menu.size_request() [menu_w, menu_h] = menu.size_request()
menu_x = x left_x = item_x - menu_w
menu_y = y + height left_y = item_y
right_x = item_x + item_w
right_y = item_y
top_x = item_x
top_y = item_y - menu_h
bottom_x = item_x
bottom_y = item_y + item_h
if (menu_x + menu_w > canvas_x) and \ if self._position == MenuShell.LEFT:
(menu_y < canvas_y + canvas_rect.height): [x, y] = [left_x, left_y]
menu_x = x - menu_w elif self._position == MenuShell.RIGHT:
menu_y = y [x, y] = [right_x, right_y]
elif self._position == MenuShell.TOP:
[x, y] = [top_x, top_y]
elif self._position == MenuShell.BOTTOM:
[x, y] = [bottom_x, bottom_y]
elif self._position == MenuShell.AUTO:
[x, y] = [right_x, right_y]
if x + menu_w > gtk.gdk.screen_width():
[x, y] = [left_x, left_y]
return [menu_x, menu_y] x = min(x, gtk.gdk.screen_width() - menu_w)
x = max(0, x)
y = min(y, gtk.gdk.screen_height() - menu_h)
y = max(0, y)
return [x, y]

View File

@ -15,8 +15,21 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA. # Boston, MA 02111-1307, USA.
import gtk
_styles = {} _styles = {}
_screen_factor = gtk.gdk.screen_width() / 1200.0
space_unit = 9 * _screen_factor
separator_thickness = 3 * _screen_factor
standard_icon_size = int(75.0 * _screen_factor)
small_icon_size = standard_icon_size * 0.5
medium_icon_size = standard_icon_size * 1.5
large_icon_size = standard_icon_size * 2.0
xlarge_icon_size = standard_icon_size * 3.0
def load_stylesheet(module): def load_stylesheet(module):
for objname in dir(module): for objname in dir(module):
if not objname.startswith('_'): if not objname.startswith('_'):
@ -32,3 +45,7 @@ def apply_stylesheet(item, stylesheet_name):
style_sheet = _styles[stylesheet_name] style_sheet = _styles[stylesheet_name]
for name in style_sheet.keys(): for name in style_sheet.keys():
item.set_property(name, style_sheet[name]) item.set_property(name, style_sheet[name])
def get_font_description(style, relative_size):
base_size = 18 * _screen_factor
return '%s %dpx' % (style, int(base_size * relative_size))

View File

@ -0,0 +1,21 @@
from sugar.graphics import style
menu = {
'background_color' : 0x000000FF,
'spacing' : style.space_unit,
'padding' : style.space_unit
}
menu_Title = {
'color' : 0xFFFFFFFF,
'font' : style.get_font_description('Bold', 1.2)
}
menu_Separator = {
'background_color' : 0xFFFFFFFF,
'box_height' : style.separator_thickness
}
menu_ActionIcon = {
'size' : style.standard_icon_size
}