dabo Commit
Revision 1885
Date: 2006-01-31 16:25:28 -0800 (Tue, 31 Jan 2006)
Author: ed

Changed:
U   trunk/dabo/dEvents.py
U   trunk/dabo/ui/uiwx/__init__.py
U   trunk/dabo/ui/uiwx/dBitmap.py
U   trunk/dabo/ui/uiwx/dBitmapButton.py
U   trunk/dabo/ui/uiwx/dFormMixin.py
U   trunk/dabo/ui/uiwx/dImage.py
U   trunk/dabo/ui/uiwx/dPemMixin.py

Log:
Added a Refresh event. This is raised when dForm.refresh() is called. All 
dPemMixin classes will receive it, and fire their refresh() hook method.

Added dynamic properties. Every property can be made dynamic by prefixing it 
with 'Dynamic'. Dynamic props are set to any callable function; when the object 
receives a Refresh event, the function's return value is used to set the value 
of the underlying property.

Example: given a label and a function 'currTime()' in a form that returns the 
current time, issuing the following:

        label.DynamicCaption = label.Form.currTime
        
will result in the label's Caption property being updated every time 
label.Form.refresh() is called with the value of the current time.

Also added two methods to dabo.ui for converting image data back to bitmaps and 
images. These were necessary because I noticed that when Editor.py was called 
from locations other than its own directory, the image file for the function 
button was not found. The solution was to convert the .png file to a data 
stream using wx.tools.img2py.py, and store that in Editor.py.


Diff:
Modified: trunk/dabo/dEvents.py
===================================================================
--- trunk/dabo/dEvents.py       2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/dEvents.py       2006-02-01 00:25:28 UTC (rev 1885)
@@ -725,3 +725,10 @@
                return issubclass(objectClass, dabo.ui.dForm)
        appliesToClass = classmethod(appliesToClass)
 
+
+class Refresh(Event):
+       """Occurs when the form wants the controls to refresh their 
appearance."""
+       def appliesToClass(eventClass, objectClass):
+               return issubclass(objectClass, dabo.ui.dForm)
+       appliesToClass = classmethod(appliesToClass)
+

Modified: trunk/dabo/ui/uiwx/__init__.py
===================================================================
--- trunk/dabo/ui/uiwx/__init__.py      2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/ui/uiwx/__init__.py      2006-02-01 00:25:28 UTC (rev 1885)
@@ -2,6 +2,7 @@
 import os
 import datetime
 import time
+import cStringIO
 
 ######################################################
 # Very first thing: check for proper wxPython build:
@@ -26,6 +27,7 @@
 del(_failedLibs)
 #######################################################
 import wx
+from wx import ImageFromStream, BitmapFromImage
 import dabo.ui
 import dabo.dConstants as kons
 from uiApp import uiApp
@@ -720,8 +722,23 @@
        dc.SetFont(fnt)
        ret = dc.GetTextExtent(txt)
        return ret
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Using the img2py.py script in the wx.tools folder, you can convert
+# an image to a text stream that can be included in a Python script.
+# These next two methods take the image data and return a
+# bitmap and an image, respectively.
+def bitmapFromData(data):
+       return BitmapFromImage(imageFromData(data))
        
+       
+def imageFromData(data):
+       stream = cStringIO.StringIO(data)
+       return ImageFromStream(stream)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
+
 # For applications that use the same image more than once,
 # this speeds up resolution of the requested image name.
 _bmpCache = {} 

Modified: trunk/dabo/ui/uiwx/dBitmap.py
===================================================================
--- trunk/dabo/ui/uiwx/dBitmap.py       2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/ui/uiwx/dBitmap.py       2006-02-01 00:25:28 UTC (rev 1885)
@@ -24,23 +24,31 @@
 
        def _getBitmap(self):
                return self.GetBitmap()
-       def _setBitmap(self, bmp):
+               
+       def _setBitmap(self, val):
                if self._constructed():
-                       if isinstance(bmp, basestring):
-                               bmp = dabo.ui.dIcons.getIconBitmap(bmp)
-                       elif not bmp:
+                       if isinstance(val, basestring):
+                               bmp = dabo.ui.dIcons.getIconBitmap(val)
+                       elif isinstance(val, wx.Bitmap):
+                               bmp = val
+                       elif not val:
                                bmp = wx.EmptyBitmap(1,1)
                                self.SetPosition((-100,-100))
                        self.SetBitmap(bmp)
                else:
                        self._properties["Bitmap"] = bmp
+                       
 
        def _getPicture(self):
                return self.GetBitmap()
+               
        def _setPicture(self, val):
                self._picture = val
                if self._constructed():
-                       bmp = dabo.ui.strToBmp(val)
+                       if isinstance(val, wx.Bitmap):
+                               bmp = val
+                       else:
+                               bmp = dabo.ui.strToBmp(val)
                        self.SetBitmap(bmp)
                else:
                        self._properties["Picture"] = val

