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