diff --git a/shell/view/clipboardicon.py b/shell/view/clipboardicon.py index 48e8bebb..65eafb77 100644 --- a/shell/view/clipboardicon.py +++ b/shell/view/clipboardicon.py @@ -3,6 +3,7 @@ import logging from sugar.graphics.canvasicon import CanvasIcon from view.clipboardmenu import ClipboardMenu from sugar.graphics.iconcolor import IconColor +from sugar.graphics import units from sugar.activity import activityfactory from sugar.clipboard import clipboardservice from sugar import util @@ -17,6 +18,9 @@ class ClipboardIcon(CanvasIcon): self._percent = 0 self._preview = None self._activity = None + self.props.box_width = units.grid_to_pixels(1) + self.props.box_height = units.grid_to_pixels(1) + self.props.scale = units.STANDARD_ICON_SCALE self.connect('activated', self._icon_activated_cb) self._menu = None diff --git a/shell/view/frame/ActivitiesBox.py b/shell/view/frame/ActivitiesBox.py index ea64b7f3..5d4c59d7 100644 --- a/shell/view/frame/ActivitiesBox.py +++ b/shell/view/frame/ActivitiesBox.py @@ -25,10 +25,11 @@ from sugar.activity import bundleregistry from sugar import profile class ActivityButton(IconButton): - def __init__(self, activity): - IconButton.__init__(self, icon_name=activity.get_icon()) - + def __init__(self, activity, popup_context): + IconButton.__init__(self, icon_name=activity.get_icon(), + tooltip=activity.get_name()) self._activity = activity + self._popup_context = popup_context def _mouse_motion_event_cb(self, item, event): if event.detail == hippo.MOTION_DETAIL_ENTER: @@ -38,6 +39,9 @@ class ActivityButton(IconButton): def get_bundle_id(self): return self._activity.get_service_name() + + def get_popup_context(self): + return self._popup_context class InviteButton(IconButton): def __init__(self, activity, invite): @@ -56,13 +60,14 @@ class InviteButton(IconButton): return self._invite class ActivitiesBox(hippo.CanvasBox): - def __init__(self, shell): + def __init__(self, shell, popup_context): hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL) self._shell = shell self._shell_model = self._shell.get_model() self._invite_to_item = {} self._invites = self._shell_model.get_invites() + self._popup_context = popup_context bundle_registry = bundleregistry.get_registry() for bundle in bundle_registry: @@ -94,7 +99,7 @@ class ActivitiesBox(hippo.CanvasBox): self.add_activity(bundle) def add_activity(self, activity): - item = ActivityButton(activity) + item = ActivityButton(activity, self._popup_context) item.connect('activated', self._activity_clicked_cb) self.append(item, 0) diff --git a/shell/view/frame/frame.py b/shell/view/frame/frame.py index f8a89ee7..27658f03 100644 --- a/shell/view/frame/frame.py +++ b/shell/view/frame/frame.py @@ -102,7 +102,7 @@ class Frame: panel = self._create_panel(hippo.ORIENTATION_HORIZONTAL) root = panel.get_root() - box = ActivitiesBox(self._shell) + box = ActivitiesBox(self._shell, self._popup_context) root.append(box) return panel diff --git a/shell/view/frame/framepopupcontext.py b/shell/view/frame/framepopupcontext.py index cf35293a..b4b5c094 100644 --- a/shell/view/frame/framepopupcontext.py +++ b/shell/view/frame/framepopupcontext.py @@ -14,13 +14,52 @@ # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. +import logging + import gobject +import gtk import hippo from sugar.graphics.popupcontext import PopupContext +from sugar.graphics import units class FramePopupContext(PopupContext): __gtype_name__ = 'SugarFramePopupContext' def __init__(self): PopupContext.__init__(self) + + def get_position(self, control, popup): + [item_x, item_y] = control.get_context().translate_to_screen(control) + [item_w, item_h] = control.get_allocation() + [popup_w, popup_h] = popup.get_request() + + left_x = item_x + item_w + left_y = item_y + right_x = item_x + item_w + right_y = item_y + top_x = item_x + top_y = item_y + item_h + bottom_x = item_x + bottom_y = item_y - popup_h + + grid_size = units.grid_to_pixels(1) + if item_x < grid_size: + [x, y] = [left_x, left_y] + elif item_x >= (gtk.gdk.screen_width() - grid_size): + [x, y] = [right_x, right_y] + elif item_y < grid_size: + [x, y] = [top_x, top_y] + elif item_y >= (gtk.gdk.screen_height() - grid_size): + [x, y] = [bottom_x, bottom_y] + else: + logging.error('Item not in the frame!') + return [None, None] + + x = min(x, gtk.gdk.screen_width() - popup_w) + x = max(0, x) + + y = min(y, gtk.gdk.screen_height() - popup_h) + y = max(0, y) + + return [x, y] diff --git a/sugar/graphics/canvasicon.py b/sugar/graphics/canvasicon.py index fb4974a9..67c35aa5 100644 --- a/sugar/graphics/canvasicon.py +++ b/sugar/graphics/canvasicon.py @@ -26,6 +26,10 @@ import time from sugar.graphics.iconcolor import IconColor from sugar.graphics.timeline import Timeline +from sugar.graphics.popup import Popup +from sugar.graphics import color +from sugar.graphics import font +from sugar.graphics import units class _IconCacheIcon: def __init__(self, name, color, now): @@ -140,6 +144,8 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): 0.0, 1024.0, 1.0, gobject.PARAM_READWRITE), 'cache' : (bool, None, None, False, + gobject.PARAM_READWRITE), + 'tooltip' : (str, None, None, None, gobject.PARAM_READWRITE) } @@ -155,7 +161,8 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): self._handle = None self._popup = None self._hover_popup = False - + self._tooltip = False + self._timeline = Timeline(self) self._timeline.add_tag('popup', 6, 6) self._timeline.add_tag('before_popdown', 7, 7) @@ -193,6 +200,8 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): self.emit_request_changed() elif pspec.name == 'cache': self._cache = value + elif pspec.name == 'tooltip': + self._tooltip = value def _get_handle(self): if not self._handle: @@ -212,6 +221,8 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): return self._color elif pspec.name == 'cache': return self._cache + elif pspec.name == 'tooltip': + return self._tooltip def _get_icon_size(self): handle = self._get_handle() @@ -272,7 +283,19 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): item.emit_activated() def get_popup(self): - return self._popup + if self._tooltip: + tooltip_popup = Popup() + canvas_text = hippo.CanvasText(text=self._tooltip) + canvas_text.props.background_color = color.MENU_BACKGROUND.get_int() + canvas_text.props.border_color = color.MENU_BORDER.get_int() + canvas_text.props.border = units.points_to_pixels(1) + canvas_text.props.color = color.LABEL_TEXT.get_int() + canvas_text.props.font_desc = font.DEFAULT.get_pango_desc() + tooltip_popup.append(canvas_text) + + return tooltip_popup + else: + return None def get_popup_context(self): return None diff --git a/sugar/graphics/iconbutton.py b/sugar/graphics/iconbutton.py index c2a10465..b1992a60 100644 --- a/sugar/graphics/iconbutton.py +++ b/sugar/graphics/iconbutton.py @@ -39,19 +39,19 @@ class IconButton(CanvasIcon): gobject.PARAM_READWRITE) } - def __init__(self, icon_name, color=None): - if color: - self._normal_color = color + def __init__(self, **kwargs): + self._active = True + + CanvasIcon.__init__(self, cache=True, **kwargs) + + if self.props.color: + self._normal_color = self.props.color else: self._normal_color = IconColor('white') + self.props.color = self._normal_color self._prelight_color = profile.get_color() self._inactive_color = IconColor('#808080,#424242') - self._active = True - - CanvasIcon.__init__(self, icon_name=icon_name, cache=True, - color=self._normal_color) - self._set_size(STANDARD_SIZE) self.connect('button-press-event', self._button_press_event_cb) diff --git a/sugar/graphics/popup.py b/sugar/graphics/popup.py index 09a1fe25..5c63b6e3 100644 --- a/sugar/graphics/popup.py +++ b/sugar/graphics/popup.py @@ -30,20 +30,21 @@ class Popup(hippo.CanvasBox, hippo.CanvasItem): def __init__(self): hippo.CanvasBox.__init__(self) - self._window = None + self._visible = False + self._window = hippo.CanvasWindow(gtk.WINDOW_POPUP) + self._window.set_root(self) self.connect('button-press-event', self._button_press_event_cb) def popup(self, x, y): - if not self._window: - self._window = hippo.CanvasWindow(gtk.WINDOW_POPUP) + if not self._visible: self._window.move(x, y) - self._window.set_root(self) self._window.show() + self._visible = True def popdown(self): - if self._window: - self._window.destroy() - self._window = None + if self._visible: + self._window.hide() + self._visible = False def _button_press_event_cb(self, menu, event): self.emit('action-completed')