root/trunk/ide/MenuPanel.py

Revision 4120, 7.3 kB (checked in by ed, 6 months ago)

Removed deprecated use of 'bindfunc' parameter.

Incremental improvement in display stability; still needs work.

  • Property svn:eol-style set to native
Line 
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import os
4 import dabo
5 dabo.ui.loadUI("wx")
6 from dabo.dLocalize import _
7 import dabo.dEvents as dEvents
8 from MenuDesignerComponents import CaptionPanel
9 from MenuDesignerComponents import CaptionBitmapPanel
10 from MenuDesignerComponents import SeparatorPanel
11 from dabo.ui import makeDynamicProperty
12 from dabo.ui import makeProxyProperty
13
14
15
16 class MenuPanel(CaptionPanel):
17     """This class represents a menu."""
18     def afterInit(self):
19         # Name for the saved mnxml file
20         self._className = "MenuPanel"
21         # Displayed name
22         self._commonName = "Menu"
23
24         class _ItemPanel(dabo.ui.dPanel):
25             _className = "MenuItemPanel"
26             def __init__(self, *args, **kwargs):
27                 # Name for the saved mnxml file
28                 self._controller = None
29                 super(_ItemPanel, self).__init__(*args, **kwargs)
30                 self.DynamicWidth = self._calcWidth
31            
32             def _calcWidth(self):
33                 kids = self.Children
34                 if not kids:
35                     return 0
36                 else:
37                     wd = max([kid.Width for kid in kids])
38                     dabo.ui.callAfter(self._resizeItems, wd)
39                     return wd
40            
41             def _resizeItems(self, wd):
42                 if not self:
43                     return
44                 for kid in self.Children:
45                     kid.Width = wd
46                 self.layout()
47                 self.refresh()
48
49             def processContextMenu(self, obj, evt):
50                 self.Controller.processContextMenu(obj, evt)                   
51            
52             def _getController(self):
53                 return self._controller
54        
55             def _setController(self, val):
56                 self._controller = val
57        
58             Controller = property(_getController, _setController, None,
59                     _("Object to which this panel is associated  (MenuPanel)"))
60            
61
62         # Add the panel that will hold the menu items. It needs to
63         # be a child of the menu bar's parent, which would be this
64         # control's grandparent.
65         gp = self.Parent.Parent
66         localPos = (self.Left, self.Bottom)
67         formPos = self.Parent.formCoordinates(localPos)
68         self.itemList = lst = _ItemPanel(gp, Controller=self, Position=formPos,
69                 Visible=True)
70        
71         sz = lst.Sizer = dabo.ui.dSizer("V")
72         sz.DefaultBorder = 1
73         sz.DefaultBorderTop = True
74        
75         # Dict to hold additional item information
76         self.itemDict = {}
77         # Holds the active object during context menu actions
78         self._contextObj = None
79        
80    
81     def __del__(self):
82         try:
83             self.itemList.release()
84         except: pass
85        
86        
87 #   def layout(self):
88 #       dabo.ui.callAfterInterval(100, self.itemList.layout, resetMin=True)
89 #       dabo.ui.callAfterInterval(100, self.itemList.fitToSizer)
90
91
92     def append(self, caption, key=None, picture=None, help=None,
93             separator=False):
94         return self.insert(None, caption, key=None, picture=picture,
95                 help=help, separator=separator)
96    
97    
98     def insert(self, pos, caption, key=None, picture=None, help=None,
99             separator=False):
100         if pos is None:
101             # Called from append
102             pos = len(self.itemList.Children)
103         if separator:
104             itm = SeparatorPanel(self.itemList, Controller=self, Visible=False)
105         else:
106             itm = CaptionBitmapPanel(self.itemList, Caption=caption,
107                     Controller=self, Visible=False)
108             itm._className = "MenuItemPanel"
109             itm._commonName = "Menu Item"
110             itm.isMenuItem = True
111             # Add the item to the dict
112             self.itemDict[itm] = {"caption": caption, "key": key, "picture": picture}
113             if picture:
114                 itm.Picture = picture
115        
116         itm.Visible = True
117         self.itemList.Height += itm.Height
118         self.itemList.Sizer.insert(pos, itm, "x")
119         self.layout()
120         self.Controller.updateLayout()
121         return itm
122        
123    
124     def appendSeparator(self):
125         ret = self.append("", separator=True)
126         self.layout()
127         self.Controller.updateLayout()
128         return ret
129    
130
131     def insertSeparator(self, pos):
132         ret = self.insert(pos, "", separator=True)
133         self.layout()
134         self.Controller.updateLayout()
135         return ret
136        
137    
138     def processContextMenu(self, obj, evt):
139         self._contextObj = obj
140         pop = dabo.ui.dMenu()
141         if not isinstance(obj, SeparatorPanel):
142             pop.append("Edit", OnHit=self.onEdit)
143             pop.appendSeparator()
144         pop.append("Add Item Above", OnHit=self.onAddAbove)
145         pop.append("Add Item Below", OnHit=self.onAddBelow)
146         pop.append("Add Separator Above", OnHit=self.onAddAbove)
147         pop.append("Add Separator Below", OnHit=self.onAddBelow)
148         if obj.getPositionInSizer() != 0:
149             pop.append("Move Up", OnHit=self.onMoveUp)
150         if obj.getPositionInSizer() != len(obj.ControllingSizer.Children)-1:
151             pop.append("Move Down", OnHit=self.onMoveDown)
152         pop.appendSeparator()
153         pop.append("Delete", OnHit=self.onDelete)
154         self.showContextMenu(pop)
155
156
157     def onEdit(self, evt):
158         obj = self._contextObj
159         txt = self.capText = dabo.ui.dTextBox(obj.Parent, Value=obj.Caption,
160                 Position=obj.Position, Size=obj.Size)
161         txt.bindEvent(dEvents.LostFocus, self.onEndEdit)
162         txt.bindEvent(dEvents.KeyChar, self.onTextCapChar)
163         obj.hide()
164         txt.setFocus()
165        
166        
167     def onTextCapChar(self, evt):
168         if evt.keyCode == 13:
169             self.onEndEdit(evt)
170            
171    
172     def onEndEdit(self, evt):
173         cap = self.capText.Value
174         self.capText.release()
175         if cap:
176             self._contextObj.Caption = cap
177         self._contextObj.show()
178         self._contextObj = None
179         self.layout()
180         self.Controller.updateLayout()
181        
182        
183     def onAddAbove(self, evt):
184         pos = self._contextObj.getPositionInSizer()
185         return self.addFromContextMenu(pos, evt)
186    
187    
188     def onAddBelow(self, evt):
189         pos = self._contextObj.getPositionInSizer() + 1
190         return self.addFromContextMenu(pos, evt)
191        
192        
193     def addFromContextMenu(self, pos, evt):
194         obj = self._contextObj
195         self._contextObj = None
196         if "Separator" in evt.EventObject.Caption:
197             return self.insertSeparator(pos)
198         else:
199             return self.addItem(pos)
200
201    
202     def addItem(self, pos):
203         itm = None
204         cap = dabo.ui.getString("Caption for new menu item?")
205         if cap:
206             itm = self.insert(pos, cap)
207             self.Controller.select(itm)
208         return itm
209        
210    
211     def onMoveDown(self, evt):
212         obj = self._contextObj
213         pos = obj.getPositionInSizer()
214         sz = obj.ControllingSizer
215         sz.remove(obj)
216         sz.insert(pos+1, obj, "x")
217         sz.layout()
218         self.Controller.updateLayout()
219    
220    
221     def onMoveUp(self, evt):
222         obj = self._contextObj
223         pos = obj.getPositionInSizer()
224         sz = obj.ControllingSizer
225         sz.remove(obj)
226         sz.insert(pos-1, obj, "x")
227         sz.layout()
228         self.Controller.updateLayout()
229    
230    
231     def onDelete(self, evt):
232         obj = self._contextObj
233         if not obj:
234             return
235         obj.ControllingSizer.remove(obj)
236         obj.release()
237         self.layout()
238         self.Controller.updateLayout()
239
240
241     def onMouseLeftClick(self, evt):
242         self.Parent.menuClick(self)
243    
244    
245     def _getChildren(self):
246         try:
247             return self.itemList.Children
248         except AttributeError:
249             return []
250
251
252     def _getPanelVisible(self):
253         return self.itemList.Visible
254
255     def _setPanelVisible(self, val):
256         if val:
257             localPos = (self.Left, self.Bottom)
258             formPos = self.Parent.formCoordinates(localPos)
259             self.itemList.Position = formPos
260             self.Controller.onShowPanel(self)
261 #       self.Visible = val
262         self.itemList.Visible = val
263
264 #       itms = self._proxyDict.get("Visible", ())
265 #       for xx in itms:
266 #           if xx == "Children":
267 #               for xkid in self.Children:
268 #           elif xx == "self":
269 #               print "SELF ITEMLIST", self.itemList.Visible
270 #           else:
271 #               obj = getattr(self, xx)
272 #               print xx, obj.Visible
273        
274         self.itemList.update()
275         self.itemList.Parent.clear()
276         self.layout()
277 #       self.itemList.Parent.refresh()
278
279
280     Children = property(_getChildren, None, None,
281             _("Returns a list of menu items for this menu (read-only) (list)"))
282    
283     PanelVisible = property(_getPanelVisible, _setPanelVisible, None,
284             _("Determines if the menu is currently 'open'  (bool)"))
285
286
287     _proxyDict = {}
288     Visible = makeProxyProperty(_proxyDict, "Visible", ("self", "Children", "_capText"))
Note: See TracBrowser for help on using the browser.