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 goocanvas
from sugar.canvas.CanvasBox import CanvasBox
from sugar.canvas.IconItem import IconItem
class BuddyPopup(gtk.Window):
def __init__(self, grid)
def __init__(self, shell, grid, friend):
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 home.IconLayout import IconLayout
from home.MyIcon import MyIcon
from BuddyPopup import BuddyPopup
from sugar.canvas.Grid import Grid
class FriendIcon(IconItem):
def __init__(self, friend):
@ -31,19 +33,45 @@ class FriendsGroup(goocanvas.Group):
for friend in self._friends:
self.add_friend(friend)
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)
friends.connect('friend-added', self._friend_added_cb)
def add_friend(self, 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._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)
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:
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):
if isinstance(component, gtk.Window):
@ -26,12 +31,16 @@ class Grid:
matrix.translate(x * scale, y * scale)
item.set_transform(matrix)
# FIXME This is really hacky
if width > 0 and height > 0:
try:
item.props.width = width * scale
item.props.height = height * scale
except:
item.props.size = width * scale
try:
item.props.size = width * scale
except:
pass
def _layout_canvas(self, canvas, x, y, width, height):
scale = 1200 / Grid.COLS

View File

@ -169,6 +169,10 @@ class IconItem(goocanvas.ItemSimple, goocanvas.Item):
__gsignals__ = {
'clicked': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
'popup': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int, int, int, int])),
'popdown': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
}
__gproperties__ = {
@ -227,8 +231,23 @@ class IconItem(goocanvas.ItemSimple, goocanvas.Item):
def do_create_view(self, canvas, parent_view):
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
def __button_press_cb(self, view, target, event):
def _button_press_cb(self, view, target, event):
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)