Convert to an ugly Hippo menu

This commit is contained in:
Dan Williams 2006-10-29 22:42:51 -05:00
parent 4bf76960a0
commit 72832e0174
3 changed files with 191 additions and 45 deletions

View File

@ -2,7 +2,8 @@ sugardir = $(pkgdatadir)/services/nm
sugar_PYTHON = \ sugar_PYTHON = \
__init__.py \ __init__.py \
nmclient.py \ nmclient.py \
nminfo.py nminfo.py \
bubble.py
bin_SCRIPTS = sugar-nm-applet bin_SCRIPTS = sugar-nm-applet

85
services/nm/bubble.py Normal file
View File

@ -0,0 +1,85 @@
# Copyright (C) 2006, 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.
import math
import gobject
import gtk
import hippo
class Bubble(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'NetworkBubble'
__gproperties__ = {
'color' : (object, None, None,
gobject.PARAM_READWRITE),
'percent' : (object, None, None,
gobject.PARAM_READWRITE),
}
def __init__(self, **kwargs):
self._color = None
self._percent = 0
self._radius = 8
hippo.CanvasBox.__init__(self, **kwargs)
def do_set_property(self, pspec, value):
if pspec.name == 'color':
self._color = value
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'percent':
self._percent = value
self.emit_paint_needed(0, 0, -1, -1)
def do_get_property(self, pspec):
if pspec.name == 'color':
return self._color
elif pspec.name == 'percent':
return self._percent
def _string_to_rgb(self, color_string):
col = gtk.gdk.color_parse(color_string)
return (col.red / 65535.0, col.green / 65535.0, col.blue / 65535.0)
def do_paint_below_children(self, cr, damaged_box):
[width, height] = self.get_allocation()
line_width = 3.0
x = line_width
y = line_width
width -= line_width * 2
height -= line_width * 2
cr.move_to(x + self._radius, y);
cr.arc(x + width - self._radius, y + self._radius,
self._radius, math.pi * 1.5, math.pi * 2);
cr.arc(x + width - self._radius, x + height - self._radius,
self._radius, 0, math.pi * 0.5);
cr.arc(x + self._radius, y + height - self._radius,
self._radius, math.pi * 0.5, math.pi);
cr.arc(x + self._radius, y + self._radius, self._radius,
math.pi, math.pi * 1.5);
color = self._string_to_rgb(self._color.get_fill_color())
cr.set_source_rgb(*color)
cr.fill_preserve();
color = self._string_to_rgb(self._color.get_stroke_color())
cr.set_source_rgb(*color)
cr.set_line_width(line_width)
cr.stroke();

View File

@ -22,9 +22,15 @@ import dbus.decorators
import gobject import gobject
import gtk import gtk
import logging import logging
from sugar.graphics.menu import Menu
from gettext import gettext as _
import os import os
from gettext import gettext as _
import hippo
from sugar.graphics.menu import Menu
from sugar.graphics import style
from sugar.graphics.iconcolor import IconColor
from sugar.graphics.timeline import Timeline
from bubble import Bubble
import nminfo import nminfo
@ -106,18 +112,13 @@ class Network(gobject.GObject):
return self._valid return self._valid
def add_to_menu(self, menu): def add_to_menu(self, menu):
item = gtk.CheckMenuItem()
strength = self._strength strength = self._strength
if strength > 100: if strength > 100:
strength = 100 strength = 100
elif strength < 0: elif strength < 0:
strength = 0 strength = 0
label_str = "%s (%d%%)" % (self._ssid, strength) item = NetworkMenuItem(text=self._ssid, percent=strength)
label = gtk.Label(label_str) menu.add_item(item)
label.set_alignment(0.0, 0.5)
item.add(label)
item.show_all()
menu.add(item)
class Device(gobject.GObject): class Device(gobject.GObject):
@ -188,14 +189,8 @@ class Device(gobject.GObject):
del self._networks[net_op] del self._networks[net_op]
def _add_to_menu_wired(self, menu): def _add_to_menu_wired(self, menu):
item = gtk.CheckMenuItem() item = NetworkMenuItem(_("Wired Network"))
label = gtk.Label(_("Wired Network")) menu.add_item(item)
label.set_alignment(0.0, 0.5);
item.add(label)
if self._caps & NM_DEVICE_CAP_CARRIER_DETECT:
item.set_sensitive(self._link)
item.show_all()
menu.add(item)
def _add_to_menu_wireless(self, menu): def _add_to_menu_wireless(self, menu):
for net in self._networks.values(): for net in self._networks.values():
@ -270,22 +265,42 @@ class Device(gobject.GObject):
def set_carrier(self, on): def set_carrier(self, on):
self._link = on self._link = on
class ActivityMenu(Menu):
def __init__(self, activity_host):
Menu.__init__(self, activity_host.get_title())
if not activity_host.get_shared(): class NetworkMenuItem(Bubble):
self._add_mesh_action() def __init__(self, text, percent=0):
color = IconColor("#646464,#646464")
Bubble.__init__(self, color=color, percent=percent)
self._add_close_action() text_item = hippo.CanvasText(text=text)
style.apply_stylesheet(text_item, 'menu.Text')
self.append(text_item)
def _add_mesh_action(self):
icon = CanvasIcon(icon_name='stock-share-mesh')
self.add_action(icon, ActivityMenu.ACTION_SHARE)
def _add_close_action(self): class NetworkMenu(gtk.Window):
icon = CanvasIcon(icon_name='stock-close') __gsignals__ = {
self.add_action(icon, ActivityMenu.ACTION_CLOSE) 'action': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int])),
}
def __init__(self):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
canvas = hippo.Canvas()
self.add(canvas)
canvas.show()
self._root = hippo.CanvasBox()
style.apply_stylesheet(self._root, 'menu')
canvas.set_root(self._root)
def add_separator(self):
separator = hippo.CanvasBox()
style.apply_stylesheet(separator, 'menu.Separator')
self._root.append(separator)
def add_item(self, item):
self._root.append(item)
NM_STATE_UNKNOWN = 0 NM_STATE_UNKNOWN = 0
@ -304,7 +319,6 @@ ICON_WIRELESS_81_100 = "stock-net-wireless-81-100"
class NMClientApp: class NMClientApp:
def __init__(self): def __init__(self):
self.menu = None
self.nminfo = None self.nminfo = None
self._nm_present = False self._nm_present = False
self._nm_state = NM_STATE_UNKNOWN self._nm_state = NM_STATE_UNKNOWN
@ -313,6 +327,13 @@ class NMClientApp:
self._active_device = None self._active_device = None
self._devices = {} self._devices = {}
self._menu = None
self._hover_menu = False
self._timeline = Timeline(self)
self._timeline.add_tag('popup', 6, 6)
self._timeline.add_tag('before_popdown', 7, 7)
self._timeline.add_tag('popdown', 8, 8)
self._icons = {} self._icons = {}
self._cur_icon = None self._cur_icon = None
@ -400,24 +421,61 @@ class NMClientApp:
def _setup_trayicon(self): def _setup_trayicon(self):
pixbuf = self._get_icon() pixbuf = self._get_icon()
self._trayicon = gtk.status_icon_new_from_pixbuf(pixbuf) self._trayicon = gtk.status_icon_new_from_pixbuf(pixbuf)
self._trayicon.connect("popup_menu", self._popup) self._trayicon.connect("popup_menu", self._status_icon_clicked)
self._trayicon.connect("activate", self._popup) self._trayicon.connect("activate", self._status_icon_clicked)
self._schedule_icon_update() self._schedule_icon_update()
def _popup(self, status, button=0, time=None): def _status_icon_clicked(self, button=0, time=None):
def menu_pos(menu): self._timeline.play(None, 'popup')
return gtk.status_icon_position_menu(menu, self._trayicon)
if time is None: def _get_menu_position(self, menu, item):
time = gtk.get_current_event_time() (screen, rect, orientation) = item.get_geometry()
if self.menu: [item_x, item_y, item_w, item_h] = rect
del self.menu [menu_w, menu_h] = menu.size_request()
self.menu = self._construct_new_menu()
self.menu.popup(None, None, menu_pos, button, time)
self.menu.show_all()
def _construct_new_menu(self): x = item_x + item_w - menu_w
menu = gtk.Menu() y = item_y + item_h
x = min(x, screen.get_width() - menu_w)
x = max(0, x)
y = min(y, screen.get_height() - menu_h)
y = max(0, y)
return (x, y)
def do_popup(self, current, n_frames):
if self._menu:
self._popdown()
return
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)
(x, y) = self._get_menu_position(self._menu, self._trayicon)
self._menu.move(x, y)
self._menu.show_all()
def do_popdown(self, current, frame):
if self._menu:
self._menu.destroy()
self._menu = None
def _popdown(self):
self._timeline.play('popdown', 'popdown')
def _menu_enter_notify_event_cb(self, widget, event):
self._hover_menu = True
self._timeline.play('popup', 'popup')
def _menu_leave_notify_event_cb(self, widget, event):
self._hover_menu = False
self._popdown()
def _create_menu(self):
menu = NetworkMenu()
# Wired devices first # Wired devices first
for dev in self._devices.values(): for dev in self._devices.values():
@ -427,6 +485,8 @@ class NMClientApp:
continue continue
dev.add_to_menu(menu) dev.add_to_menu(menu)
menu.add_separator()
# Wireless devices second # Wireless devices second
for dev in self._devices.values(): for dev in self._devices.values():
if not dev.is_valid(): if not dev.is_valid():