Modified: trunk/dabo/ui/uiwx/dBitmapButton.py
===================================================================
--- trunk/dabo/ui/uiwx/dBitmapButton.py 2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/ui/uiwx/dBitmapButton.py 2006-02-01 00:25:28 UTC (rev 1885)
@@ -52,11 +52,14 @@
        
        def _getAutoSize(self):
                return self._autoSize
+               
        def _setAutoSize(self, val):
                self._autoSize = val
+               
        
        def _getBmpBorder(self):
                return self._bmpBorder
+               
        def _setBmpBorder(self, val):
                self._bmpBorder = val
                if self._autoSize:
@@ -66,6 +69,7 @@
        def _getCancelButton(self):
                # need to implement
                return False
+               
        def _setCancelButton(self, val):
                warnings.warn("CancelButton isn't implemented yet.", Warning)   
        
@@ -75,6 +79,7 @@
                        return self.Parent.GetDefaultItem() == self
                else:
                        return False
+                       
        def _setDefaultButton(self, val):
                if self._constructed():
                        if val:
@@ -93,37 +98,54 @@
        def _getDownBitmap(self):
                return self.GetBitmapSelected()
        
+       
        def _getDownPicture(self):
                return self._downPicture
+               
        def _setDownPicture(self, val):
                self._downPicture = val
                if self._constructed():
-                       self.SetBitmapSelected(dabo.ui.strToBmp(val, 
self._imgScale, self._imgWd, self._imgHt))
+                       if isinstance(val, wx.Bitmap):
+                               bmp = val
+                       else:
+                               bmp = dabo.ui.strToBmp(val, self._imgScale, 
self._imgWd, self._imgHt)
+                       self.SetBitmapSelected(bmp)
                else:
                        self._properties["DownPicture"] = val
 
+
        def _getFocusBitmap(self):
                return self.GetBitmapFocus()
+
        
        def _getFocusPicture(self):
                return self._focusPicture
+
        def _setFocusPicture(self, val):
                self._focusPicture = val
                if self._constructed():
-                       self.SetBitmapFocus(dabo.ui.strToBmp(val, 
self._imgScale, self._imgWd, self._imgHt))
+                       if isinstance(val, wx.Bitmap):
+                               bmp = val
+                       else:
+                               bmp = dabo.ui.strToBmp(val, self._imgScale, 
self._imgWd, self._imgHt)
+                       self.SetBitmapFocus(bmp)
                else:
                        self._properties["FocusPicture"] = val
 
+
        def _getImgHt(self):
                return self._imgHt
+
        def _setImgHt(self, val):
                self._imgHt = val
                if self._autoSize:
                        self.Picture = self.Picture
                        self.__sizeToBitmap()
-               
+       
+       
        def _getImgScale(self):
                return self._imgScale
+       
        def _setImgScale(self, val):
                self._imgScale = val
                if self._autoSize:
@@ -132,23 +154,31 @@
                                self.Picture = pic
                        self.__sizeToBitmap()
        
+       
        def _getImgWd(self):
                return self._imgWd
+       
        def _setImgWd(self, val):
                self._imgWd = val
                if self._autoSize:
                        self.Picture = self.Picture
                        self.__sizeToBitmap()
                
+               
        def _getNormalBitmap(self):
                return self.GetBitmapLabel()
        
+       
        def _getNormalPicture(self):
                return self._picture
+       
        def _setNormalPicture(self, val):
                self._picture = val
                if self._constructed():
-                       bmp = dabo.ui.strToBmp(val, self._imgScale, 
self._imgWd, self._imgHt)
+                       if isinstance(val, wx.Bitmap):
+                               bmp = val
+                       else:
+                               bmp = dabo.ui.strToBmp(val, self._imgScale, 
self._imgWd, self._imgHt)
                        self.SetBitmapLabel(bmp)
                        # If the others haven't been specified, default them to 
the same
                        if not self._downPicture:

Modified: trunk/dabo/ui/uiwx/dFormMixin.py
===================================================================
--- trunk/dabo/ui/uiwx/dFormMixin.py    2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/ui/uiwx/dFormMixin.py    2006-02-01 00:25:28 UTC (rev 1885)
@@ -479,13 +479,12 @@
                pass
 
 
-       def refresh(self):
+       def refresh(self, fromRefresh=False):
                """Refreshed the values of the controls, and also calls the
                wxPython Refresh to update the form.
                """
                try:
                        self.refreshControls()
-                       self.Refresh()
                except dabo.ui.deadObjectException:
                        # This can happen if a form is released when there is a 
                        # pending callAfter() refresh.
@@ -506,6 +505,8 @@
                try:
                        self.setStatusText(self.getCurrentRecordText(grid=grid))
                except: pass
+               # Now update anything that needs refreshing
+               self.raiseEvent(dEvents.Refresh)
 
 
        def onDebugDlg(self, evt):

Modified: trunk/dabo/ui/uiwx/dImage.py
===================================================================
--- trunk/dabo/ui/uiwx/dImage.py        2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/ui/uiwx/dImage.py        2006-02-01 00:25:28 UTC (rev 1885)
@@ -131,22 +131,27 @@
                return self._picture
                
        def _setPic(self, val):
