annotate src/libs/garden/garden.contextmenu/app_menu.py @ 97:5d2289127bb7

menu (upload): better menu using dedicated widget: upload menu now use a decicated widget instead of context menu. The menu take half the size of the main window, and show each upload option as an icon. Use can select upload or P2P sending, and a short text message explains how the file will be transmitted.
author Goffi <goffi@goffi.org>
date Thu, 29 Dec 2016 23:47:07 +0100
parents 741a7d6d8c28
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'))