aboutsummaryrefslogtreecommitdiffstats
path: root/tagit/dialogues/dialogue.py
blob: bf72a288ecaf1b2aa64a6baf5e7c7a5f2fd319ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""Popup dialogue.

Rougly based on code from https://gist.github.com/kived/742397a80d61e6be225a
by Ryan Pessa. The license is provided in the source folder.

Part of the tagit module.
A copy of the license is provided with the project.
Modifications authored by: Matthias Baumgartner, 2022
"""
# standard imports
import os

# kivy imports
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
import kivy.properties as kp

# exports
__all__ = ('Dialogue', )


## code ##

# Load kv
Builder.load_file(os.path.join(os.path.dirname(__file__), 'dialogue.kv'))

# classes
class Dialogue(Popup):
    """Popup dialogue base class.

    Use like below:

    >>> dlg = Dialogue()
    >>> dlg.bind(on_ok=....)
    >>> dlg.open()

    """

    ok_on_enter = kp.BooleanProperty()

    __events__ = ('on_ok', 'on_cancel')

    def __init__(self, *args, **kwargs):
        super(Dialogue, self).__init__(*args, **kwargs)
        from kivy.core.window import Window
        # assumes that the first widget created controls the keyboard
        #Window.children[-1].request_exclusive_keyboard()
        # Alternatively, you can bind a function (self._on_keyboard) to on_keyboard
        # which returns True. This stops the event from being processed by the main
        # window.
        # However, this still does not keep the 'enter' from 'on_text_validate' from
        # being processed by the main window.
        Window.bind(on_keyboard=self._on_keyboard)
        # By binding to on_key_down, the <enter> key can trigger the ok action.
        # This also prevents the enter event to be processed by the main window,
        # unlike the 'on_text_validate' of TextInput.
        Window.bind(on_key_down=self._key_down)

    def _on_keyboard(self, *args, **kwargs):
        # block events from processing in the main window
        return True

    def _key_down(self, instance, key, scancode, codepoint, modifiers):
        if key == 13 and self.ok_on_enter:
            self.ok()
            return True
        # must not stop other events such that ctrl up/down reach the browser

    def ok(self):
        """User pressed the OK button."""
        self.dispatch('on_ok')
        self.dismiss()

    def cancel(self):
        """User pressed the Cancel button."""
        self.dispatch('on_cancel')
        self.dismiss()

    def on_dismiss(self):
        from kivy.core.window import Window
        # assumes that the first widget created controls the keyboard
        #Window.children[-1].release_exclusive_keyboard()
        Window.unbind(on_keyboard=self._on_keyboard)
        Window.unbind(on_key_down=self._key_down)
        super(Dialogue, self).on_dismiss()

    def on_ok(self):
        """Event prototype."""
        pass

    def on_cancel(self):
        """Event prototype."""
        pass

# helper classes

# content bases
class DialogueContentBase(BoxLayout): pass
class DialogueContentTitle(DialogueContentBase): pass
class DialogueContentNoTitle(DialogueContentBase): pass

# buttons
class DialogueButtonRow(BoxLayout): pass
class DialogueButtons_One(DialogueButtonRow): pass
class DialogueButtons_Two(DialogueButtonRow): pass

## EOF ##