Implement popup menu for friends

This commit is contained in:
Marco Pesenti Gritti 2006-09-14 13:03:11 +02:00
parent 8f6baf6239
commit fe69dec4ad
4 changed files with 158 additions and 15 deletions

View File

@ -1,10 +1,97 @@
import gtk import gtk
import goocanvas
from sugar.canvas.CanvasBox import CanvasBox from sugar.canvas.CanvasBox import CanvasBox
from sugar.canvas.IconItem import IconItem
class BuddyPopup(gtk.Window): class BuddyPopup(gtk.Window):
def __init__(self, grid) def __init__(self, shell, grid, friend):
gtk.Window.__init__(self, gtk.WINDOW_POPUP) gtk.Window.__init__(self, gtk.WINDOW_POPUP)
box = CanvasBox(grid) self._shell = shell
self._friend = friend
self._hover = False
self._popdown_on_leave = False
self._width = 20
self._height = 12
canvas = goocanvas.CanvasView()
self.add(canvas)
canvas.show()
grid.set_constraints(canvas, 0, 0, self._width, self._height)
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
color = friend.get_color()
rect = goocanvas.Rect(fill_color=color.get_fill_color(),
stroke_color=color.get_stroke_color(),
line_width=3)
grid.set_constraints(rect, 0, 0, self._width, self._height)
root.add_child(rect)
text = goocanvas.Text(text=friend.get_name(), font="Sans bold 14",
fill_color='black', anchor = gtk.ANCHOR_SW)
grid.set_constraints(text, 1, 2, self._width, self._height)
root.add_child(text)
separator = goocanvas.Path(data='M 15 0 L 185 0', line_width=3,
fill_color='black')
grid.set_constraints(separator, 0, 3)
root.add_child(separator)
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
grid.set_constraints(box, 0, 3)
icon = IconItem(icon_name='stock-make-friend')
icon.connect('clicked', self._make_friend_clicked_cb)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-chat')
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-invite')
icon.connect('clicked', self._invite_clicked_cb)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
root.add_child(box)
canvas.set_model(model)
self.connect('enter-notify-event', self._enter_notify_event_cb)
self.connect('leave-notify-event', self._leave_notify_event_cb)
def _invite_clicked_cb(self, icon):
activity = self._shell.get_current_activity()
buddy = self._friend.get_buddy()
if buddy != None:
activity.invite(buddy)
else:
print 'Friend not online'
def _make_friend_clicked_cb(self, icon):
pass
def _enter_notify_event_cb(self, widget, event):
self._hover = True
def _leave_notify_event_cb(self, widget, event):
self._hover = False
if self._popdown_on_leave:
self.popdown()
def popdown(self):
if not self._hover:
self.destroy()
else:
self._popdown_on_leave = True
def get_width(self):
return self._width
def get_height(self):
return self._height

View File

@ -5,6 +5,8 @@ import goocanvas
from sugar.canvas.IconItem import IconItem from sugar.canvas.IconItem import IconItem
from home.IconLayout import IconLayout from home.IconLayout import IconLayout
from home.MyIcon import MyIcon from home.MyIcon import MyIcon
from BuddyPopup import BuddyPopup
from sugar.canvas.Grid import Grid
class FriendIcon(IconItem): class FriendIcon(IconItem):
def __init__(self, friend): def __init__(self, friend):
@ -31,19 +33,45 @@ class FriendsGroup(goocanvas.Group):
for friend in self._friends: for friend in self._friends:
self.add_friend(friend) self.add_friend(friend)
friends.connect('friend-added', self.__friend_added_cb) friends.connect('friend-added', self._friend_added_cb)
def __friend_clicked_cb(self, icon):
activity = self._shell.get_current_activity()
buddy = icon.get_friend().get_buddy()
if buddy != None:
activity.invite(buddy)
def add_friend(self, friend): def add_friend(self, friend):
icon = FriendIcon(friend) icon = FriendIcon(friend)
icon.connect('clicked', self.__friend_clicked_cb)
icon.connect('popup', self._friend_popup_cb)
icon.connect('popdown', self._friend_popdown_cb)
self.add_child(icon) self.add_child(icon)
self._icon_layout.add_icon(icon) self._icon_layout.add_icon(icon)
def __friend_added_cb(self, data_model, friend): def _friend_added_cb(self, data_model, friend):
self.add_friend(friend) self.add_friend(friend)
def _friend_popup_cb(self, icon, x1, y1, x2, y2):
grid = Grid()
self._popup = BuddyPopup(self._shell, grid, icon.get_friend())
[grid_x1, grid_y1] = grid.convert_from_screen(x1, y1)
[grid_x2, grid_y2] = grid.convert_from_screen(x2, y2)
if grid_x2 + self._popup.get_width() + 1 > Grid.ROWS:
grid_x = grid_x1 - self._popup.get_width() + 1
else:
grid_x = grid_x2 - 1
grid_y = grid_y1
if grid_y < 0:
grid_y = 0
if grid_y + self._popup.get_width() > Grid.ROWS:
grid_y = Grid.ROWS - self._popup.get_width()
grid.set_constraints(self._popup, grid_x, grid_y,
self._popup.get_width(), self._popup.get_height())
self._popup.show()
def _friend_popdown_cb(self, friend):
self._popup.popdown()
self._popup = None

