Paul McNett wrote:
Okay, I'm finding it works fine on Linux using 8, 16, and 24 bit, and on Windows using 16, 24, and 32 bit, but on Mac it just hangs with the beachball. So... time to hack on Mac for a while! One thing I'm noticing on Mac is that wx.GetDisplayDepth() returns None.

On Linux and Windows, I keep the DC for drawing the test color around, to avoid any overhead in creating it and deleting it over and over again. However, on Mac it seems that until the DC is deleted, we can't access the new color in the bitmap.

So, my patch has bracketed code based on platform. I humbly attach it for review.

Again, with this patch I'm able to create objects with proper HitTest behavior on Windows, Mac, and Linux with various display depths. I think the practical minimum is probably 16 bits, though.

Paul
Index: FloatCanvas.py
===================================================================
--- FloatCanvas.py	(revision 57217)
+++ FloatCanvas.py	(working copy)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
 from __future__ import division
+import sys
 
 try:
     import numpy as N
@@ -13,6 +14,7 @@
 from Utilities import BBox
 import GUIMode
 
+mac = sys.platform.startswith("darwin")
 
 ## A global variable to hold the Pixels per inch that wxWindows thinks is in use
 ## This is used for scaling fonts.
@@ -91,19 +93,53 @@
     def __getattr__(self, name):
         return getattr(self._NativeEvent, name)
 
+_testBitmap = None
+_testDC = None
 def _cycleidxs(indexcount, maxvalue, step):
 
     """!
     Utility function used by _colorGenerator
 
     """
-    
+    def colormatch(color):
+        """Return True if the color comes back from the bitmap identically."""
+        if len(color) < 3:
+            return True
+        global _testBitmap, _testDC
+        B = _testBitmap
+        if not mac:
+            dc = _testDC
+        if not B:
+            B = _testBitmap = wx.EmptyBitmap(1, 1)
+            if not mac:
+                dc = _testDC = wx.MemoryDC()
+        if mac:
+            dc = wx.MemoryDC()
+        dc.SelectObject(B)
+        dc.SetBackground(wx.BLACK_BRUSH)
+        dc.Clear()
+        dc.SetPen(wx.Pen(wx.Color(*color), 4))
+        dc.DrawPoint(0,0)
+        if mac:
+            del dc
+            pdata = wx.AlphaPixelData(B)
+            pacc = pdata.GetPixels()
+            pacc.MoveTo(pdata, 0, 0)
+            outcolor = pacc.Get()[:3]
+        else:
+            outcolor = dc.GetPixel(0,0)
+        return outcolor == color
+
     if indexcount == 0:
         yield ()
     else:
         for idx in xrange(0, maxvalue, step):
             for tail in _cycleidxs(indexcount - 1, maxvalue, step):
-                yield (idx, ) + tail
+                color = (idx, ) + tail
+                if not colormatch(color):
+                    continue
+                yield color
+                
 
 def _colorGenerator():
 
@@ -112,22 +148,8 @@
     Generates a series of unique colors used to do hit-tests with the Hit
     Test bitmap
     """
+    return _cycleidxs(indexcount=3, maxvalue=256, step=1)
 
-    depth = wx.GetDisplayDepth()
-##    ##there have been problems with 16 bbp displays, to I'm disabling this for now.
-##    if depth == 16:
-##        print "Warning: There have been problems with hit-testing on 16bbp displays"
-##        step = 8
-    if depth >= 24:
-        step = 1
-    else:
-        msg= ["ColorGenerator does not work with depth = %s" % depth]
-        msg.append("It is required for hit testing -- binding events to mouse")
-        msg.append("actions on objects on the Canvas.")
-        msg.append("Please set your display to 24bit")
-        msg.append("Alternatively, the code could be adapted to 16 bit if that's required")
-        raise FloatCanvasError(msg)
-    return _cycleidxs(indexcount=3, maxvalue=256, step=step)
 
 class DrawObject:
     """!
@@ -2499,7 +2521,7 @@
             pacc.MoveTo(pdata, xy[0], xy[1])
             return pacc.Get()[:3]
     else:
-        HitTestBitmapDepth = 24
+        HitTestBitmapDepth = -1  ## (display depth in use)
         #print "using pre-2.8 hit test code"
         def GetHitTestColor(self,  xy ):
             dc = wx.MemoryDC()
@@ -2509,6 +2531,8 @@
                 dc.SelectObject(self._HTBitmap)
             hitcolor = dc.GetPixelPoint( xy )
             return hitcolor.Get()
+
+
     def UnBindAll(self):
         """
         Removes all bindings to Objects
_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to