-               # Don't allow built-in graphics to be displayed here
-               if not os.path.exists(val):
-                       if val:
-                               # They passed a non-existent image file
-                               raise IOError, "No file named '%s' exists." % 
val
-                       else:
-                               # Empty string passed; clear any current image
-                               self._picture = ""
-                               self._rotation = 0
-                               self._bmp = wx.EmptyBitmap(1, 1, 1)
-                               self.__image = self._bmp.ConvertToImage()
-                               self._showPic()
-                               return
-               self._picture = val
-               self._rotation = 0
-               self._Image.LoadFile(val)
+               if isinstance(val, wx.Image):
+                       # An image stored as a stream is being used
+                       self.__image = val
+                       self._picture = "(stream)"
+               else:
+                       # Don't allow built-in graphics to be displayed here
+                       if not os.path.exists(val):
+                               if val:
+                                       # They passed a non-existent image file
+                                       raise IOError, "No file named '%s' 
exists." % val
+                               else:
+                                       # Empty string passed; clear any 
current image
+                                       self._picture = ""
+                                       self._rotation = 0
+                                       self._bmp = wx.EmptyBitmap(1, 1, 1)
+                                       self.__image = 
self._bmp.ConvertToImage()
+                                       self._showPic()
+                                       return
+                       self._picture = val
+                       self._rotation = 0
+                       self._Image.LoadFile(val)
                self._imgProp = float(self._Image.GetWidth()) / 
float(self._Image.GetHeight())
                self._showPic()
                

Modified: trunk/dabo/ui/uiwx/dPemMixin.py
===================================================================
--- trunk/dabo/ui/uiwx/dPemMixin.py     2006-02-01 00:09:18 UTC (rev 1884)
+++ trunk/dabo/ui/uiwx/dPemMixin.py     2006-02-01 00:25:28 UTC (rev 1885)
@@ -9,6 +9,9 @@
 import dabo.dColors as dColors
 import dKeys
 from dabo.dObject import dObject
+# This can't be an attribute, since it is used in the __getattr__() 
+# method. It designates properties that can be dynamically updated.
+_prefixDynamic = "Dynamic"
 
 
 class dPemMixin(dPemMixinBase):
@@ -24,7 +27,6 @@
                # This is the major, common constructor code for all the 
dabo/ui/uiwx 
                # classes. The __init__'s of each class are just thin wrappers 
to this
                # code.
-
                self._properties = {}
                
                # Lots of useful wx props are actually only settable before the
@@ -45,6 +47,9 @@
                # type.
                threeWayInit = (type(preClass) == types.FunctionType)
                
+               # Dictionary to keep track of Dynamic properties
+               self._dynamic = {}
+               
                if threeWayInit:
                        # Instantiate the wx Pre object
                        pre = preClass()
@@ -175,8 +180,30 @@
                except Exception, e:
                        print e
                        return False
-
+       
+       
+       def __getattr__(self, att):
+               ret = None
+               if att.startswith(_prefixDynamic):
+                       attFunc = self._dynamic.get(att)
+                       if callable(attFunc):
+                               ret = attFunc()
+               if ret is None:
+                       ret = super(dPemMixin, self).__getattr__(att)
+               return ret
+       
+       
+       def __setattr__(self, att, val):
+               isSet = False
+               if att.startswith(_prefixDynamic):
+                       if callable(val):
+                               self._dynamic[att] = val
+                               isSet = True
+               if not isSet:
+                       super(dPemMixin, self).__setattr__(att, val)
                
+                               
+               
        def _beforeInit(self, pre):
                self._acceleratorTable = {}
                self._name = "?"
@@ -293,6 +320,11 @@
                self.bindEvent(dEvents.Create, self.__onCreate)
                self.bindEvent(dEvents.ChildBorn, self.__onChildBorn)
                
+               if isinstance(self, (wx.Frame, wx.Dialog)):
+                       self.bindEvent(dEvents.Refresh, self.__onRefresh)
+               else:
+                       self.Form.bindEvent(dEvents.Refresh, 
self.__refreshDynamicProps)
+
                self.initEvents()
 
 
@@ -796,12 +828,34 @@
                """Sets focus to the object."""
                self.SetFocus()
                
+
+       def __onRefresh(self, evt):
+               """Update any dynamic properties, and then call
+               the refresh() hook.
+               """
+               self.__refreshDynamicProps()
+               self.refresh()
+               
+               
+       def __refreshDynamicProps(self):
+               """Refreshes the object's contents, and/or repaints the object.
+               Also updates any dynamic properties.
+               """
+               needRefresh = False
+               for prop, func in self._dynamic.items():
+                       baseProp = prop[len(_prefixDynamic):]
+                       exec("self.%s = func()" % baseProp)
+                       needRefresh = True
+               if needRefresh:
+                       # Call the native refresh
+                       self.Refresh()
        
+       
        def refresh(self):
-               """Refreshes the object's contents, and/or repaints the 
object."""
-               self.Refresh()
-       
-       
+               """Hook method to allow a developer to customize refresh 
behavior."""
+               pass
+               
+               
        def show(self):
                """Make the object visible."""
                self.Show(True)




_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev

Reply via email to