changeset 510:db3436c85fb1

browser_side: the status menu is now based on GenericMenuBar instead of PopupMenuPanel
author souliane <souliane@mailoo.org>
date Thu, 21 Aug 2014 16:44:39 +0200
parents 35ccb3ff8245
children 8843ae9e92bd
files src/browser/sat_browser/base_menu.py src/browser/sat_browser/base_widget.py src/browser/sat_browser/contact.py src/browser/sat_browser/panels.py
diffstat 4 files changed, 60 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/browser/sat_browser/base_menu.py	Thu Aug 21 16:18:51 2014 +0200
+++ b/src/browser/sat_browser/base_menu.py	Thu Aug 21 16:44:39 2014 +0200
@@ -39,13 +39,14 @@
 class MenuCmd:
     """Return an object with an "execute" method that can be set to a menu item callback"""
 
-    def __init__(self, object_, handler):
+    def __init__(self, object_, handler, data=None):
         self._object = object_
         self._handler = handler
+        self._data = data
 
     def execute(self):
         handler = getattr(self._object, self._handler)
-        handler()
+        handler(self._data) if self._data else handler()
 
 
 class PluginMenuCmd:
@@ -123,14 +124,15 @@
             return cat.getCategories(target_path[-1:]) if cat else None
         return [child for child in self.children if child.menu]
 
-    def addMenuItem(self, path, path_i18n, types, callback=None):
+    def addMenuItem(self, path, path_i18n, types, callback=None, asHTML=False):
         """Recursively add a new node, which could be a category or a leaf node.
 
         @param path (list[str], str): path to the item
         @param path_i18n (list[str], str): internationalized path to the item
         @param types (list[str], str): types of the item and its parents
-        @param menu_cmd (MenuCmd, PluginMenuCmd or GenericMenuBar): instance to
-        execute as a leaf's callback or to popup as a category sub-menu.
+        @param callback (MenuCmd, PluginMenuCmd or GenericMenuBar): instance to
+        execute as a leaf's callback or to popup as a category sub-menu
+        @param asHTML (boolean): True to display the UI item as HTML
         """
         log.info("addMenuItem: %s %s %s %s" % (path, path_i18n, types, callback))
 
@@ -149,7 +151,7 @@
             path.append(None)  # dummy name for a leaf node
 
         parent = self._getOrCreateCategory(path[:-1], path_i18n[:-1], types[:-1], True)
-        return parent.addItem(path_i18n[-1], callback)
+        return parent.addItem(path_i18n[-1], asHTML=asHTML, popup=callback)
 
     def addCategory(self, path, path_i18n, types, menu_bar=None):
         """Recursively add a new category.
@@ -289,8 +291,8 @@
         """
         return [cat.item for cat in self.node.getCategories(parent_path)]
 
-    def addMenuItem(self, path, path_i18n, types, menu_cmd):
-        return self.node.addMenuItem(path, path_i18n, types, menu_cmd).item
+    def addMenuItem(self, path, path_i18n, types, menu_cmd, asHTML=False):
+        return self.node.addMenuItem(path, path_i18n, types, menu_cmd, asHTML).item
 
     def addCategory(self, path, path_i18n, types, menu_bar):
         return self.node.addCategory(path, path_i18n, types, menu_bar).item
--- a/src/browser/sat_browser/base_widget.py	Thu Aug 21 16:18:51 2014 +0200
+++ b/src/browser/sat_browser/base_widget.py	Thu Aug 21 16:44:39 2014 +0200
@@ -169,15 +169,18 @@
 
     ITEM_TPL = "<img src='media/icons/misc/%s.png' />"
 
-    def __init__(self, parent, host, vertical=False):
-        styles = {'menu_bar': 'widgetHeader_buttonGroup'}
-        base_menu.GenericMenuBar.__init__(self, host, vertical=vertical, styles=styles)
+    def __init__(self, parent, host, vertical=False, styles=None):
+        menu_styles = {'menu_bar': 'widgetHeader_buttonGroup'}
+        if styles:
+            menu_styles.update(styles)
+        base_menu.GenericMenuBar.__init__(self, host, vertical=vertical, styles=menu_styles)
 
