diff browser_side/panels.py @ 279:2d6bd975a72d

browser_side: set your own presence status and display those of others
author souliane <souliane@mailoo.org>
date Sat, 23 Nov 2013 14:46:03 +0100
parents aebb96bfa8d1
children ae3ec654836d
line wrap: on
line diff
--- a/browser_side/panels.py	Fri Nov 22 21:43:08 2013 +0100
+++ b/browser_side/panels.py	Sat Nov 23 14:46:03 2013 +0100
@@ -37,13 +37,14 @@
 from pyjamas.ui.KeyboardListener import KEY_ENTER, KEY_UP, KEY_DOWN
 from pyjamas.ui.Event import BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT
 from pyjamas.ui.MouseListener import MouseHandler
+from pyjamas.ui.ListBox import ListBox
 from pyjamas.Timer import Timer
 from pyjamas import DOM
 from card_game import CardPanel
 from radiocol import RadioColPanel
 from menu import Menu
 from jid import JID
-from tools import html_sanitize, addURLToText, inlineRoot
+from tools import html_sanitize, addURLToText, inlineRoot, setPresenceStyle
 from datetime import datetime
 from time import time
 import dialog
@@ -53,6 +54,11 @@
 from pyjamas import Window
 from __pyjamas__ import doc
 from sat_frontends.tools.games import SYMBOLS
+from sat_frontends import constants
+from pyjamas.ui.ContextMenuPopupPanel import ContextMenuPopupPanel
+
+
+const = constants.Const  # to directly import 'const' doesn't work
 
 
 class UniBoxPanel(HorizontalPanel):
@@ -587,14 +593,12 @@
         return False
 
 
-class StatusPanel(HTMLPanel, ClickHandler):
+class StatusPanel(HTMLPanel):
     def __init__(self, host, status=''):
         self.host = host
         self.status = status or '&nbsp;'
         HTMLPanel.__init__(self, self.__getContent())
         self.setStyleName('statusPanel')
-        ClickHandler.__init__(self)
-        self.addClickListener(self)
 
     def __getContent(self):
         return "<span class='status'>%(status)s</span>" % {'status': html_sanitize(self.status)}
@@ -603,6 +607,49 @@
         self.status = new_status or '&nbsp;'
         self.setHTML(self.__getContent())
 
+
+class PresenceStatusPanel(HorizontalPanel, ClickHandler):
+
+    def __init__(self, host, presence="", status=""):
+        self.host = host
+        HorizontalPanel.__init__(self, Width='100%')
+        self.presence_button = Label(u"◉")
+        self.presence_button.setStyleName("presence-button")
+        self.status_panel = StatusPanel(host, status=status)
+        self.setPresence(presence)
+        entries = {}
+        for value in const.PRESENCE.keys():
+            entries.update({const.PRESENCE[value]: {"value": value}})
+
+        def callback(sender, key):
+            self.setPresence(entries[key]["value"])  # order matters
+            self.host.send([("STATUS", None)], self.status_panel.status)
+
+        self.presence_list = PopupMenuPanel(entries, callback=callback, style={"menu": "gwt-ListBox"})
+        self.presence_list.registerClickSender(self.presence_button)
+
+        panel = HorizontalPanel()
+        panel.add(self.presence_button)
+        panel.add(self.status_panel)
+        panel.setStyleName("marginAuto")
+        self.add(panel)
+
+        ClickHandler.__init__(self)
+        self.addClickListener(self)
+
+    def getPresence(self):
+        return self.presence
+
+    def setPresence(self, presence):
+        status = self.status_panel.status
+        if not status.strip() or status == "&nbsp;" or status == const.PRESENCE[self.presence]:
+            self.changeStatus(const.PRESENCE[presence])
+        self.presence = presence
+        setPresenceStyle(self.presence_button, self.presence)
+
+    def changeStatus(self, new_status):
+        self.status_panel.changeStatus(new_status)
+
     def onClick(self, sender):
         # As status is the default target of uniBar, we don't want to select anything if click on it
         self.host.setSelected(None)
@@ -978,7 +1025,7 @@
     certain items and also easily define their callbacks. The menu can be
     bound to any of the mouse button (left, middle, right).
     """
-    def __init__(self, entries, hide=None, callback=None, vertical=True, item_style="popupMenuItem", menu_style=None, **kwargs):
+    def __init__(self, entries, hide=None, callback=None, vertical=True, style={}, **kwargs):
         """
         @param entries: a dict of dicts, where each sub-dict is representing
         one menu item: the sub-dict key can be used as the item text and
@@ -987,7 +1034,7 @@
         more complicated stuff or overwrite the common methods.
         @param hide: function  with 2 args: widget, key as string and
         returns True if that item should be hidden from the context menu.
-        @param callback: function with 2 args: widget, key as string
+        @param callback: function with 2 args: sender, key as string
         @param vertical: True or False, to set the direction
         @param item_style: alternative CSS class for the menu items
         @param menu_style: supplementary CSS class for the sender widget
@@ -997,8 +1044,8 @@
         self._hide = hide
         self._callback = callback
         self.vertical = vertical
-        self.item_style = item_style
-        self.menu_style = menu_style
+        self.style = {"selected": None, "menu": "recipientTypeMenu", "item": "popupMenuItem"}
+        self.style.update(style)
         self._senders = {}
 
     def _show(self, sender):
@@ -1006,7 +1053,7 @@
         @param sender: the widget that has been clicked
         """
         menu = VerticalPanel() if self.vertical is True else HorizontalPanel()
-        menu.setStyleName("recipientTypeMenu")
+        menu.setStyleName(self.style["menu"])
 
         def button_cb(item):
             """You can not put that method in the loop and rely
@@ -1026,7 +1073,7 @@
             title = entry["title"] if "title" in entry.keys() else _key
             item = Button(title, button_cb)
             item.key = _key
-            item.setStyleName(self.item_style)
+            item.setStyleName(self.style["item"])
             item.setTitle(entry["desc"] if "desc" in entry.keys() else title)
             menu.add(item)
         if len(menu.getChildren()) == 0:
@@ -1040,12 +1087,12 @@
             y = sender.getAbsoluteTop() + sender.getOffsetHeight()
         self.setPopupPosition(x, y)
         self.show()
-        if self.menu_style:
-            sender.addStyleDependentName(self.menu_style)
+        if self.style["selected"]:
+            sender.addStyleDependentName(self.style["selected"])
 
         def _onHide(popup):
-            if hasattr(self, "menu_style") and self.menu_style is not None:
-                sender.removeStyleDependentName(self.menu_style)
+            if self.style["selected"]:
+                sender.removeStyleDependentName(self.style["selected"])
             return PopupPanel.onHideImpl(self, popup)
 
         self.onHideImpl = _onHide