diff src/cagou/core/menu.py @ 51:3f8599d9a766

core: menus first draft: - menus are handled. Global menus are shown above notification for the moment, but may be displayed differently depending on plateform (e.g. using a button on mobile plateforms) - menu are displayed after profile is connected - backends menus are displayed but not working yet - help/about menu has been added.
author Goffi <goffi@goffi.org>
date Sun, 11 Sep 2016 12:15:41 +0200
parents
children 65775152aac1
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cagou/core/menu.py	Sun Sep 11 12:15:41 2016 +0200
@@ -0,0 +1,165 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Cagou: desktop/mobile frontend for Salut à Toi XMPP client
+# Copyright (C) 2016 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+from sat.core.i18n import _
+from sat.core import log as logging
+log = logging.getLogger(__name__)
+from cagou.core.constants import Const as C
+from kivy.uix.scrollview import ScrollView
+from kivy.uix.gridlayout import GridLayout
+from kivy.uix.widget import Widget
+from kivy.uix.label import Label
+from kivy.uix.button import Button
+from kivy.uix.popup import Popup
+from kivy.uix.dropdown import DropDown
+from kivy import properties
+from sat_frontends.quick_frontend import quick_menus
+from cagou import G
+import webbrowser
+
+ABOUT_TITLE = _(u"About {}".format(C.APP_NAME))
+ABOUT_CONTENT = _(u"""Cagou (Salut à Toi) v{}
+
+Cagou is a libre communication tool based on libre standard XMPP.
+
+Cagou is part of the "Salut à Toi" project
+more informations at [color=5500ff][ref=website]salut-a-toi.org[/ref][/color]
+""").format(C.APP_VERSION)
+
+
+class AboutContent(Label):
+
+    def on_ref_press(self, value):
+        if value == "website":
+            webbrowser.open("https://salut-a-toi.org")
+
+
+class AboutPopup(Popup):
+
+    def on_touch_down(self, touch):
+        if self.collide_point(*touch.pos):
+            self.dismiss()
+        return super(AboutPopup, self).on_touch_down(touch)
+
+
+class MenuItem(Button):
+    item = properties.ObjectProperty()
+
+    def on_item(self, instance, item):
+        self.text = item.name
+
+    def on_release(self):
+        try:
+            self.parent.parent.dismiss()
+        except AttributeError:
+            pass
+        selected = G.host.selected_widget
+        profile = None
+        if selected is not None:
+            try:
+                profile = selected.profile
+            except AttributeError:
+                pass
+
+        if profile is None:
+            try:
+                profile = list(selected.profiles)[0]
+            except (AttributeError, IndexError):
+                try:
+                    profile = list(G.host.profiles)[0]
+                except IndexError:
+                    log.warning(u"Can't find profile")
+
+        self.item.call(selected, profile)
+
+
+class MenuSeparator(Widget):
+    pass
+
+
+class MenuContainer(Button):
+
+    def __init__(self, **kwargs):
+        super(MenuContainer, self).__init__(**kwargs)
+        self.dropdown = DropDown(auto_width=False, size_hint_x=None, width=400)
+
+    def on_release(self):
+        self.dropdown.open(self)
+
+    def add_widget(self, widget):
+        widget.size_hint_y = None
+        self.dropdown.add_widget(widget)
+
+
+class MenusWidget(ScrollView):
+
+    def __init__(self, **kwargs):
+        super(MenusWidget, self).__init__(**kwargs)
+        self._grid = GridLayout(rows=1, size_hint=(None, 1))
+        self._grid.width = self._grid.minimum_width
+        super(MenusWidget, self).add_widget(self._grid)
+
+    def add_widget(self, widget):
+        self._grid.add_widget(widget)
+
+    def clear_widgets(self, children=None):
+        self._grid.clear_widgets(children)
+
+    def update(self, type_, caller=None):
+        """Method to call when menus have changed
+
+        @param type_(unicode): menu type like in sat.core.sat_main.importMenu
+        @param caller(Widget): instance linked to the menus
+        """
+        self.menus_container = G.host.menus.getMainContainer(type_)
+        self.createMenus(caller)
+
+    def _buildMenus(self, container, caller=None):
+        """Recursively build menus of the container
+
+        @param container(quick_menus.MenuContainer): menu container
+        @param caller(Widget): instance linked to the menus
+        """
+        if caller is None:
+            caller = self
+        for child in container.getActiveMenus():
+            if isinstance(child, quick_menus.MenuContainer):
+                menu_container = MenuContainer()
+                menu_container.text = child.name
+                caller.add_widget(menu_container)
+                self._buildMenus(child, caller=menu_container)
+            elif isinstance(child, quick_menus.MenuSeparator):
+                wid = MenuSeparator()
+                caller.add_widget(wid)
+            elif isinstance(child, quick_menus.MenuItem):
+                wid = MenuItem(item=child)
+                caller.add_widget(wid)
+            else:
+                log.error(u"Unknown child type: {}".format(child))
+
+    def createMenus(self, caller):
+        self.clear_widgets()
+        self._buildMenus(self.menus_container, caller)
+
+    def onAbout(self):
+        about = AboutPopup()
+        about.title = ABOUT_TITLE
+        about.content = AboutContent(text=ABOUT_CONTENT, markup=True)
+        about.open()