# HG changeset patch # User Goffi # Date 1473588941 -7200 # Node ID 3f8599d9a76604fc5233d7fb3c490ffa7fb584c1 # Parent c45d6e9ec73111289da8d1c0b45b83c565acafd2 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. diff -r c45d6e9ec731 -r 3f8599d9a766 src/cagou/core/cagou_main.py --- a/src/cagou/core/cagou_main.py Sat Sep 10 18:01:32 2016 +0200 +++ b/src/cagou/core/cagou_main.py Sun Sep 11 12:15:41 2016 +0200 @@ -48,6 +48,7 @@ from cagou_widget import CagouWidget from . import widgets_handler from .common import IconButton +from .menu import MenusWidget from importlib import import_module import os.path import glob @@ -138,10 +139,12 @@ def __init__(self, main_widget): super(CagouRootWidget, self).__init__(orientation=("vertical")) + # general menus + self.menus_widget = MenusWidget() + self.add_widget(self.menus_widget) # header self._head_widget = RootHeadWidget() self.add_widget(self._head_widget) - # body self._manager = ScreenManager() # main widgets @@ -340,7 +343,6 @@ ## widgets handling - def newWidget(self, widget): log.debug(u"new widget created: {}".format(widget)) if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: @@ -413,10 +415,19 @@ w.addTarget(t) return w + ## menus ## + + def _getMenusCb(self, backend_menus): + main_menu = self.app.root.menus_widget + self.menus.addMenus(backend_menus) + self.menus.addMenu(C.MENU_GLOBAL, (_(u"Help"), _(u"About")), callback=main_menu.onAbout) + main_menu.update(C.MENU_GLOBAL) + ## misc ## def plugging_profiles(self): self.app.root.changeWidget(WidgetsHandler()) + self.bridge.getMenus("", C.NO_SECURITY_LIMIT, callback=self._getMenusCb) def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): log.info(u"Profile presence status set to {show}/{status}".format(show=show, status=status)) diff -r c45d6e9ec731 -r 3f8599d9a766 src/cagou/core/cagou_widget.py --- a/src/cagou/core/cagou_widget.py Sat Sep 10 18:01:32 2016 +0200 +++ b/src/cagou/core/cagou_widget.py Sun Sep 11 12:15:41 2016 +0200 @@ -67,3 +67,9 @@ def onHeaderInput(self): log.info(u"header input text entered") + + def on_touch_down(self, touch): + if self.collide_point(*touch.pos): + G.host.selected_widget = self + super(CagouWidget, self).on_touch_down(touch) + diff -r c45d6e9ec731 -r 3f8599d9a766 src/cagou/core/menu.py --- /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 . + + +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() diff -r c45d6e9ec731 -r 3f8599d9a766 src/cagou/kv/menu.kv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cagou/kv/menu.kv Sun Sep 11 12:15:41 2016 +0200 @@ -0,0 +1,43 @@ +# 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 . + +: + size_hint: None, 1 + padding: 10, 0 + width: self.texture_size[0] + height: 30 + +: + size_hint: None, None + width: 30 + +: + size_hint: None, 1 + width: self.texture_size[0] + dp(20) + background_color: 0, 0, 0, 1 + +: + size_hint: 1, None + height: 30 + +: + text_size: self.size + halign: "center" + valign: "middle" + +: + title_align: "center" + size_hint: 0.8, 0.8