View File

@ -4,6 +4,11 @@ import cairo
class Grid: class Grid:
COLS = 80.0 COLS = 80.0
ROWS = 60.0
def convert_from_screen(self, x, y):
factor = Grid.COLS / gtk.gdk.screen_width()
return [int(x * factor), int(y * factor)]
def set_constraints(self, component, x, y, width=-1, height=-1): def set_constraints(self, component, x, y, width=-1, height=-1):
if isinstance(component, gtk.Window): if isinstance(component, gtk.Window):
@ -26,12 +31,16 @@ class Grid:
matrix.translate(x * scale, y * scale) matrix.translate(x * scale, y * scale)
item.set_transform(matrix) item.set_transform(matrix)
# FIXME This is really hacky
if width > 0 and height > 0: if width > 0 and height > 0:
try: try:
item.props.width = width * scale item.props.width = width * scale
item.props.height = height * scale item.props.height = height * scale
except: except:
try:
item.props.size = width * scale item.props.size = width * scale
except:
pass
def _layout_canvas(self, canvas, x, y, width, height): def _layout_canvas(self, canvas, x, y, width, height):
scale = 1200 / Grid.COLS scale = 1200 / Grid.COLS

View File

@ -169,6 +169,10 @@ class IconItem(goocanvas.ItemSimple, goocanvas.Item):
__gsignals__ = { __gsignals__ = {
'clicked': (gobject.SIGNAL_RUN_FIRST, 'clicked': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])), gobject.TYPE_NONE, ([])),
'popup': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int, int, int, int])),
'popdown': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
} }
__gproperties__ = { __gproperties__ = {
@ -227,8 +231,23 @@ class IconItem(goocanvas.ItemSimple, goocanvas.Item):
def do_create_view(self, canvas, parent_view): def do_create_view(self, canvas, parent_view):
view = IconView(canvas, parent_view, self) view = IconView(canvas, parent_view, self)
view.connect('button-press-event', self.__button_press_cb) view.connect('button-press-event', self._button_press_cb)
view.connect('enter-notify-event', self._enter_notify_event_cb, canvas)
view.connect('leave-notify-event', self._leave_notify_event_cb)
return view return view
def __button_press_cb(self, view, target, event): def _button_press_cb(self, view, target, event):
self.emit('clicked') self.emit('clicked')
def _enter_notify_event_cb(self, view, target, event, canvas):
[x1, y1] = canvas.convert_to_pixels(view.get_bounds().x1,
view.get_bounds().y1)
[x2, y2] = canvas.convert_to_pixels(view.get_bounds().x2,
view.get_bounds().y2)
self.emit('popup', int(x1), int(y1), int(x2), int(y2))
def _popdown(self):
self.emit('popdown')
def _leave_notify_event_cb(self, view, target, event):
gobject.timeout_add(1000, self._popdown)