]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/src/pseudodc.cpp
Don't use hidden items for size calc (patch 1698314)
[wxWidgets.git] / wxPython / src / pseudodc.cpp
index dc2d2eb1af03653d8cc5b47c66912b34ba097978..02788b1fb1df99d5952a2972b6e78d1735dc9803 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 
 // For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
+//include "wx/wxprec.h"
 
+#undef DEBUG
+#include <Python.h>
+#include "wx/wxPython/wxPython.h"
 #include "wx/wxPython/pseudodc.h"
-#include <stdio.h>
 
 // wxList based class definitions
 #include <wx/listimpl.cpp>
 WX_DEFINE_LIST(pdcOpList);
 WX_DEFINE_LIST(pdcObjectList);
 
+//----------------------------------------------------------------------------
+// Helper functions used for drawing greyed out versions of objects
+//----------------------------------------------------------------------------
+wxColour &MakeColourGrey(const wxColour &c)
+{
+    static wxColour rval;
+    rval.Set(byte((230-c.Red())*0.7+c.Red()),
+             byte((230-c.Green())*0.7+c.Green()),
+             byte((230-c.Blue())*0.7+c.Blue()));
+    return rval;
+}
+wxBrush &GetGreyBrush(wxBrush &brush)
+{
+       static wxBrush b;
+       wxColour c;
+       b = brush;
+       c = MakeColourGrey(brush.GetColour());
+       b.SetColour(c);
+       return b;
+}
+
+wxPen &GetGreyPen(wxPen &pen)
+{
+       static wxPen p;
+       wxColour c;
+       p = pen;
+       c = MakeColourGrey(pen.GetColour());
+       p.SetColour(c);
+       return p;
+}
+
+void GreyOutImage(wxImage &img)
+{
+    unsigned char *data = img.GetData();
+    unsigned char r,g,b;
+    unsigned char mr,mg,mb;
+    int i, tst;
+    int len = img.GetHeight()*img.GetWidth()*3;
+    if (img.HasMask())
+    {
+        mr = img.GetMaskRed();
+        mg = img.GetMaskGreen();
+        mb = img.GetMaskBlue();
+    }
+    tst=0;
+    for (i=0;i<len;i+=3)
+    {
+        r=data[i]; g=data[i+1]; b=data[i+2];
+        if (!img.HasMask() || 
+            r!=mr || g!=mg || b!=mb)
+        {
+            if (!tst)
+            {
+                tst=1;
+            }
+            r = (unsigned char)((230.0-r)*0.7+r);
+            g = (unsigned char)((230.0-g)*0.7+g);
+            b = (unsigned char)((230.0-b)*0.7+b);
+            data[i]=r; data[i+1]=g; data[i+2]=b;
+        }
+    }
+}
+
+wxIcon &GetGreyIcon(wxIcon &icon)
+{
+    wxBitmap bmp;
+    bmp.CopyFromIcon(icon);
+    wxImage img = bmp.ConvertToImage();
+    GreyOutImage(img);
+    wxBitmap bmp2(img,32);
+    static wxIcon rval;
+    rval.CopyFromBitmap(bmp2);
+    return rval;
+}
+
+wxBitmap &GetGreyBitmap(wxBitmap &bmp)
+{
+    wxImage img = bmp.ConvertToImage();
+    GreyOutImage(img);
+    static wxBitmap rval(img,32);
+    return rval;
+}
+
 // ============================================================================
 // various pdcOp class implementation methods
 // ============================================================================
@@ -154,7 +239,7 @@ void pdcObject::DrawToDC(wxDC *dc)
     pdcOpList::Node *node = m_oplist.GetFirst(); 
     while(node)
     {
-        node->GetData()->DrawToDC(dc);
+        node->GetData()->DrawToDC(dc, m_greyedout);
         node = node->GetNext();
     }
 }
@@ -177,6 +262,27 @@ void pdcObject::Translate(wxCoord dx, wxCoord dy)
        }
 }
 
+// ----------------------------------------------------------------------------
+// SetGreyedOut - set the greyout member and cache grey versions of everything
+// if greyout is true
+// ----------------------------------------------------------------------------
+void pdcObject::SetGreyedOut(bool greyout) 
+{
+       m_greyedout=greyout;
+       if (greyout)
+       {
+               pdcOpList::Node *node = m_oplist.GetFirst(); 
+        pdcOp *obj;
+               while(node)
+               {
+
+                       obj = node->GetData();
+            obj->CacheGrey();
+                       node = node->GetNext();
+               }
+       }
+}
+
 // ============================================================================
 // wxPseudoDC implementation
 // ============================================================================
@@ -321,6 +427,170 @@ void wxPseudoDC::DrawIdToDC(int id, wxDC *dc)
     if (pt) pt->GetData()->DrawToDC(dc);
 }
 
