Updates from Paul

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41648 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-10-05 23:53:44 +00:00
parent b7a0abc732
commit 6f67d53729
4 changed files with 519 additions and 122 deletions

View File

@@ -10,16 +10,101 @@
/////////////////////////////////////////////////////////////////////////////
// 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,164 @@ 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);
// AND with circle bitmap
memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxAND);
// 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