Implement popup menu for friends
This commit is contained in:
parent
8f6baf6239
commit
fe69dec4ad
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user