+// ----------------------------------------------------------------------------
+// SetIdGreyedOut - Set the greyedout member of id
+// ----------------------------------------------------------------------------
+void wxPseudoDC::SetIdGreyedOut(int id, bool greyout)
+{
+    pdcObjectList::Node *pt = FindObjNode(id);
+    if (pt) pt->GetData()->SetGreyedOut(greyout);
+}
+
+// ----------------------------------------------------------------------------
+// GetIdGreyedOut - Get the greyedout member of id
+// ----------------------------------------------------------------------------
+bool wxPseudoDC::GetIdGreyedOut(int id)
+{
+    pdcObjectList::Node *pt = FindObjNode(id);
+    if (pt) return pt->GetData()->GetGreyedOut();
+       else return false;
+}
+
+// ----------------------------------------------------------------------------
+// FindObjectsByBBox - Return a list of all the ids whose bounding boxes
+//                     contain (x,y)
+// ----------------------------------------------------------------------------
+PyObject *wxPseudoDC::FindObjectsByBBox(wxCoord x, wxCoord y)
+{
+    //wxPyBlock_t blocked = wxPyBeginBlockThreads();
+    pdcObjectList::Node *pt = m_objectlist.GetFirst();
+    pdcObject *obj;
+    PyObject* pyList = NULL;
+    pyList = PyList_New(0);
+    wxRect r;
+    while (pt) 
+    {
+        obj = pt->GetData();
+        r = obj->GetBounds();
+        if (obj->IsBounded() && r.Contains(x,y))
+        {
+            PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
+            PyList_Insert(pyList, 0, pyObj);
+            Py_DECREF(pyObj);
+        }
+        pt = pt->GetNext();
+    }
+    //wxPyEndBlockThreads(blocked);
+    return pyList;
+}
+
+// ----------------------------------------------------------------------------
+// FindObjects - Return a list of all the ids that draw to (x,y)
+// ----------------------------------------------------------------------------
+PyObject *wxPseudoDC::FindObjects(wxCoord x, wxCoord y, 
+                                  wxCoord radius, const wxColor& bg)
+{
+    //wxPyBlock_t blocked = wxPyBeginBlockThreads();
+    pdcObjectList::Node *pt = m_objectlist.GetFirst();
+    pdcObject *obj;
+    PyObject* pyList = NULL;
+    pyList = PyList_New(0);
+    wxBrush bgbrush(bg);
+    wxPen bgpen(bg);
+    // special case radius = 0
+    if (radius == 0)
+    {
+        wxBitmap bmp(4,4,24);
+        wxMemoryDC memdc;
+        wxColor pix;
+        wxRect viewrect(x-2,y-2,4,4);
+        // setup the memdc for rendering
+        memdc.SelectObject(bmp);
+        memdc.SetBackground(bgbrush);
+        memdc.Clear();
+        memdc.SetDeviceOrigin(2-x,2-y);
+        while (pt) 
+        {
+            obj = pt->GetData();
+            if (obj->IsBounded() && obj->GetBounds().Contains(x,y))
+            {
+                // start clean
+                memdc.SetBrush(bgbrush);
+                memdc.SetPen(bgpen);
+                memdc.DrawRectangle(viewrect);
+                // draw the object
+                obj->DrawToDC(&memdc);
+                memdc.GetPixel(x,y,&pix);
+                // clear and update rgn2
+                if (pix != bg)
+                {
+                    PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
+                    PyList_Insert(pyList, 0, pyObj);
+                    Py_DECREF(pyObj);
+                }
+            }
+            pt = pt->GetNext();
+        }
+        memdc.SelectObject(wxNullBitmap);
+    }
+    else
+    {
+        wxRect viewrect(x-radius,y-radius,2*radius,2*radius);
+        wxBitmap maskbmp(2*radius,2*radius,24);
+        wxMemoryDC maskdc;
+        // create bitmap with circle for masking
+        maskdc.SelectObject(maskbmp);
+        maskdc.SetBackground(*wxBLACK_BRUSH);
+        maskdc.Clear();
+        maskdc.SetBrush(*wxWHITE_BRUSH);
+        maskdc.SetPen(*wxWHITE_PEN);
+        maskdc.DrawCircle(radius,radius,radius);
+        // now setup a memdc for rendering our object
+        wxBitmap bmp(2*radius,2*radius,24);
+        wxMemoryDC memdc;
+        memdc.SelectObject(bmp);
+        // set the origin so (x,y) is in the bmp center
+        memdc.SetDeviceOrigin(radius-x,radius-y);
+        // a region will be used to see if the result is empty
+        wxRegion rgn2;
+        while (pt) 
+        {
+            obj = pt->GetData();
+            if (obj->IsBounded() && viewrect.Intersects(obj->GetBounds()))
+            {
+                // start clean
+                //memdc.Clear();
+                memdc.SetBrush(bgbrush);
+                memdc.SetPen(bgpen);
+                memdc.DrawRectangle(viewrect);
+                // draw the object
+                obj->DrawToDC(&memdc);
+                // remove background color
+                memdc.SetLogicalFunction(wxXOR);
+                memdc.SetBrush(bgbrush);
+                memdc.SetPen(bgpen);
+                memdc.DrawRectangle(viewrect);
+                memdc.SetLogicalFunction(wxCOPY);
+#ifdef __WXMAC__
+                // wxAND is not supported on wxMac, but it doesn't seem to
+                // hurt anything to use wxCOPY instead...
+                memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxCOPY);
+#else
+                // AND with circle bitmap
+                memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxAND);
+#endif
+                // clear and update rgn2
+                memdc.SelectObject(wxNullBitmap);
+                rgn2.Clear();
+                rgn2.Union(bmp, *wxBLACK);
+                //rgn2.Intersect(rgn);
+                memdc.SelectObject(bmp);
+                if (!rgn2.IsEmpty())
+                {
+                    PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
+                    PyList_Insert(pyList, 0, pyObj);
+                    Py_DECREF(pyObj);
+                }
+            }
+            pt = pt->GetNext();
+        }
+        maskdc.SelectObject(wxNullBitmap);
+        memdc.SelectObject(wxNullBitmap);
+    }
+    //wxPyEndBlockThreads(blocked);
+    return pyList;
+}
+
 // ----------------------------------------------------------------------------
 // DrawToDCClipped - play back the op list to the DC but clip any objects
 //                   known to be not in rect.  This is a coarse level of