diff options
Diffstat (limited to 'src/jarabe/frame/frame.py')
-rw-r--r-- | src/jarabe/frame/frame.py | 132 |
1 files changed, 114 insertions, 18 deletions
diff --git a/src/jarabe/frame/frame.py b/src/jarabe/frame/frame.py index 410e08b..19754c9 100644 --- a/src/jarabe/frame/frame.py +++ b/src/jarabe/frame/frame.py @@ -15,6 +15,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import logging +import os from gi.repository import Gtk from gi.repository import Gdk @@ -33,6 +34,7 @@ from jarabe.frame.devicestray import DevicesTray from jarabe.frame.framewindow import FrameWindow from jarabe.frame.clipboardpanelwindow import ClipboardPanelWindow from jarabe.frame.notification import NotificationIcon, NotificationWindow +from jarabe.frame.notification import NotificationButton, HistoryPalette from jarabe.model import notifications @@ -43,6 +45,8 @@ BOTTOM_LEFT = 3 _NOTIFICATION_DURATION = 5000 +_DEFAULT_ICON = 'emblem-notification' + class _Animation(animator.Animation): def __init__(self, frame, end): @@ -83,6 +87,10 @@ class Frame(object): self._event_area.connect('enter', self._enter_corner_cb) self._event_area.show() + self._activities_tray = None + self._devices_tray = None + self._friends_tray = None + self._top_panel = self._create_top_panel() self._bottom_panel = self._create_bottom_panel() self._left_panel = self._create_left_panel() @@ -94,6 +102,7 @@ class Frame(object): self._key_listener = _KeyListener(self) self._notif_by_icon = {} + self._notif_by_message = {} notification_service = notifications.get_service() notification_service.notification_received.connect( @@ -143,6 +152,8 @@ class Frame(object): panel.append(activities_tray) activities_tray.show() + self._activities_tray = activities_tray + return panel def _create_bottom_panel(self): @@ -152,6 +163,8 @@ class Frame(object): panel.append(devices_tray) devices_tray.show() + self._devices_tray = devices_tray + return panel def _create_right_panel(self): @@ -161,6 +174,8 @@ class Frame(object): panel.append(tray) tray.show() + self._friends_tray = tray + return panel def _create_left_panel(self): @@ -211,15 +226,7 @@ class Frame(object): else: self.show() - def notify_key_press(self): - self._key_listener.key_press() - - def add_notification(self, icon, corner=Gtk.CornerType.TOP_LEFT, - duration=_NOTIFICATION_DURATION): - - if not isinstance(icon, NotificationIcon): - raise TypeError('icon must be a NotificationIcon.') - + def _create_notification_window(self, corner): window = NotificationWindow() screen = Gdk.Screen.get_default() @@ -235,6 +242,47 @@ class Frame(object): else: raise ValueError('Inalid corner: %r' % corner) + return window + + def _add_message_button(self, button, corner): + if corner == Gtk.CornerType.BOTTOM_RIGHT: + self._devices_tray.add_item(button) + elif corner == Gtk.CornerType.TOP_RIGHT: + self._friends_tray.add_item(button) + else: + self._activities_tray.add_item(button) + + def _remove_message_button(self, button, corner): + if corner == Gtk.CornerType.BOTTOM_RIGHT: + self._devices_tray.remove_item(button) + elif corner == Gtk.CornerType.TOP_RIGHT: + self._friends_tray.remove_item(button) + else: + self._activities_tray.remove_item(button) + + def _launch_notification_icon(self, icon_name, xo_color, + position, duration): + icon = NotificationIcon() + icon.props.xo_color = xo_color + + if icon_name.startswith(os.sep): + icon.props.icon_filename = icon_name + else: + icon.props.icon_name = icon_name + + self.add_notification(icon, position, duration) + + def notify_key_press(self): + self._key_listener.key_press() + + def add_notification(self, icon, corner=Gtk.CornerType.TOP_LEFT, + duration=_NOTIFICATION_DURATION): + + if not isinstance(icon, NotificationIcon): + raise TypeError('icon must be a NotificationIcon.') + + window = self._create_notification_window(corner) + window.add(icon) icon.show() window.show() @@ -253,28 +301,76 @@ class Frame(object): window.destroy() del self._notif_by_icon[icon] + def add_message(self, body, summary='', icon_name=_DEFAULT_ICON, + xo_color=None, corner=Gtk.CornerType.TOP_LEFT, + duration=_NOTIFICATION_DURATION): + + if xo_color is None: + xo_color = profile.get_color() + + button = self._notif_by_message.get(corner, None) + if button is None: + button = NotificationButton(_DEFAULT_ICON, xo_color) + button.show() + self._add_message_button(button, corner) + self._notif_by_message[corner] = button + + palette = button.get_palette() + if palette is None: + palette = HistoryPalette() + palette.set_group_id('frame') + palette.connect('clear-messages', self.remove_message, corner) + palette.connect('notice-messages', button.stop_pulsing) + button.set_palette(palette) + + button.start_pulsing() + + palette.push_message(body, summary, icon_name, xo_color) + self._launch_notification_icon(_DEFAULT_ICON, xo_color, corner, duration) + + def remove_message(self, palette, corner): + if corner not in self._notif_by_message: + logging.debug('Button %s is not active', str(corner)) + return + + button = self._notif_by_message[corner] + self._remove_message_button(button, corner) + del self._notif_by_message[corner] + def __notification_received_cb(self, **kwargs): - logging.debug('__notification_received_cb') - icon = NotificationIcon() + logging.debug('__notification_received_cb %r', kwargs) hints = kwargs['hints'] - icon_file_name = hints.get('x-sugar-icon-file-name', '') - if icon_file_name: - icon.props.icon_filename = icon_file_name - else: - icon.props.icon_name = 'application-octet-stream' + icon_name = hints.get('x-sugar-icon-file-name', '') + if not icon_name: + icon_name = _DEFAULT_ICON icon_colors = hints.get('x-sugar-icon-colors', '') if not icon_colors: icon_colors = profile.get_color() - icon.props.xo_color = icon_colors duration = kwargs.get('expire_timeout', -1) if duration == -1: duration = _NOTIFICATION_DURATION - self.add_notification(icon, Gtk.CornerType.TOP_RIGHT, duration) + category = hints.get('category', '') + if category == 'device': + position = Gtk.CornerType.BOTTOM_RIGHT + elif category == 'presence': + position = Gtk.CornerType.TOP_RIGHT + else: + position = Gtk.CornerType.TOP_LEFT + + summary = kwargs.get('summary', '') + body = kwargs.get('body', '') + + if summary or body: + self.add_message(body, summary, icon_name, + icon_colors, position, duration) + else: + self._launch_notification_icon(icon_name, icon_colors, + position, duration) def __notification_cancelled_cb(self, **kwargs): # Do nothing for now. Our notification UI is so simple, there's no |