-        # regroup all the dynamic menu categories in a sub-menu
-        sub_menu = WidgetSubMenuBar(host, vertical=True)
-        parent.addMenus(sub_menu)
-        if len(sub_menu.getCategories()) > 0:
-            self.addMenuItem('', '', 'plugins', sub_menu)
+        if hasattr(parent, 'addMenus'):
+            # regroup all the dynamic menu categories in a sub-menu
+            sub_menu = WidgetSubMenuBar(host, vertical=True)
+            parent.addMenus(sub_menu)
+            if len(sub_menu.getCategories()) > 0:
+                self.addCategory('', '', 'plugins', sub_menu)
 
     @classmethod
     def getCategoryHTML(cls, menu_name_i18n, type_):
--- a/src/browser/sat_browser/contact.py	Thu Aug 21 16:18:51 2014 +0200
+++ b/src/browser/sat_browser/contact.py	Thu Aug 21 16:44:39 2014 +0200
@@ -39,7 +39,18 @@
 import html_tools
 
 
-def setPresenceStyle(widget, presence, base_style="contactLabel"):
+def buildPresenceStyle(presence, base_style=None):
+    """Return the CSS classname to be used for displaying the given presence information.
+    @param presence (str): presence is a value in ('', 'chat', 'away', 'dnd', 'xa')
+    @param base_style (str): base classname
+    @return: str
+    """
+    if not base_style:
+        base_style = "contactLabel"
+    return '%s-%s' % (base_style, presence or 'connected')
+
+
+def setPresenceStyle(widget, presence, base_style=None):
     """
     Set the CSS style of a contact's element according to its presence.
 
@@ -49,7 +60,7 @@
     """
     if not hasattr(widget, 'presence_style'):
         widget.presence_style = None
-    style = '%s-%s' % (base_style, presence or 'connected')
+    style = buildPresenceStyle(presence, base_style)
     if style == widget.presence_style:
         return
     if widget.presence_style is not None:
--- a/src/browser/sat_browser/panels.py	Thu Aug 21 16:18:51 2014 +0200
+++ b/src/browser/sat_browser/panels.py	Thu Aug 21 16:44:39 2014 +0200
@@ -52,6 +52,7 @@
 import jid
 import html_tools
 import base_panels
+import base_menu
 import card_game
 import radiocol
 import menu
@@ -1039,30 +1040,40 @@
         self.display.setHTML(addURLToText(status))
 
 
+class PresenceStatusMenuBar(base_widget.WidgetMenuBar):
+    def __init__(self, parent):
+        styles = {'menu_bar': 'presence-button'}
+        base_widget.WidgetMenuBar.__init__(self, None, parent.host, styles=styles)
+        self.button = self.addCategory(u"◉", u"◉", '')
+        for presence, presence_i18n in C.PRESENCE.items():
+            html = u'<span class="%s">◉</span> %s' % (contact.buildPresenceStyle(presence), presence_i18n)
+            self.addMenuItem([u"◉", presence], [u"◉", html], '', base_menu.MenuCmd(self, 'changePresenceCb', presence), asHTML=True)
+        self.parent_panel = parent
+
+    def changePresenceCb(self, presence):
+        """Callback to notice the backend of a new presence set by the user.
+        @param presence (str): the new presence is a value in ('', 'chat', 'away', 'dnd', 'xa')
+        """
+        self.host.bridge.call('setStatus', None, presence, self.parent_panel.status_panel.status)
+
+    @classmethod
+    def getCategoryHTML(cls, menu_name_i18n, type_):
+        return menu_name_i18n
+
+
 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.menu = PresenceStatusMenuBar(self)
         self.status_panel = StatusPanel(host, status=status)
         self.setPresence(presence)
-        entries = {}
-        for value in C.PRESENCE.keys():
-            entries.update({C.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 = base_panels.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.menu)
         panel.add(self.status_panel)
-        panel.setCellVerticalAlignment(self.presence_button, 'baseline')
+        panel.setCellVerticalAlignment(self.menu, 'baseline')
         panel.setCellVerticalAlignment(self.status_panel, 'baseline')
         panel.setStyleName("marginAuto")
         self.add(panel)
@@ -1082,7 +1093,7 @@
 
     def setPresence(self, presence):
         self._presence = presence
-        contact.setPresenceStyle(self.presence_button, self._presence)
+        contact.setPresenceStyle(self.menu.button, self._presence)
 
     def setStatus(self, status):
         self.status_panel.setContent({'text': status})