X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7e664d85e6512d807ce2eb186ed9e0bbd60d6e8b..5172800e29f9c4b3f4dfa9737f80114a61e55f1f:/wxPython/src/pseudodc.cpp diff --git a/wxPython/src/pseudodc.cpp b/wxPython/src/pseudodc.cpp index dc2d2eb1af..02788b1fb1 100644 --- a/wxPython/src/pseudodc.cpp +++ b/wxPython/src/pseudodc.cpp @@ -10,16 +10,101 @@ ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" +//include "wx/wxprec.h" +#undef DEBUG +#include +#include "wx/wxPython/wxPython.h" #include "wx/wxPython/pseudodc.h" -#include // wxList based class definitions #include 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;iGetData()->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