annotate src/libs/garden/garden.contextmenu/app_menu.py @ 83:741a7d6d8c28

garden: added contextmenu
author Goffi <goffi@goffi.org>
date Sat, 24 Dec 2016 14:16:58 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
83
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
1 from kivy.uix.relativelayout import RelativeLayout
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
2 from kivy.uix.stacklayout import StackLayout
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
3 from kivy.uix.behaviors import ToggleButtonBehavior
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
4 from kivy.uix.togglebutton import ToggleButton
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from kivy.lang import Builder
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
6 import kivy.properties as kp
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
7 import os
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
8
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
9 from .context_menu import AbstractMenu, AbstractMenuItem, AbstractMenuItemHoverable
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
10
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
11
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
12 class AppMenu(StackLayout, AbstractMenu):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
13 bounding_box = kp.ObjectProperty(None)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
14
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
15 def __init__(self, *args, **kwargs):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
16 super(AppMenu, self).__init__(*args, **kwargs)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
17 self.hovered_menu_item = None
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
18
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
19 def update_height(self):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
20 max_height = 0
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
21 for widget in self.menu_item_widgets:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
22 if widget.height > max_height:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
23 max_height = widget.height
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
24 return max_height
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
25
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
26 def on_children(self, obj, new_children):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
27 for w in new_children:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
28 # bind events that update app menu height when any of its children resize
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
29 w.bind(on_size=self.update_height)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
30 w.bind(on_height=self.update_height)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
31
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
32 def get_context_menu_root_parent(self):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
33 return self
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
34
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
35 def self_or_submenu_collide_with_point(self, x, y):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
36 collide_widget = None
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
37
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
38 # Iterate all siblings and all children
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
39 for widget in self.menu_item_widgets:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
40 widget_pos = widget.to_window(0, 0)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
41 if widget.collide_point(x - widget_pos[0], y - widget_pos[1]) and not widget.disabled:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
42 if self.hovered_menu_item is None:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
43 self.hovered_menu_item = widget
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
44
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
45 if self.hovered_menu_item != widget:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
46 self.hovered_menu_item = widget
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
47 for sibling in widget.siblings:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
48 sibling.state = 'normal'
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
49
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
50 if widget.state == 'normal':
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
51 widget.state = 'down'
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
52 widget.on_release()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
53
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
54 for sib in widget.siblings:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
55 sib.hovered = False
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
56 elif widget.get_submenu() is not None and not widget.get_submenu().visible:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
57 widget.state = 'normal'
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
58
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
59 return collide_widget
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
60
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
61 def close_all(self):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
62 for submenu in [w.get_submenu() for w in self.menu_item_widgets if w.get_submenu() is not None]:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
63 submenu.hide()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
64 for w in self.menu_item_widgets:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
65 w.state = 'normal'
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
66
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
67 def hide_app_menus(self, obj, pos):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
68 if not self.collide_point(pos.x, pos.y):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
69 for w in [w for w in self.menu_item_widgets if not w.disabled and w.get_submenu().visible]:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
70 submenu = w.get_submenu()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
71 if submenu.self_or_submenu_collide_with_point(pos.x, pos.y) is None:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
72 self.close_all()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
73 self._cancel_hover_timer()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
74
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
75
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
76 class AppMenuTextItem(ToggleButton, AbstractMenuItem):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
77 label = kp.ObjectProperty(None)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
78 text = kp.StringProperty('')
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
79 font_size = kp.NumericProperty(14)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
80 color = kp.ListProperty([1, 1, 1, 1])
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
81
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
82 def on_release(self):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
83 submenu = self.get_submenu()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
84
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
85 if self.state == 'down':
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
86 root = self._root_parent
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
87 submenu.bounding_box_widget = root.bounding_box if root.bounding_box else root.parent
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
88
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
89 submenu.bind(visible=self.on_visible)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
90 submenu.show(self.x, self.y - 1)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
91
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
92 for sibling in self.siblings:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
93 if sibling.get_submenu() is not None:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
94 sibling.state = 'normal'
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
95 sibling.get_submenu().hide()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
96
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
97 self.parent._setup_hover_timer()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
98 else:
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
99 self.parent._cancel_hover_timer()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
100 submenu.hide()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
101
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
102 def on_visible(self, *args):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
103 submenu = self.get_submenu()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
104 if self.width > submenu.get_max_width():
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
105 submenu.width = self.width
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
106
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
107 def _check_submenu(self):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
108 super(AppMenuTextItem, self)._check_submenu()
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
109 self.disabled = (self.get_submenu() is None)
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
110
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
111 # def on_mouse_down(self):
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
112 # print('on_mouse_down')
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
113 # return True
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
114
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
115
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
116 _path = os.path.dirname(os.path.realpath(__file__))
741a7d6d8c28 garden: added contextmenu
Goffi <goffi@goffi.org>
parents:
diff changeset
117 Builder.load_file(os.path.join(_path, 'app_menu.kv'))