# -*- coding: utf-8 -*- import dabo dabo.ui.loadUI("wx") import dabo.dEvents as dEvents from dabo.dLocalize import _ from dabo.ui import dKeys from ClassDesignerComponents import LayoutPanel from ClassDesignerComponents import LayoutBasePanel from ClassDesignerComponents import LayoutSpacerPanel from ClassDesignerComponents import LayoutSizer from ClassDesignerComponents import LayoutGridSizer from ClassDesignerComponents import NoSizerBasePanel from DragHandle import DragHandle import ClassDesignerMenu from MenuBarPanel import MenuBarPanel from MenuPanel import MenuPanel from MenuDesignerComponents import SeparatorPanel dui = dabo.ui class TreeSheet(dui.dPanel): def afterInit(self): self._slotCaption = _("Empty Sizer Slot") self._spacerCaption = _("Spacer") self.tree = dui.dTreeView(self, MultipleSelect=self.MultipleSelect, ShowButtons=True) plat = self.Application.Platform if plat == "Mac": self.tree.FontSize -= 3 elif plat == "Win": self.tree.FontSize += 1 else: self.tree.FontSize -= 1 self.tree.bindEvent(dEvents.TreeSelection, self.onTreeSel) self.tree.bindEvent(dEvents.TreeItemContextMenu, self.onTreeContextMenu) self.tree.bindEvent(dEvents.MouseLeftDoubleClick, self.onTreeAction) self.tree.bindKey("enter", self.onTreeAction) self.tree.bindKey("numpad_enter", self.onTreeAction) # self.tree.bindEvent(dEvents.TreeBeginDrag, self.onTreeBeginDrag) # self.tree.bindEvent(dEvents.TreeEndDrag, self.onTreeEndDrag) self.Sizer = dui.dSizer("v") self.Sizer.append1x(self.tree) # Flag for determining if the user or the app is selecting self._inAppSelection = False def onTreeAction(self, evt): self.Form.hideTree() # def onTreeBeginDrag(self, evt): # print "BEGIN DRAG" # print "ALLOWED?",evt._uiEvent.IsAllowed() # print evt.EventData # print evt.selectedCaption # # # def onTreeEndDrag(self, evt): # print "End DRAG" # print evt.EventData # print evt.selectedCaption def onTreeSel(self, evt): if self._inAppSelection: # Otherwise, this would be infinite recursion return dui.callAfter(self.Controller.treeSelect) def onTreeContextMenu(self, evt): evt.stop() try: obj = self.tree.find(evt.itemID)[0].Object # See if there is a context menu for this object menu = self.Controller.getTreeContextMenu(obj) if menu: dabo.ui.callAfter(self.showContextMenu, menu) except: pass def expandAll(self): self.tree.expandAll() def collapseAll(self): self.tree.collapseAll() def getSelection(self): if self.MultipleSelect: nds = self.tree.Selection ret = [] for nd in nds: ob = nd.Object if ob not in ret: ret.append(ob) else: ret = self.tree.Selection.Object return ret def select(self, ctls): """Iterate through the nodes, and set their Selected status to match if they are in the current selection of controls. """ if self._inAppSelection: return if not isinstance(ctls, (tuple, list)): ctls = [ctls] self._inAppSelection = True selNodes = [nn for nn in self.tree.nodes if nn.Object in ctls] self.tree.Selection = selNodes self._inAppSelection = False def priorObj(self): """Return the next node up from the current selection""" ret = None nx = self.tree.priorNode() if nx is not None: ret = nx._object return ret def nextObj(self): """Return the next node down from the current selection""" ret = None nx = self.tree.nextNode() if nx is not None: ret = nx._object return ret def getNodeFor(self, obj): """Return the node whose Object property is the passed object.""" return self.tree.nodeForObject(obj) def updateDisplay(self, frm): """Constructs the tree for the form's layout.""" sel = self.tree.Selection if sel: if self.MultipleSelect: selObjs = [nn.Object for nn in sel] # Preserve the expand/collapse state if possible. expState = [(nn.Object, nn.Expanded) for nn in self.tree.nodes] self.tree.clear() topObj = frm.getObjectHierarchy()[0][1] self.recurseLayout(topObj, None) self.tree.expandAll() if sel: if self.MultipleSelect: self.select(selObjs) else: self.select(sel) # Restore the expand/collapse state if possible. for obj, expand in expState: nn = self.tree.nodeForObject(obj) if nn: nn.Expanded = expand def updateNames(self, frm): """Refreshes the object names without changing the layout.""" sel = self.tree.Selection for nd in sel: obj = nd.Object nd.Caption = self._getDisplayName(obj) def _getDisplayName(self, obj): """Create the name displayed on the tree for a given object.""" ret = str(obj) if isinstance(obj, (dui.dSizer, dui.dBorderSizer, dui.dGridSizer)): ornt = obj.Orientation if ornt in ("r", "c"): ornt = {"r":"Row", "c":"Column"}[ornt] ret = _("Grid Sizer") else: if isinstance(obj, dui.dBorderSizer): itmCap = obj.Caption if itmCap: ret = _("BorderSizer ('%s'): %s") % (itmCap, ornt) else: ret = _("BorderSizer: %s") % ornt else: ret = _("Sizer: %s") % ornt elif isinstance(obj, LayoutSpacerPanel): ret = self._slotCaption if isinstance(obj.ControllingSizer, LayoutGridSizer): # Add the row,col info to the caption r, c = obj.ControllingSizer.getGridPos(obj) ret = "%s r:%s, c:%s" % (self._slotCaption, r, c) else: ret = "%s - (%s)" % (self._spacerCaption, obj.Spacing) elif isinstance(obj, SeparatorPanel): return " (Separator) " else: if hasattr(obj, "TreeDisplayCaption"): dsp = obj.TreeDisplayCaption if isinstance(dsp[1], type): dsp = (dsp[0], self._getClassName(dsp[1])) elif isinstance(obj, dui.dColumn): dsp = "Column", obj.DataField elif isinstance(obj, dui.dialogs.Wizard): dsp = "Wizard", obj.Caption elif hasattr(obj, "Name"): dsp = (obj.Name, self._getClassName(obj._baseClass)) else: dsp = ("", self._getClassName(obj.__class__)) try: if isinstance(obj.ControllingSizer, LayoutGridSizer): r, c = obj.ControllingSizer.getGridPos(obj) dsp = ("%s r:%s, c:%s" % (dsp[0], r, c), dsp[1]) except: pass ret = "%s (%s)" % dsp return ret def _getClassName(self, cls): """Takes a string representation of the form: and returns just the actual class name (i.e., in this case, 'dTextBox'). """ ret = str(cls) if ret.startswith("