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