dabo Commit
Revision 7171
Date: 2012-05-01 11:55:52 -0700 (Tue, 01 May 2012)
Author: Ed
Trac: http://trac.dabodev.com/changeset/7171

Changed:
A   trunk/ide/MenuDesignerComponents.py

Log:
Adding this file to svn - should have been added with the rest of the 
MenuDesigner changes.

Diff:
Added: trunk/ide/MenuDesignerComponents.py
===================================================================
--- trunk/ide/MenuDesignerComponents.py                         (rev 0)
+++ trunk/ide/MenuDesignerComponents.py 2012-05-01 18:55:52 UTC (rev 7171)
@@ -0,0 +1,581 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
+import dabo
+from dabo.dLocalize import _
+import dabo.dEvents as dEvents
+from dabo.ui import makeDynamicProperty
+from dabo.ui import makeProxyProperty
+
+
+
+class MenuSaverMixin(object):
+       """Contains the basic code for generating the dict required
+       to save the MenuDesigner's contents.
+       """
+       def getDesignerDict(self):
+               ret = {}
+               ret["name"] = self.__class__.__name__
+               ret["attributes"] = ra = {}
+               propsToExclude = ("HotKeyChar", "HotKeyControl",
+                               "HotKeyAlt", "HotKeyShift")
+               for prop in self.DesignerProps:
+                       if prop in propsToExclude:
+                               continue
+                       if hasattr(self, prop):
+                               val = eval("self.%s" % prop)
+                       else:
+                               # Custom-defined property; that's saved 
elsewhere
+                               continue
+                       if isinstance(val, basestring) and os.path.exists(val):
+                               # It's a path; convert it to a relative path
+                               if isinstance(self, dabo.ui.dForm):
+                                       ref = self.Form._menuBarFile
+                               else:
+                                       ref = "."
+                               ref = os.path.abspath(ref)
+                               val = dabo.lib.utils.getPathAttributePrefix() + 
\
+                                               
dabo.lib.utils.relativePath(val, ref)
+                       if isinstance(val, basestring):
+                               strval = val
+                       else:
+                               strval = unicode(val)
+                       # Special cases
+                       try:
+                               evalStrVal = eval(strval)
+                       except:
+                               evalStrVal = None
+                       ra[prop] = val
+               ret["children"] = [kid.getDesignerDict()
+                               for kid in self.Children
+                               if hasattr(kid, "getDesignerDict")]
+               return ret
+
+
+
+class CaptionPanel(MenuSaverMixin, dabo.ui.dPanel):
+       # Name for the saved mnxml file
+       _className = "CaptionPanel"
+       # Displayed name
+       _commonName = "Generic Item"
+       _kids = []
+
+       def __init__(self, parent, *args, **kwargs):
+               self._caption = ""
+               self._MRU = False
+               self._selected = False
+               self._inUpdate = False
+               # The draw object representing the Caption
+               self._capText = None
+               # The draw object representing the HotKey
+               self._hotKeyText = None
+               # Minimum spacing between the caption and hot key
+               self._captionHotKeySpacing = 20
+               # Function to be called when a menu item is selected. This
+               # is a string representation that will be eval'd at runtime
+               self._action = ""
+               # Flag to let the Menu Designer know that this is a MenuItem
+               self.isMenuItem = False
+               # The following underlie the HotKey property and its components
+               self._hotKey = ""
+               self._hotKeyAlt = False
+               self._hotKeyChar = ""
+               self._hotKeyControl = False
+               self._hotKeyShift = False
+               super(CaptionPanel, self).__init__(parent, *args, **kwargs)
+               self.BorderWidth = 1
+               self.BorderColor = (222, 222, 222)
+               self.Height = 24
+               self._unselectedBackColor = "white"
+               self._selectedBackColor = (255, 255, 192)
+               self._unselectedForeColor = "black"
+               self._selectedForeColor = "blue"
+               # This is the background draw object
+               self._background = self.drawRectangle(0, 0, -1, -1,
+                               penWidth=0, 
fillColor=self._unselectedBackColor, visible=False)
+               self._capText = self.drawText(self.Caption, 5, 5, visible=False)
+               self._hotKeyText = self.drawText(self.AbbreviatedHotKey, 5, 5, 
visible=False)
+               self.DynamicBackColor = self.getBack            #lambda: {True: 
self._selectedBackColor, False: self._unselectedBackColor}[self._selected]
+               self._background.DynamicFillColor = 
self._capText.DynamicFillColor = \
+                               self._hotKeyText.DynamicFillColor = 
self.getBack                #lambda: {True: self._selectedBackColor, False: 
self._unselectedBackColor}[self._selected]
+               self._capText.DynamicForeColor = lambda: {True: 
self._selectedForeColor, False: self._unselectedForeColor}[self._selected]
+               # This will allow the hot key text position to stay 
right-aligned.
+               self._hotKeyText.DynamicXpos = self.positionHotKeyText
+               self.refresh()
+               self.Parent.update()
+               self._dragging = False
+               self._dragImg = None
+               self._helpText = ""
+               # We want the drawing surface cleared between drawings
+               self.autoClearDrawings = True
+               # We want Hover behavior
+               self.Hover = True
+               # Smooth the drawing
+               self.Buffered = True
+
+               self._kids = [self._background, self._hotKeyText, self._capText]
+
+       def getBack(self):
+               if self._selected:
+                       ret = self._selectedBackColor
+               else:
+                       ret = self._unselectedBackColor
+               return ret
+
+
+       # These two methods will display the item's HelpText
+       # in the form's Status Bar when the mouse is over them.
+       def onHover(self, evt):
+               self.Form.StatusText = self.HelpText
+       def endHover(self, evt):
+               self.Form.StatusText = ""
+
+#### Someday I hope to have the time to enable dragging menus
+#### around to re-arrange them!
+#      def onMouseLeftDown(self, evt):
+#              self._dragging = True
+#              self._dragImg = dabo.ui.dDragImage(self)
+#
+#      def onMouseMove(self, evt):
+#              if not self._dragging:
+#                      return
+#              if evt.mouseDown:
+#                      self._dragImg.updatePosition()
+#              else:
+#                      self._dragImg.clear()
+#                      self._dragImg = None
+#                      self._dragging = False
+#
+#      def onMouseLeftUp(self, evt):
+#              print "LEFT UP", self._caption,  self._dragging,
+#              self._dragging = False
+#              x, y = evt.mousePosition
+#              print x, y, self.posIsWithin(x, y)
+#              if self._dragImg:
+#                      self._dragImg.clear()
+#              self._dragImg = None
+
+
+       def setWidth(self):
+               """Set the width to the width of the text, plus 5 pixels on 
each side."""
+               curr = self.Width
+               capwd = dabo.ui.fontMetricFromDrawObject(self._capText)[0]
+               hkwd = dabo.ui.fontMetricFromDrawObject(self._hotKeyText)[0]
+               addlwd = self.getAdditionalWidth()
+               if self._hotKey:
+                       addlwd += self._captionHotKeySpacing
+               calc = capwd + hkwd + addlwd
+               if curr < calc:
+                       self.Width = calc
+
+
+       def positionHotKeyText(self):
+               "This is the function for the DynamicXPos property of the 
HotKey."""
+               hkt = self._hotKeyText
+               wd = dabo.ui.fontMetricFromDrawObject(hkt)[0]
+               margin = 10
+               return (self.Width - wd) - margin
+
+
+       def getAdditionalWidth(self):
+               """Provide for a little 'breathing room' on the panel. 
Subclasses
+               can override as needed if they contain additional items.
+               """
+               return 10
+
+
+       def refresh(self):
+               if self._capText is not None:
+                       dabo.ui.callAfterInterval(60, self._refresh)
+       def _refresh(self):
+               """By linking this to a 'callAfterInterval', when several events
+               that require a refresh occur quickly, the 'slow stuff' only gets
+               called once.
+               """
+               super(CaptionPanel, self).refresh()
+               self.setWidth()
+               self.Parent.update()
+               self.Parent.layout()
+
+
+       def onContextMenu(self, evt):
+               self.Parent.processContextMenu(self, evt)
+
+
+       def onMouseLeftClick(self, evt):
+               self.Form.select(self)
+
+
+       def _updateHotKey(self):
+               """Called when the user changes any component of the hotkey 
combo."""
+               if not self._inUpdate:
+                       self._inUpdate = True
+                       currHK = self.HotKey
+                       ctlTxt = {True: "Ctrl+", False: ""}[self.HotKeyControl]
+                       shiftTxt = {True: "Shift+", False: ""}[self.HotKeyShift]
+                       altTxt = {True: "Alt+", False: ""}[self.HotKeyAlt]
+                       newHK = ctlTxt + altTxt + shiftTxt + self.HotKeyChar
+                       if newHK != currHK:
+                               self.HotKey = newHK
+                               self.refresh()
+                       self._inUpdate = False
+
+
+       def _updateHotKeyProps(self, val=None):
+               """Called when the user changes the hotkey combo to reset the 
components."""
+               if not self._inUpdate:
+                       self._inUpdate = True
+                       if val is None:
+                               val = self.HotKey
+                       self.HotKeyControl = ("Ctrl+" in val)
+                       self.HotKeyShift = ("Shift+" in val)
+                       self.HotKeyAlt = ("Alt+" in val)
+                       self.HotKeyChar = val.split("+")[-1]
+                       self._inUpdate = False
+
+
+       def _getAbbreviatedHotKey(self):
+               ctlTxt = {True: "c", False: ""}[self.HotKeyControl]
+               shiftTxt = {True: "s", False: ""}[self.HotKeyShift]
+               altTxt = {True: "a", False: ""}[self.HotKeyAlt]
+               prefix = ctlTxt + altTxt + shiftTxt
+               if prefix:
+                       prefix += "+"
+               return prefix + self.HotKeyChar
+
+
+       def _getAction(self):
+               return self._action
+
+       def _setAction(self, val):
+               if self._constructed():
+                       self._action = val
+               else:
+                       self._properties["Action"] = val
+
+
+       def _getCaption(self):
+               return self._caption
+
+       def _setCaption(self, val):
+               self._caption = val
+               if self._capText is not None:
+                       self._capText.Text = val
+                       self.refresh()
+
+
+       def _getController(self):
+               try:
+                       return self._controller
+               except AttributeError:
+                       self._controller = self.Form
+                       return self._controller
+
+       def _setController(self, val):
+               if self._constructed():
+                       self._controller = val
+               else:
+                       self._properties["Controller"] = val
+
+
+       def _getDesignerProps(self):
+               ret = {"Caption": {"type" : unicode, "readonly" : False},
+                               "HelpText" : {"type" : unicode, "readonly" : 
False},
+                               "MRU": {"type" : bool, "readonly" : False}}
+               if self.isMenuItem:
+                       ret.update({"HotKey": {"type" : unicode, "readonly" : 
False,
+                                       "customEditor": "editHotKey"},
+                                       "HotKeyAlt": {"type" : bool, "readonly" 
: False},
+                                       "HotKeyChar": {"type" : unicode, 
"readonly" : False},
+                                       "HotKeyControl": {"type" : bool, 
"readonly" : False},
+                                       "HotKeyShift": {"type" : bool, 
"readonly" : False},
+                                       "Action": {"type" : unicode, "readonly" 
: False}})
+                       del ret["MRU"]
+               return ret
+
+
+       def _getDisplayText(self):
+               return "%s: '%s'" % (self._commonName, self.Caption)
+
+
+       def _getHelpText(self):
+               return self._helpText
+
+       def _setHelpText(self, val):
+               if self._constructed():
+                       self._helpText = val
+               else:
+                       self._properties["HelpText"] = val
+
+
+       def _getHotKey(self):
+               return self._hotKey
+
+       def _setHotKey(self, val):
+               if self._constructed():
+                       self._hotKey = val
+                       self._updateHotKeyProps(val)
+                       self._hotKeyText.Text = self._getAbbreviatedHotKey()
+                       self.update()
+               else:
+                       self._properties["HotKey"] = val
+
+
+       def _getHotKeyAlt(self):
+               return self._hotKeyAlt
+
+       def _setHotKeyAlt(self, val):
+               if self._constructed():
+                       self._hotKeyAlt = val
+                       self._updateHotKey()
+               else:
+                       self._properties["HotKeyAlt"] = val
+
+
+       def _getHotKeyChar(self):
+               return self._hotKeyChar
+
+       def _setHotKeyChar(self, val):
+               if self._constructed():
+                       self._hotKeyChar = val
+                       self._updateHotKey()
+               else:
+                       self._properties["HotKeyChar"] = val
+
+
+       def _getHotKeyControl(self):
+               return self._hotKeyControl
+
+       def _setHotKeyControl(self, val):
+               if self._constructed():
+                       self._hotKeyControl = val
+                       self._updateHotKey()
+               else:
+                       self._properties["HotKeyControl"] = val
+
+
+       def _getHotKeyShift(self):
+               return self._hotKeyShift
+
+       def _setHotKeyShift(self, val):
+               if self._constructed():
+                       self._hotKeyShift = val
+                       self._updateHotKey()
+               else:
+                       self._properties["HotKeyShift"] = val
+
+
+       def _getMRU(self):
+               return self._MRU
+
+       def _setMRU(self, val):
+               self._MRU = val
+
+
+       def _getSelected(self):
+               return self._selected
+
+       def _setSelected(self, val):
+               if self._constructed():
+                       self._selected = val
+#                      self.clear()
+#                      self.lockDisplay()
+#                      backcolor = {True: self._selectedBackColor,
+#                                      False: self._unselectedBackColor}[val]
+#                      forecolor = {True: self._selectedForeColor,
+#                                      False: self._unselectedForeColor}[val]
+#                      self._capText.ForeColor = self._capText.PenColor = 
forecolor
+#                      self._capText.FontBold = val
+#                      self.BackColor = self._background.FillColor = backcolor
+                       self.Parent.refresh()
+#                      self.unlockDisplay()
+               else:
+                       self._properties["Selected"] = val
+
+
+       # Tree display is the same as the displayed text
+       def _getTreeDisplayCaption(self):
+               return ("'%s'" % self.Caption, self._commonName)
+
+
+       AbbreviatedHotKey = property(_getAbbreviatedHotKey, None, None,
+                       _("Short version of the HotKey string (read-only) 
(str)"))
+
+       Action = property(_getAction, _setAction, None,
+                       _("Action to be called when a menu item is selected.  
(str)"))
+
+       Caption = property(_getCaption, _setCaption, None,
+                       _("Caption displayed on this panel  (str)"))
+
+       Controller = property(_getController, _setController, None,
+                       _("Object to which this one reports events  (object 
(varies))"))
+
+       DesignerProps = property(_getDesignerProps, None, None,
+                       _("Properties exposed in the Menu Designer (read-only) 
(dict)"))
+
+       DisplayText = property(_getDisplayText, None, None,
+                       _("Text used in the prop sheet to identify this object 
(read-only) (str)"))
+
+       HelpText = property(_getHelpText, _setHelpText, None,
+                       _("Help string displayed when the menu item is 
selected.  (str)"))
+
+       HotKey = property(_getHotKey, _setHotKey, None,
+                       _("Displayed version of the hotkey combination  (str)"))
+
+       HotKeyAlt = property(_getHotKeyAlt, _setHotKeyAlt, None,
+                       _("Is the Alt key part of the hotkey combo?  (bool)"))
+
+       HotKeyChar = property(_getHotKeyChar, _setHotKeyChar, None,
+                       _("Character part of the hot key for this menu  (str)"))
+
+       HotKeyControl = property(_getHotKeyControl, _setHotKeyControl, None,
+                       _("Is the Control key part of the hotkey combo?  
(bool)"))
+
+       HotKeyShift = property(_getHotKeyShift, _setHotKeyShift, None,
+                       _("Is the Shift key part of the hotkey combo?  (bool)"))
+
+       MRU = property(_getMRU, _setMRU, None,
+                       _("Should this menu be tracked for MRU lists  (bool)"))
+
+       Selected = property(_getSelected, _setSelected, None,
+                       _("Is this the currently selected item?  (bool)"))
+
+       TreeDisplayCaption = property(_getTreeDisplayCaption, None, None,
+                       _("Identifying label displayed in the prop sheet tree 
(read-only) (str)"))
+
+
+       _proxyDict = {}
+       Visible = makeProxyProperty(_proxyDict, "Visible", ("self", "_kids"))
+
+
+class CaptionBitmapPanel(CaptionPanel):
+       """Like the CaptionPanel, but can also display a bitmap image
+       to the left of the caption.
+       """
+       # Name for the saved mnxml file
+       _className = "CaptionBitmapPanel"
+
+       def __init__(self, parent, *args, **kwargs):
+               self._bitmap = None
+               self._bmp = None
+               self._picture = None
+               super(CaptionBitmapPanel, self).__init__(parent, *args, 
**kwargs)
+
+
+       def getAdditionalWidth(self):
+               """Add in the width of the bitmap."""
+               ret = super(CaptionBitmapPanel, self).getAdditionalWidth()
+               if self._bmp is not None:
+                       ret += self._bmp.Width + 5
+               return ret
+
+
+       def _getBitmap(self):
+               return self._bitmap
+
+       def _setBitmap(self, val):
+               self._bitmap = val
+               if isinstance(val, basestring):
+                       bmp = dabo.ui.strToBmp(val)
+               else:
+                       bmp = val
+               # Create the bitmap object
+               if self._bmp:
+                       # Remove it.
+                       self.removeDrawnObject(self._bmp)
+                       self._kids.remove(self._bmp)
+                       self._bmp = None
+               self._bmp = self.drawBitmap(bmp, 5, 5, 
visible=self.Parent.Visible)
+
+               self._kids.append(self._bmp)
+
+               wd = self._bmp.Width
+               # Move the text over to fit
+               self._capText.Xpos = wd + 10
+               self.refresh()
+
+
+       def _getDesignerProps(self):
+               ret = super(CaptionBitmapPanel, self)._getDesignerProps()
+               ret.update({"Picture": {"type" : "path", "readonly" : False,
+                               "customEditor": "editStdPicture"}})
+               return ret
+
+
+       def _getPicture(self):
+               return self._picture
+
+       def _setPicture(self, val):
+               self._picture = val
+               if isinstance(val, dabo.ui.dBitmap):
+                       bmp = val
+               else:
+                       bmp = dabo.ui.strToBmp(val)
+               self._setBitmap(bmp)
+
+
+       Bitmap = property(_getBitmap, _setBitmap, None,
+                       _("Bitmap to display on the panel  (bitmap)"))
+
+       DesignerProps = property(_getDesignerProps, None, None,
+                       _("Properties exposed in the Menu Designer (read-only) 
(dict)"))
+
+       Picture = property(_getPicture, _setPicture, None,
+                       _("The file used as the source for the displayed image. 
 (str)") )
+
+
+
+class SeparatorPanel(CaptionBitmapPanel):
+       """Represents a menu separator item."""
+       # Name for the saved mnxml file
+       _className = "SeparatorPanel"
+       # Displayed name
+       _commonName = "Separator"
+       # Displayed separator line
+       _line = None
+
+       def afterInitAll(self):
+               self.Height = 16
+               midHt = self.Height / 2.0
+               self._line = self.drawLine(4, midHt, self.Width-4, midHt,
+                               penColor="gray", penWidth=1)
+               self._line.DynamicPoints = self.setLineWidth
+               self._line.DynamicPenWidth = self.setLineThick
+               self._kids.append(self._line)
+
+
+       def onResize(self, evt):
+               if self._line:
+                       self.update()
+
+
+       def setLineWidth(self):
+               """We want the line to be the full width of the panel,
+               with a few pixels 'breathing room' on each side.
+               """
+               midHt = self.Height / 2.0
+               x1 = 4
+               x2 = self.Width - 4
+               y1 = y2 = midHt
+               return ((x1, y1), (x2, y2))
+
+
+       def setLineThick(self):
+               """Make it look thicker when selected."""
+               return {True: 2, False: 1}[self.Selected]
+
+
+       def _getDesignerProps(self):
+               return {}
+
+
+       def _getDisplayText(self):
+               return "Separator"
+
+
+       DesignerProps = property(_getDesignerProps, None, None,
+                       _("Properties exposed in the Menu Designer (read-only) 
(dict)"))
+
+       DisplayText = property(_getDisplayText, None, None,
+                       _("Text used in the prop sheet to identify this object 
(read-only) (str)"))
+



_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev
Searchable Archives: http://leafe.com/archives/search/dabo-dev
This message: 
http://leafe.com/archives/byMID/[email protected]

Reply via email to