view src/cagou/core/widgets_handler.py @ 35:20b04c58868f

chat: header_input text is reset when widget is changed due to input
author Goffi <goffi@goffi.org>
date Sun, 28 Aug 2016 14:59:49 +0200
parents 02acbb297a61
children 9f45098289cc
line wrap: on
line source

#!/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 import log as logging
log = logging.getLogger(__name__)
from sat_frontends.quick_frontend import quick_widgets
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy import properties
from cagou import G


NEW_WIDGET_DIST = 10
REMOVE_WIDGET_DIST = NEW_WIDGET_DIST


class WHSplitter(Button):
    horizontal=properties.BooleanProperty(True)
    thickness=properties.NumericProperty(15)
    split_move = None # we handle one split at a time, so we use a class attribute

    def __init__(self, handler, **kwargs):
        super(WHSplitter, self).__init__(**kwargs)
        self.handler = handler

    def getPos(self, touch):
        if self.horizontal:
            relative_y = self.handler.to_local(*touch.pos, relative=True)[1]
            return self.handler.height - relative_y
        else:
            return touch.x

    def on_touch_move(self, touch):
        if self.split_move is None and self.collide_point(*touch.opos):
            WHSplitter.split_move = self

        if self.split_move is self:
            pos = self.getPos(touch)
            if pos > NEW_WIDGET_DIST:
                # we are above minimal distance, we resize the widget
                self.handler.setWidgetSize(self.horizontal, pos)

    def on_touch_up(self, touch):
        if self.split_move is self:
            pos = self.getPos(touch)
            if pos <= REMOVE_WIDGET_DIST:
                # if we go under minimal distance, the widget is not wanted anymore
                self.handler.removeWidget(self.horizontal)
            WHSplitter.split_move=None
        return super(WHSplitter, self).on_touch_up(touch)


class WidgetsHandler(BoxLayout):

    def __init__(self, wid=None, **kw):
        if wid is None:
            wid=self.default_widget
        self.vert_wid = self.hor_wid = None
        BoxLayout.__init__(self, orientation="vertical", **kw)
        self.blh = BoxLayout(orientation="horizontal")
        self.blv = BoxLayout(orientation="vertical")
        self.blv.add_widget(WHSplitter(self))
        self.blv.add_widget(wid)
        self.blh.add_widget(WHSplitter(self, horizontal=False))
        self.blh.add_widget(self.blv)
        self.add_widget(self.blh)

    @property
    def default_widget(self):
        return G.host.default_wid['factory'](G.host.default_wid, None, None)

    def removeWidget(self, vertical):
        if vertical and self.vert_wid is not None:
            self.remove_widget(self.vert_wid)
            self.vert_wid.onDelete()
            self.vert_wid = None
        elif self.hor_wid is not None:
            self.blh.remove_widget(self.hor_wid)
            self.hor_wid.onDelete()
            self.hor_wid = None

    def setWidgetSize(self, vertical, size):
        if vertical:
            if self.vert_wid is None:
                self.vert_wid = WidgetsHandler(self.default_widget, size_hint=(1, None))
                self.add_widget(self.vert_wid, len(self.children))
            self.vert_wid.height=size
        else:
            if self.hor_wid is None:
                self.hor_wid = WidgetsHandler(self.default_widget, size_hint=(None, 1))
                self.blh.add_widget(self.hor_wid, len(self.blh.children))
            self.hor_wid.width=size

    def onDelete(self):
        # when this handler is deleted, we need to delete the holded CagouWidget
        cagou_widget = self.children[0].children[0].children[0]
        if isinstance(cagou_widget, quick_widgets.QuickWidget):
            G.host.widgets.deleteWidget(cagou_widget)