dabo Commit
Revision 4164
Date: 2008-06-19 10:27:53 -0700 (Thu, 19 Jun 2008)
Author: Ed
Trac: http://svn.dabodev.com/trac/dabo/changeset/4164
Changed:
U trunk/dabo/ui/uiwx/__init__.py
U trunk/dabo/ui/uiwx/dDialog.py
Log:
Major re-write to the dDialog subclasses. Specifically, there is now a subclass
called 'dStandardButtonDialog' that can accept one or more of the following
parameters when it is created:
OK
Cancel
Yes
No
Help
It uses the wx standard button sizer methods to create the buttons following
platform-specific layout guidelines. Each button has a corresponding on* (e.g.,
onYes, onHelp) handler which is called when the button is clicked.
There are two subclasses of dStandardButtonDialog included: dOkCancelDialog,
and dYesNoDialog. dOkCancelDialog is pretty much the same as before; while
dYesNoDialog is like dOkCancelDialog, except with Yes/No buttons. If you call
dStandardButtonDialog without passing any parameters, a single OK button will
be displayed.
I've tested this with my apps, and it seems to work seamlessly. Please consider
it beta until a few more people have played around with it.
Diff:
Modified: trunk/dabo/ui/uiwx/__init__.py
===================================================================
--- trunk/dabo/ui/uiwx/__init__.py 2008-06-19 15:41:02 UTC (rev 4163)
+++ trunk/dabo/ui/uiwx/__init__.py 2008-06-19 17:27:53 UTC (rev 4164)
@@ -79,7 +79,9 @@
from dDateTextBox import dDateTextBox
from dDropdownList import dDropdownList
from dDialog import dDialog
+from dDialog import dStandardButtonDialog
from dDialog import dOkCancelDialog
+from dDialog import dYesNoDialog
from dEditableList import dEditableList
from dEditBox import dEditBox
from dEditor import dEditor
Modified: trunk/dabo/ui/uiwx/dDialog.py
===================================================================
--- trunk/dabo/ui/uiwx/dDialog.py 2008-06-19 15:41:02 UTC (rev 4163)
+++ trunk/dabo/ui/uiwx/dDialog.py 2008-06-19 17:27:53 UTC (rev 4164)
@@ -203,18 +203,33 @@
-class dOkCancelDialog(dDialog):
- """Creates a dialog with OK/Cancel buttons and associated functionality.
+class dStandardButtonDialog(dDialog):
+ """Creates a dialog with standard buttons and associated functionality.
You can
+ choose the buttons that display by passing True for any of the
following
+ properties:
+
+ OK
+ Cancel
+ Yes
+ No
+ Help
- Add your custom controls in the addControls() hook method, and respond
to
- the pressing of the Ok and Cancel buttons in the onOK() and onCancel()
- event handlers. The default behavior in both cases is just to close the
- form, and you can query the Accepted property to find out if the user
- pressed "OK" or not.
+ If you don't specify buttons, only the OK will be included; if you do
specify buttons,
+ you must specify them all; in other words, OK is only assumed if
nothing is specified.
+ Then add your custom controls in the addControls() hook method, and
respond to
+ the pressing of the standard buttons in the on*() handlers, where * is
the name of the
+ associated property (e.g., onOK(), onNo(), etc.). You can query the
Accepted property
+ to find out if the user pressed "OK" or "Yes"; if neither of these was
pressed,
+ Accepted will be False.
"""
def __init__(self, parent=None, properties=None, *args, **kwargs):
- super(dOkCancelDialog, self).__init__(parent=parent,
properties=properties, *args, **kwargs)
- self._baseClass = dOkCancelDialog
+ self._ok = self._extractKey((properties, kwargs), "OK")
+ self._cancel = self._extractKey((properties, kwargs), "Cancel")
+ self._yes = self._extractKey((properties, kwargs), "Yes")
+ self._no = self._extractKey((properties, kwargs), "No")
+ self._help = self._extractKey((properties, kwargs), "Help")
+ super(dStandardButtonDialog, self).__init__(parent=parent,
properties=properties, *args, **kwargs)
+ self._baseClass = dStandardButtonDialog
self._accepted = False
@@ -225,70 +240,115 @@
sz.DefaultBorderLeft = sz.DefaultBorderRight = True
sz.append((0, sz.DefaultBorder))
- # Define Ok/Cancel, and tell wx that we want stock buttons.
- # We are creating them now, so that the user code can access
them if needed.
- self.btnOK = dabo.ui.dButton(self, id=wx.ID_OK,
DefaultButton=True)
- self.btnOK.bindEvent(dEvents.Hit, self.onOK)
- self.btnCancel = dabo.ui.dButton(self, id=wx.ID_CANCEL,
CancelButton=True)
- self.btnCancel.bindEvent(dEvents.Hit, self.onCancel)
+ # Add the specified buttons. If none were specified, then just
add OK
+ ok = self._ok
+ cancel = self._cancel
+ yes = self._yes
+ no = self._no
+ help = self._help
+ if (ok is None and cancel is None and yes is None and
+ no is None and help is None):
+ ok = True
- # Put the buttons in a StdDialogButtonSizer, so they get
positioned/sized
- # per the native platform conventions:
- buttonSizer = wx.StdDialogButtonSizer()
- buttonSizer.AddButton(self.btnOK)
- buttonSizer.AddButton(self.btnCancel)
- buttonSizer.Realize()
- self._btnSizer = bsWrapper = dabo.ui.dSizer("v")
- bsWrapper.append(buttonSizer, "x")
-
+ flags = 0
+ if ok:
+ flags = flags | wx.OK
+ if cancel:
+ flags = flags | wx.CANCEL
+ if yes:
+ flags = flags | wx.YES
+ if no:
+ flags = flags | wx.NO
+ if help:
+ flags = flags | wx.HELP
+ if flags == 0:
+ # Nothing specified; default to just OK
+ flags = wx.OK
+ # Initialize the button references
+ self.btnOK = self.btnCancel = self.btnYes = self.btnNo =
self.btnHelp = None
+ self.stdButtonSizer = sbs = self.CreateButtonSizer(flags)
+ btns = [b.GetWindow() for b in sbs.GetChildren() if
b.IsWindow()]
+ for btn in btns:
+ id_ = btn.GetId()
+ if id_ == wx.ID_OK:
+ self.btnOK = btn
+ mthd = self._onOK
+ elif id_ == wx.ID_CANCEL:
+ self.btnCancel = btn
+ mthd = self._onCancel
+ elif id_ == wx.ID_YES:
+ self.btnYes = btn
+ mthd = self._onYes
+ elif id_ == wx.ID_NO:
+ self.btnNo = btn
+ mthd = self._onNo
+ elif id_ == wx.ID_HELP:
+ self.btnHelp = btn
+ mthd = self._onHelp
+ btn.Bind(wx.EVT_BUTTON, mthd)
+
# Wx rearranges the order of the buttons per platform
conventions, but
# doesn't rearrange the tab order for us. So, we do it manually:
buttons = []
- for child in buttonSizer.GetChildren():
+ for child in sbs.GetChildren():
win = child.GetWindow()
if win is not None:
buttons.append(win)
- buttons[1].MoveAfterInTabOrder(buttons[0])
+ for pos, btn in enumerate(buttons[1:]):
+ btn.MoveAfterInTabOrder(buttons[pos-1])
+ if cancel or no:
+ # The default Escape behavior destroys the dialog, so
we need to replace
+ # this with out own.
+ self.SetEscapeId(wx.ID_NONE)
+ if cancel:
+ self.bindKey("esc", self._onCancel)
+ elif no:
+ self.bindKey("esc", self._onNo)
# Let the user add their controls
- super(dOkCancelDialog, self)._addControls()
+ super(dStandardButtonDialog, self)._addControls()
# Just in case user changed Self.Sizer, update our reference:
- sz = self.Sizer
+ bs = dabo.ui.dSizer("v")
+ bs.append((0, sz.DefaultBorder/2))
+ bs.append(sbs, "x")
+ bs.append((0, sz.DefaultBorder))
+ sz.append(bs, "x")
- if self.ButtonSizerPosition is None:
- # User code didn't add it, so we must.
- bs = dabo.ui.dSizer("v")
- bs.append((0, sz.DefaultBorder/2))
- bs.append(self.ButtonSizer, "x")
- bs.append((0, sz.DefaultBorder))
- sz.append(bs, "x")
-
- self.layout()
+ ################################################
+ # Handlers for the standard buttons
+ def _onOK(self, evt):
+ self.Accepted = True
+ self.onOK()
+ self.EndModal(kons.DLG_OK)
+ def _onCancel(self, evt):
+ self.onCancel()
+ self.EndModal(kons.DLG_CANCEL)
+ def _onYes(self, evt):
+ self.Accepted = True
+ self.onYes()
+ self.EndModal(kons.DLG_YES)
+ def _onNo(self, evt):
+ self.onNo()
+ self.EndModal(kons.DLG_NO)
+ def _onHelp(self, evt):
+ self.onHelp()
+ # The following are stub methods that can be overridden when needed.
+ def onOK(self): pass
+ def onCancel(self): pass
+ def onYes(self): pass
+ def onNo(self): pass
+ def onHelp(self): pass
+ ################################################
def addControls(self):
- """Use this method to add controls to the dialog.
-
- The OK/Cancel buttons will be added after this method runs,
so that they
- appear at the bottom of the dialog.
+ """Use this method to add controls to the dialog. The standard
buttons will be added
+ after this method runs, so that they appear at the bottom of
the dialog.
"""
pass
- def _setEscapeBehavior(self):
- """Bind/unbind the Cancel button to the escape key."""
- try:
- self.btnCancel.CancelButton = self.ReleaseOnEscape
- if self.ReleaseOnEscape:
- self.SetEscapeId(wx.ID_ANY)
- else:
- self.SetEscapeId(wx.ID_NONE)
- except AttributeError:
- # Button hasn't been added yet
- dabo.ui.callAfter(self._setEscapeBehavior)
-
-
def addControlSequence(self, seq):
"""This takes a sequence of 3-tuples or 3-lists, and adds
controls
to the dialog as a grid of labels and data controls. The first
element of
@@ -317,15 +377,6 @@
self.layout()
- def onOK(self, evt):
- self.Accepted = True
- self.EndModal(kons.DLG_OK)
-
- def onCancel(self, evt):
- self.Accepted = False
- self.EndModal(kons.DLG_CANCEL)
-
-
def _getAccepted(self):
return self._accepted
@@ -334,42 +385,72 @@
def _getButtonSizer(self):
- return getattr(self, "_btnSizer", None)
+ return getattr(self, "stdButtonSizer", None)
- def _getButtonSizerPosition(self):
- return self.ButtonSizer.getPositionInSizer()
-
-
def _getCancelButton(self):
return self.btnCancel
+ def _getHelpButton(self):
+ return self.btnHelp
+
+
def _getOKButton(self):
return self.btnOK
+ def _getNoButton(self):
+ return self.btnNo
+
+
+ def _getYesButton(self):
+ return self.btnYes
+
+
Accepted = property(_getAccepted, _setAccepted, None,
_("Specifies whether the user accepted the dialog, or
canceled. (bool)"))
ButtonSizer = property(_getButtonSizer, None, None,
_("Returns a reference to the sizer controlling the
Ok/Cancel buttons. (dSizer)"))
- ButtonSizerPosition = property(_getButtonSizerPosition, None, None,
- _("""Returns the position of the Ok/Cancel buttons in
the sizer. (int)"""))
-
CancelButton = property(_getCancelButton, None, None,
- _("Reference to the Cancel button on the form
(dButton)."))
+ _("Reference to the Cancel button on the form, if
present (dButton or None)."))
- LastPositionInSizer = ButtonSizerPosition ## backwards compatibility
-
+ HelpButton = property(_getHelpButton, None, None,
+ _("Reference to the Help button on the form, if present
(dButton or None)."))
+
+ NoButton = property(_getNoButton, None, None,
+ _("Reference to the No button on the form, if present
(dButton or None)."))
+
OKButton = property(_getOKButton, None, None,
- _("Reference to the OK button on the form (dButton)."))
+ _("Reference to the OK button on the form, if present
(dButton or None)."))
+ YesButton = property(_getYesButton, None, None,
+ _("Reference to the Yes button on the form, if present
(dButton or None)."))
+
+class dOkCancelDialog(dStandardButtonDialog):
+ def __init__(self, parent=None, properties=None, *args, **kwargs):
+ kwargs["Yes"] = kwargs["No"] = False
+ kwargs["OK"] = kwargs["Cancel"] = True
+ super(dOkCancelDialog, self).__init__(parent, properties,
*args, **kwargs)
+ self._baseClass = dOkCancelDialog
+
+class dYesNoDialog(dStandardButtonDialog):
+ def __init__(self, parent=None, properties=None, *args, **kwargs):
+ kwargs["Yes"] = kwargs["No"] = True
+ kwargs["OK"] = kwargs["Cancel"] = False
+ super(dYesNoDialog, self).__init__(parent, properties, *args,
**kwargs)
+ self._baseClass = dYesNoDialog
+
+
+
if __name__ == "__main__":
import test
test.Test().runTest(dDialog)
+ test.Test().runTest(dStandardButtonDialog)
test.Test().runTest(dOkCancelDialog)
+ test.Test().runTest(dYesNoDialog)
_______________________________________________
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]