mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-05 03:20:08 +01:00
Begin adding PseudoDC
This commit is contained in:
55
etg/pseudodc.py
Normal file
55
etg/pseudodc.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/pseudodc.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 26-Jul-2016
|
||||
# Copyright: (c) 2016 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_adv"
|
||||
NAME = "pseudodc" # Base name of the file to generate to for this script
|
||||
DOCSTRING = ""
|
||||
|
||||
# The classes and/or the basename of the Doxygen XML files to be processed by
|
||||
# this script.
|
||||
ITEMS = [ ]
|
||||
|
||||
OTHERDEPS = [ 'src/pseudodc.h',
|
||||
'src/pseudodc.cpp',
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def run():
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, ITEMS)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for
|
||||
# customizing the generated code and docstrings.
|
||||
|
||||
# The PseudoDC classes are not in wxWidgets, so there is no Doxygen XML
|
||||
# for them. That means we'll have to construct each of the extractor
|
||||
# objects from scratch.
|
||||
|
||||
module.addHeaderCode('#include "pseudodc.h"')
|
||||
module.includeCppCode('src/pseudodc.cpp')
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.doCommonTweaks(module)
|
||||
tools.runGenerators(module)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
626
src/pseudodc.cpp
Normal file
626
src/pseudodc.cpp
Normal file
@@ -0,0 +1,626 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/pseudodc.cpp
|
||||
// Purpose: Implementation of the wxPseudoDC classes
|
||||
// Author: Paul Lanier
|
||||
// Modified by: Robin Dunn
|
||||
//
|
||||
// Created: 05/25/06
|
||||
// Copyright: (c) 2006-2016 Total Control Software
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
//include "wx/wxprec.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <Python.h>
|
||||
#include "wx/wxPython/wxPython.h"
|
||||
#include "wx/wxPython/pseudodc.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
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawPolyPolygonOp constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawPolyPolygonOp::pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
|
||||
wxCoord xoffset, wxCoord yoffset, wxPolygonFillMode fillStyle)
|
||||
{
|
||||
m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
|
||||
int total_n=0;
|
||||
if (n)
|
||||
{
|
||||
m_count = new int[n];
|
||||
for(int i=0; i<n; i++)
|
||||
{
|
||||
total_n+=count[i];
|
||||
m_count[i]=count[i];
|
||||
}
|
||||
if (total_n)
|
||||
{
|
||||
m_points = new wxPoint[total_n];
|
||||
for(int j=0; j<total_n; j++)
|
||||
m_points[j] = points[j];
|
||||
}
|
||||
else m_points=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_points=NULL;
|
||||
m_count=NULL;
|
||||
}
|
||||
m_totaln = total_n;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawPolyPolygonOp destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawPolyPolygonOp::~pdcDrawPolyPolygonOp()
|
||||
{
|
||||
if (m_points) delete m_points;
|
||||
if (m_count) delete m_count;
|
||||
m_points=NULL;
|
||||
m_count=NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawLinesOp constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawLinesOp::pdcDrawLinesOp(int n, wxPoint points[],
|
||||
wxCoord xoffset, wxCoord yoffset)
|
||||
{
|
||||
m_n=n; m_xoffset=xoffset; m_yoffset=yoffset;
|
||||
if (n)
|
||||
{
|
||||
m_points = new wxPoint[n];
|
||||
for (int i=0; i<n; i++)
|
||||
m_points[i] = points[i];
|
||||
}
|
||||
else m_points=NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawLinesOp destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawLinesOp::~pdcDrawLinesOp()
|
||||
{
|
||||
if (m_points) delete m_points;
|
||||
m_points=NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawPolygonOp constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawPolygonOp::pdcDrawPolygonOp(int n, wxPoint points[],
|
||||
wxCoord xoffset, wxCoord yoffset, wxPolygonFillMode fillStyle)
|
||||
{
|
||||
m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
|
||||
if (n)
|
||||
{
|
||||
m_points = new wxPoint[n];
|
||||
for (int i=0; i<n; i++)
|
||||
m_points[i] = points[i];
|
||||
}
|
||||
else m_points=NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawPolygonOp destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawPolygonOp::~pdcDrawPolygonOp()
|
||||
{
|
||||
if (m_points) delete m_points;
|
||||
m_points=NULL;
|
||||
}
|
||||
|
||||
#if wxUSE_SPLINES
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawSplineOp constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawSplineOp::pdcDrawSplineOp(int n, wxPoint points[])
|
||||
{
|
||||
m_n=n;
|
||||
if (n)
|
||||
{
|
||||
m_points = new wxPoint[n];
|
||||
for(int i=0; i<n; i++)
|
||||
m_points[i] = points[i];
|
||||
}
|
||||
else m_points=NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// pdcDrawSplineOp destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcDrawSplineOp::~pdcDrawSplineOp()
|
||||
{
|
||||
if (m_points) delete m_points;
|
||||
m_points=NULL;
|
||||
}
|
||||
#endif // wxUSE_SPLINES
|
||||
|
||||
// ============================================================================
|
||||
// pdcObject implementation
|
||||
// ============================================================================
|
||||
// ----------------------------------------------------------------------------
|
||||
// DrawToDC - play back the op list to the DC
|
||||
// ----------------------------------------------------------------------------
|
||||
void pdcObject::DrawToDC(wxDC *dc)
|
||||
{
|
||||
pdcOpList::compatibility_iterator node = m_oplist.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
node->GetData()->DrawToDC(dc, m_greyedout);
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Translate - translate all the operations by some dx,dy
|
||||
// ----------------------------------------------------------------------------
|
||||
void pdcObject::Translate(wxCoord dx, wxCoord dy)
|
||||
{
|
||||
pdcOpList::compatibility_iterator node = m_oplist.GetFirst();
|
||||
while(node)
|
||||
{
|
||||
node->GetData()->Translate(dx,dy);
|
||||
node = node->GetNext();
|
||||
}
|
||||
if (m_bounded)
|
||||
{
|
||||
m_bounds.x += dx;
|
||||
m_bounds.y += 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::compatibility_iterator node = m_oplist.GetFirst();
|
||||
pdcOp *obj;
|
||||
while(node)
|
||||
{
|
||||
obj = node->GetData();
|
||||
obj->CacheGrey();
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxPseudoDC implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
wxPseudoDC::~wxPseudoDC()
|
||||
{
|
||||
// delete all the nodes in the list
|
||||
RemoveAll();
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ClearAll - remove all nodes from list
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::RemoveAll(void)
|
||||
{
|
||||
m_objectlist.Clear();
|
||||
m_objectIndex.clear();
|
||||
m_currId = -1;
|
||||
m_lastObject = NULL;
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetLen - return the number of operations in the current op list
|
||||
// ----------------------------------------------------------------------------
|
||||
int wxPseudoDC::GetLen(void)
|
||||
{
|
||||
pdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
|
||||
int len=0;
|
||||
while (pt)
|
||||
{
|
||||
len += pt->GetData()->GetLen();
|
||||
pt = pt->GetNext();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// FindObject - find and return an object node by id. If node doesn't exist
|
||||
// and create is true then create one and return it. Otherwise
|
||||
// return NULL.
|
||||
// ----------------------------------------------------------------------------
|
||||
pdcObject *wxPseudoDC::FindObject(int id, bool create)
|
||||
{
|
||||
// see if last operation was for same id
|
||||
//~ if (m_lastObject && m_lastObject->GetId() == id)
|
||||
//~ return m_lastObject;
|
||||
// if not then search for it
|
||||
pdcObjectHash::iterator lookup = m_objectIndex.find(id);
|
||||
if (lookup == m_objectIndex.end()) {//not found
|
||||
if (create) {
|
||||
m_lastObject = new pdcObject(id);
|
||||
m_objectlist.Append(m_lastObject);
|
||||
pdcObjectHash::value_type insert(id, m_lastObject);
|
||||
m_objectIndex.insert(insert);
|
||||
return m_lastObject;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else { //found
|
||||
return lookup->second;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AddToList - Add a node to the list at the end (preserve draw order)
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::AddToList(pdcOp *newOp)
|
||||
{
|
||||
pdcObject *obj = FindObject(m_currId, true);
|
||||
obj->AddOp(newOp);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ClearID - remove all the operations associated with a single ID
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::ClearId(int id)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj) obj->Clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RemoveID - Remove the object node (and all operations) associated with an id
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::RemoveId(int id)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj)
|
||||
{
|
||||
if (m_lastObject == obj)
|
||||
m_lastObject = obj;
|
||||
m_objectlist.DeleteObject(obj);
|
||||
}
|
||||
m_objectIndex.erase(id);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetIdBounds - Set the bounding rect for a given id
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::SetIdBounds(int id, wxRect& rect)
|
||||
{
|
||||
pdcObject *obj = FindObject(id, true);
|
||||
obj->SetBounds(rect);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetIdBounds - Get the bounding rect for a given id
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::GetIdBounds(int id, wxRect& rect)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj && obj->IsBounded())
|
||||
rect = obj->GetBounds();
|
||||
else
|
||||
rect.x = rect.y = rect.width = rect.height = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// TranslateId - Translate all the operations of a single id
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj) obj->Translate(dx,dy);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DrawIdToDC - Draw a specific id to the dc passed in
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::DrawIdToDC(int id, wxDC *dc)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj) obj->DrawToDC(dc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetIdGreyedOut - Set the greyedout member of id
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::SetIdGreyedOut(int id, bool greyout)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj) obj->SetGreyedOut(greyout);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetIdGreyedOut - Get the greyedout member of id
|
||||
// ----------------------------------------------------------------------------
|
||||
bool wxPseudoDC::GetIdGreyedOut(int id)
|
||||
{
|
||||
pdcObject *obj = FindObject(id);
|
||||
if (obj) return obj->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::compatibility_iterator 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::compatibility_iterator 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);
|
||||
memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxCOPY);
|
||||
// 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
|
||||
// clipping to speed things up when lots of objects are off
|
||||
// screen and doesn't affect the dc level clipping
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect)
|
||||
{
|
||||
pdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
|
||||
pdcObject *obj;
|
||||
while (pt)
|
||||
{
|
||||
obj = pt->GetData();
|
||||
if (!obj->IsBounded() || rect.Intersects(obj->GetBounds()))
|
||||
obj->DrawToDC(dc);
|
||||
pt = pt->GetNext();
|
||||
}
|
||||
}
|
||||
void wxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region)
|
||||
{
|
||||
pdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
|
||||
pdcObject *obj;
|
||||
while (pt)
|
||||
{
|
||||
obj = pt->GetData();
|
||||
if (!obj->IsBounded() ||
|
||||
(region.Contains(obj->GetBounds()) != wxOutRegion))
|
||||
obj->DrawToDC(dc);
|
||||
pt = pt->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DrawToDC - play back the op list to the DC
|
||||
// ----------------------------------------------------------------------------
|
||||
void wxPseudoDC::DrawToDC(wxDC *dc)
|
||||
{
|
||||
pdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
|
||||
while (pt)
|
||||
{
|
||||
pt->GetData()->DrawToDC(dc);
|
||||
pt = pt->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
829
src/pseudodc.h
Normal file
829
src/pseudodc.h
Normal file
@@ -0,0 +1,829 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: pseudodc.h
|
||||
// Purpose: wxPseudoDC classes
|
||||
// Author: Paul Lanier
|
||||
// Modified by: Robin Dunn
|
||||
//
|
||||
// Created: 05/25/06
|
||||
// Copyright: (c) 2006-2016 Total Control Software
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_PSUEDO_DC_H_BASE_
|
||||
#define _WX_PSUEDO_DC_H_BASE_
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Base class for all pdcOp classes
|
||||
//----------------------------------------------------------------------------
|
||||
class pdcOp
|
||||
{
|
||||
public:
|
||||
// Constructor and Destructor
|
||||
pdcOp() {}
|
||||
virtual ~pdcOp() {}
|
||||
|
||||
// Virtual Drawing Methods
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)=0;
|
||||
virtual void Translate(wxCoord WXUNUSED(dx), wxCoord WXUNUSED(dy)) {}
|
||||
virtual void CacheGrey() {}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// declare a list class for list of pdcOps
|
||||
//----------------------------------------------------------------------------
|
||||
WX_DECLARE_LIST(pdcOp, pdcOpList);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Helper functions used for drawing greyed out versions of objects
|
||||
//----------------------------------------------------------------------------
|
||||
wxColour &MakeColourGrey(const wxColour &c);
|
||||
wxBrush &GetGreyBrush(wxBrush &brush);
|
||||
wxPen &GetGreyPen(wxPen &pen);
|
||||
wxIcon &GetGreyIcon(wxIcon &icon);
|
||||
wxBitmap &GetGreyBitmap(wxBitmap &bmp);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Classes derived from pdcOp
|
||||
// There is one class for each method mirrored from wxDC to wxPseudoDC
|
||||
//----------------------------------------------------------------------------
|
||||
class pdcSetFontOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetFontOp(const wxFont& font)
|
||||
{m_font=font;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetFont(m_font);}
|
||||
protected:
|
||||
wxFont m_font;
|
||||
};
|
||||
|
||||
class pdcSetBrushOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetBrushOp(const wxBrush& brush)
|
||||
{m_greybrush=m_brush=brush;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (!grey) dc->SetBrush(m_brush);
|
||||
else dc->SetBrush(m_greybrush);
|
||||
}
|
||||
virtual void CacheGrey() {m_greybrush=GetGreyBrush(m_brush);}
|
||||
protected:
|
||||
wxBrush m_brush;
|
||||
wxBrush m_greybrush;
|
||||
};
|
||||
|
||||
class pdcSetBackgroundOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetBackgroundOp(const wxBrush& brush)
|
||||
{m_greybrush=m_brush=brush;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (!grey) dc->SetBackground(m_brush);
|
||||
else dc->SetBackground(m_greybrush);
|
||||
}
|
||||
virtual void CacheGrey() {m_greybrush=GetGreyBrush(m_brush);}
|
||||
protected:
|
||||
wxBrush m_brush;
|
||||
wxBrush m_greybrush;
|
||||
};
|
||||
|
||||
class pdcSetPenOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetPenOp(const wxPen& pen)
|
||||
{m_greypen=m_pen=pen;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (!grey) dc->SetPen(m_pen);
|
||||
else dc->SetPen(m_greypen);
|
||||
}
|
||||
virtual void CacheGrey() {m_greypen=GetGreyPen(m_pen);}
|
||||
protected:
|
||||
wxPen m_pen;
|
||||
wxPen m_greypen;
|
||||
};
|
||||
|
||||
class pdcSetTextBackgroundOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetTextBackgroundOp(const wxColour& colour)
|
||||
{m_colour=colour;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (!grey) dc->SetTextBackground(m_colour);
|
||||
else dc->SetTextBackground(MakeColourGrey(m_colour));
|
||||
}
|
||||
protected:
|
||||
wxColour m_colour;
|
||||
};
|
||||
|
||||
class pdcSetTextForegroundOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetTextForegroundOp(const wxColour& colour)
|
||||
{m_colour=colour;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (!grey) dc->SetTextForeground(m_colour);
|
||||
else dc->SetTextForeground(MakeColourGrey(m_colour));
|
||||
}
|
||||
protected:
|
||||
wxColour m_colour;
|
||||
};
|
||||
|
||||
class pdcDrawRectangleOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawRectangleOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
|
||||
{m_x=x; m_y=y; m_w=w; m_h=h;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawRectangle(m_x,m_y,m_w,m_h);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx;m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y,m_w,m_h;
|
||||
};
|
||||
|
||||
class pdcDrawLineOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawLineOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
||||
{m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawLine(m_x1,m_y1,m_x2,m_y2);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x1+=dx; m_y1+=dy; m_x2+=dx; m_y2+=dy;}
|
||||
protected:
|
||||
wxCoord m_x1,m_y1,m_x2,m_y2;
|
||||
};
|
||||
|
||||
class pdcSetBackgroundModeOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetBackgroundModeOp(int mode) {m_mode=mode;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetBackgroundMode(m_mode);}
|
||||
protected:
|
||||
int m_mode;
|
||||
};
|
||||
|
||||
class pdcDrawTextOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawTextOp(const wxString& text, wxCoord x, wxCoord y)
|
||||
{m_text=text; m_x=x; m_y=y;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawText(m_text, m_x, m_y);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxString m_text;
|
||||
wxCoord m_x, m_y;
|
||||
};
|
||||
|
||||
class pdcClearOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcClearOp() {}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->Clear();}
|
||||
};
|
||||
|
||||
class pdcBeginDrawingOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcBeginDrawingOp() {}
|
||||
virtual void DrawToDC(wxDC *WXUNUSED(dc), bool WXUNUSED(grey)=false) {}
|
||||
};
|
||||
|
||||
class pdcEndDrawingOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcEndDrawingOp() {}
|
||||
virtual void DrawToDC(wxDC *WXUNUSED(dc), bool WXUNUSED(grey)=false) {}
|
||||
};
|
||||
|
||||
class pdcFloodFillOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcFloodFillOp(wxCoord x, wxCoord y, const wxColour& col,
|
||||
wxFloodFillStyle style) {m_x=x; m_y=y; m_col=col; m_style=style;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (!grey) dc->FloodFill(m_x,m_y,m_col,m_style);
|
||||
else dc->FloodFill(m_x,m_y,MakeColourGrey(m_col),m_style);
|
||||
}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y;
|
||||
wxColour m_col;
|
||||
wxFloodFillStyle m_style;
|
||||
};
|
||||
|
||||
class pdcCrossHairOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcCrossHairOp(wxCoord x, wxCoord y) {m_x=x; m_y=y;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->CrossHair(m_x,m_y);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y;
|
||||
};
|
||||
|
||||
class pdcDrawArcOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawArcOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
|
||||
wxCoord xc, wxCoord yc)
|
||||
{m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2; m_xc=xc; m_yc=yc;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawArc(m_x1,m_y1,m_x2,m_y2,m_xc,m_yc);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x1+=dx; m_x2+=dx; m_y1+=dy; m_y2+=dy;}
|
||||
protected:
|
||||
wxCoord m_x1,m_x2,m_xc;
|
||||
wxCoord m_y1,m_y2,m_yc;
|
||||
};
|
||||
|
||||
class pdcDrawCheckMarkOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawCheckMarkOp(wxCoord x, wxCoord y,
|
||||
wxCoord width, wxCoord height)
|
||||
{m_x=x; m_y=y; m_w=width; m_h=height;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawCheckMark(m_x,m_y,m_w,m_h);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y,m_w,m_h;
|
||||
};
|
||||
|
||||
class pdcDrawEllipticArcOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawEllipticArcOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
||||
double sa, double ea)
|
||||
{m_x=x; m_y=y; m_w=w; m_h=h; m_sa=sa; m_ea=ea;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawEllipticArc(m_x,m_y,m_w,m_h,m_sa,m_ea);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y,m_w,m_h;
|
||||
double m_sa,m_ea;
|
||||
};
|
||||
|
||||
class pdcDrawPointOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawPointOp(wxCoord x, wxCoord y)
|
||||
{m_x=x; m_y=y;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawPoint(m_x,m_y);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y;
|
||||
};
|
||||
|
||||
class pdcDrawRoundedRectangleOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawRoundedRectangleOp(wxCoord x, wxCoord y, wxCoord width,
|
||||
wxCoord height, double radius)
|
||||
{m_x=x; m_y=y; m_w=width; m_h=height; m_r=radius;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawRoundedRectangle(m_x,m_y,m_w,m_h,m_r);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y,m_w,m_h;
|
||||
double m_r;
|
||||
};
|
||||
|
||||
class pdcDrawEllipseOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawEllipseOp(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
||||
{m_x=x; m_y=y; m_w=width; m_h=height;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawEllipse(m_x,m_y,m_w,m_h);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxCoord m_x,m_y,m_w,m_h;
|
||||
};
|
||||
|
||||
class pdcDrawIconOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawIconOp(const wxIcon& icon, wxCoord x, wxCoord y)
|
||||
{m_icon=icon; m_x=x; m_y=y;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (grey) dc->DrawIcon(m_greyicon,m_x,m_y);
|
||||
else dc->DrawIcon(m_icon,m_x,m_y);
|
||||
}
|
||||
virtual void CacheGrey() {m_greyicon=GetGreyIcon(m_icon);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxIcon m_icon;
|
||||
wxIcon m_greyicon;
|
||||
wxCoord m_x,m_y;
|
||||
};
|
||||
|
||||
class pdcDrawLinesOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawLinesOp(int n, wxPoint points[],
|
||||
wxCoord xoffset = 0, wxCoord yoffset = 0);
|
||||
virtual ~pdcDrawLinesOp();
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawLines(m_n,m_points,m_xoffset,m_yoffset);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{
|
||||
for(int i=0; i<m_n; i++)
|
||||
{
|
||||
m_points[i].x+=dx;
|
||||
m_points[i].y+=dy;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
int m_n;
|
||||
wxPoint *m_points;
|
||||
wxCoord m_xoffset,m_yoffset;
|
||||
};
|
||||
|
||||
class pdcDrawPolygonOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawPolygonOp(int n, wxPoint points[],
|
||||
wxCoord xoffset = 0, wxCoord yoffset = 0,
|
||||
wxPolygonFillMode fillStyle = wxODDEVEN_RULE);
|
||||
virtual ~pdcDrawPolygonOp();
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawPolygon(m_n,m_points,m_xoffset,m_yoffset,m_fillStyle);}
|
||||
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{
|
||||
for(int i=0; i<m_n; i++)
|
||||
{
|
||||
m_points[i].x+=dx;
|
||||
m_points[i].y+=dy;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
int m_n;
|
||||
wxPoint *m_points;
|
||||
wxCoord m_xoffset,m_yoffset;
|
||||
wxPolygonFillMode m_fillStyle;
|
||||
};
|
||||
|
||||
class pdcDrawPolyPolygonOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
|
||||
wxCoord xoffset = 0, wxCoord yoffset = 0,
|
||||
wxPolygonFillMode fillStyle = wxODDEVEN_RULE);
|
||||
virtual ~pdcDrawPolyPolygonOp();
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawPolyPolygon(m_n,m_count,m_points,
|
||||
m_xoffset,m_yoffset,m_fillStyle);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{
|
||||
for(int i=0; i<m_totaln; i++)
|
||||
{
|
||||
m_points[i].x += dx;
|
||||
m_points[i].y += dy;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
int m_n;
|
||||
int m_totaln;
|
||||
int *m_count;
|
||||
wxPoint *m_points;
|
||||
wxCoord m_xoffset, m_yoffset;
|
||||
wxPolygonFillMode m_fillStyle;
|
||||
};
|
||||
|
||||
class pdcDrawRotatedTextOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawRotatedTextOp(const wxString& text, wxCoord x, wxCoord y, double angle)
|
||||
{m_text=text; m_x=x; m_y=y; m_angle=angle;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawRotatedText(m_text,m_x,m_y,m_angle);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxString m_text;
|
||||
wxCoord m_x,m_y;
|
||||
double m_angle;
|
||||
};
|
||||
|
||||
class pdcDrawBitmapOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawBitmapOp(const wxBitmap &bmp, wxCoord x, wxCoord y,
|
||||
bool useMask = false)
|
||||
{m_bmp=bmp; m_x=x; m_y=y; m_useMask=useMask;}
|
||||
virtual void DrawToDC(wxDC *dc, bool grey=false)
|
||||
{
|
||||
if (grey) dc->DrawBitmap(m_greybmp,m_x,m_y,m_useMask);
|
||||
else dc->DrawBitmap(m_bmp,m_x,m_y,m_useMask);
|
||||
}
|
||||
virtual void CacheGrey() {m_greybmp=GetGreyBitmap(m_bmp);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_x+=dx; m_y+=dy;}
|
||||
protected:
|
||||
wxBitmap m_bmp;
|
||||
wxBitmap m_greybmp;
|
||||
wxCoord m_x,m_y;
|
||||
bool m_useMask;
|
||||
};
|
||||
|
||||
class pdcDrawLabelOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawLabelOp(const wxString& text,
|
||||
const wxBitmap& image,
|
||||
const wxRect& rect,
|
||||
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
|
||||
int indexAccel = -1)
|
||||
{m_text=text; m_image=image; m_rect=rect;
|
||||
m_align=alignment; m_iAccel=indexAccel;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
|
||||
{dc->DrawLabel(m_text,m_image,m_rect,m_align,m_iAccel);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{m_rect.x+=dx; m_rect.y+=dy;}
|
||||
protected:
|
||||
wxString m_text;
|
||||
wxBitmap m_image;
|
||||
wxRect m_rect;
|
||||
int m_align;
|
||||
int m_iAccel;
|
||||
};
|
||||
|
||||
#if wxUSE_SPLINES
|
||||
class pdcDrawSplineOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcDrawSplineOp(int n, wxPoint points[]);
|
||||
virtual ~pdcDrawSplineOp();
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawSpline(m_n,m_points);}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<m_n; i++)
|
||||
{
|
||||
m_points[i].x += dx;
|
||||
m_points[i].y += dy;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
wxPoint *m_points;
|
||||
int m_n;
|
||||
};
|
||||
#endif // wxUSE_SPLINES
|
||||
|
||||
#if wxUSE_PALETTE
|
||||
class pdcSetPaletteOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetPaletteOp(const wxPalette& palette) {m_palette=palette;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetPalette(m_palette);}
|
||||
protected:
|
||||
wxPalette m_palette;
|
||||
};
|
||||
#endif // wxUSE_PALETTE
|
||||
|
||||
class pdcSetLogicalFunctionOp : public pdcOp
|
||||
{
|
||||
public:
|
||||
pdcSetLogicalFunctionOp(wxRasterOperationMode function) {m_function=function;}
|
||||
virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetLogicalFunction(m_function);}
|
||||
protected:
|
||||
wxRasterOperationMode m_function;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pdcObject type to contain list of operations for each real (Python) object
|
||||
//----------------------------------------------------------------------------
|
||||
class pdcObject
|
||||
{
|
||||
public:
|
||||
pdcObject(int id)
|
||||
{m_id=id; m_bounded=false; m_oplist.DeleteContents(true);
|
||||
m_greyedout=false;}
|
||||
|
||||
virtual ~pdcObject() {m_oplist.Clear();}
|
||||
|
||||
// Protected Member Access
|
||||
void SetId(int id) {m_id=id;}
|
||||
int GetId() {return m_id;}
|
||||
void SetBounds(wxRect& rect) {m_bounds=rect; m_bounded=true;}
|
||||
wxRect GetBounds() {return m_bounds;}
|
||||
void SetBounded(bool bounded) {m_bounded=bounded;}
|
||||
bool IsBounded() {return m_bounded;}
|
||||
void SetGreyedOut(bool greyout=true);
|
||||
bool GetGreyedOut() {return m_greyedout;}
|
||||
|
||||
// Op List Management Methods
|
||||
void Clear() {m_oplist.Clear();}
|
||||
void AddOp(pdcOp *op)
|
||||
{
|
||||
m_oplist.Append(op);
|
||||
if (m_greyedout) op->CacheGrey();
|
||||
}
|
||||
int GetLen() {return m_oplist.GetCount();}
|
||||
virtual void Translate(wxCoord dx, wxCoord dy);
|
||||
|
||||
// Drawing Method
|
||||
virtual void DrawToDC(wxDC *dc);
|
||||
protected:
|
||||
int m_id; // id of object (associates this pdcObject
|
||||
// with a Python object with same id)
|
||||
wxRect m_bounds; // bounding rect of this object
|
||||
bool m_bounded; // true if bounds is valid, false by default
|
||||
pdcOpList m_oplist; // list of operations for this object
|
||||
bool m_greyedout; // if true then draw this object in greys only
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Declare a wxList to hold all the objects. List order reflects drawing
|
||||
// order (Z order) and is the same order as objects are added to the list
|
||||
//----------------------------------------------------------------------------
|
||||
class pdcObjectList;
|
||||
WX_DECLARE_LIST(pdcObject, pdcObjectList);
|
||||
|
||||
//Declare a hashmap that maps from ids to nodes in the object list.
|
||||
WX_DECLARE_HASH_MAP(
|
||||
int,
|
||||
pdcObject *,
|
||||
wxIntegerHash,
|
||||
wxIntegerEqual,
|
||||
pdcObjectHash
|
||||
);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxPseudoDC class
|
||||
// ----------------------------------------------------------------------------
|
||||
// This is the actual PseudoDC class
|
||||
// This class stores a list of recorded dc operations in m_list
|
||||
// and plays them back to a real dc using DrawToDC or DrawToDCClipped.
|
||||
// Drawing methods are mirrored from wxDC but add nodes to m_list
|
||||
// instead of doing any real drawing.
|
||||
// ----------------------------------------------------------------------------
|
||||
class wxPseudoDC : public wxObject
|
||||
{
|
||||
public:
|
||||
wxPseudoDC()
|
||||
{m_currId=-1; m_lastObject=NULL; m_objectlist.DeleteContents(true);m_objectIndex.clear();}
|
||||
~wxPseudoDC();
|
||||
// ------------------------------------------------------------------------
|
||||
// List managment methods
|
||||
//
|
||||
void RemoveAll();
|
||||
int GetLen();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// methods for managing operations by ID
|
||||
//
|
||||
// Set the Id for all subsequent operations (until SetId is called again)
|
||||
void SetId(int id) {m_currId = id;}
|
||||
// Remove all the operations associated with an id so it can be redrawn
|
||||
void ClearId(int id);
|
||||
// Remove the object node (and all operations) associated with an id
|
||||
void RemoveId(int id);
|
||||
// Set the bounding rect of a given object
|
||||
// This will create an object node if one doesn't exist
|
||||
void SetIdBounds(int id, wxRect& rect);
|
||||
void GetIdBounds(int id, wxRect& rect);
|
||||
// Translate all the operations for this id
|
||||
void TranslateId(int id, wxCoord dx, wxCoord dy);
|
||||
// Grey-out an object
|
||||
void SetIdGreyedOut(int id, bool greyout=true);
|
||||
bool GetIdGreyedOut(int id);
|
||||
// Find Objects at a point. Returns Python list of id's
|
||||
// sorted in reverse drawing order (result[0] is top object)
|
||||
// This version looks at drawn pixels
|
||||
PyObject *FindObjects(wxCoord x, wxCoord y,
|
||||
wxCoord radius=1, const wxColor& bg=*wxWHITE);
|
||||
// This version only looks at bounding boxes
|
||||
PyObject *FindObjectsByBBox(wxCoord x, wxCoord y);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Playback Methods
|
||||
//
|
||||
// draw to dc but skip objects known to be outside of rect
|
||||
// This is a coarse level of clipping to speed things up
|
||||
// when lots of objects are off screen and doesn't affect the dc level
|
||||
// clipping
|
||||
void DrawToDCClipped(wxDC *dc, const wxRect& rect);
|
||||
void DrawToDCClippedRgn(wxDC *dc, const wxRegion& region);
|
||||
// draw to dc with no clipping (well the dc will still clip)
|
||||
void DrawToDC(wxDC *dc);
|
||||
// draw a single object to the dc
|
||||
void DrawIdToDC(int id, wxDC *dc);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Hit Detection Methods
|
||||
//
|
||||
// returns list of object with a drawn pixel within radius pixels of (x,y)
|
||||
// the list is in reverse draw order so last drawn is first in list
|
||||
// PyObject *HitTest(wxCoord x, wxCoord y, double radius)
|
||||
// returns list of objects whose bounding boxes include (x,y)
|
||||
// PyObject *HitTestBB(wxCoord x, wxCoord y)
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Methods mirrored from wxDC
|
||||
//
|
||||
void FloodFill(wxCoord x, wxCoord y, const wxColour& col,
|
||||
wxFloodFillStyle style = wxFLOOD_SURFACE)
|
||||
{AddToList(new pdcFloodFillOp(x,y,col,style));}
|
||||
void FloodFill(const wxPoint& pt, const wxColour& col,
|
||||
wxFloodFillStyle style = wxFLOOD_SURFACE)
|
||||
{ FloodFill(pt.x, pt.y, col, style); }
|
||||
|
||||
void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
||||
{AddToList(new pdcDrawLineOp(x1, y1, x2, y2));}
|
||||
void DrawLine(const wxPoint& pt1, const wxPoint& pt2)
|
||||
{ DrawLine(pt1.x, pt1.y, pt2.x, pt2.y); }
|
||||
|
||||
void CrossHair(wxCoord x, wxCoord y)
|
||||
{AddToList(new pdcCrossHairOp(x,y));}
|
||||
void CrossHair(const wxPoint& pt)
|
||||
{ CrossHair(pt.x, pt.y); }
|
||||
|
||||
void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
|
||||
wxCoord xc, wxCoord yc)
|
||||
{AddToList(new pdcDrawArcOp(x1,y1,x2,y2,xc,yc));}
|
||||
void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre)
|
||||
{ DrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); }
|
||||
|
||||
void DrawCheckMark(wxCoord x, wxCoord y,
|
||||
wxCoord width, wxCoord height)
|
||||
{AddToList(new pdcDrawCheckMarkOp(x,y,width,height));}
|
||||
void DrawCheckMark(const wxRect& rect)
|
||||
{ DrawCheckMark(rect.x, rect.y, rect.width, rect.height); }
|
||||
|
||||
void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
||||
double sa, double ea)
|
||||
{AddToList(new pdcDrawEllipticArcOp(x,y,w,h,sa,ea));}
|
||||
void DrawEllipticArc(const wxPoint& pt, const wxSize& sz,
|
||||
double sa, double ea)
|
||||
{ DrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); }
|
||||
|
||||
void DrawPoint(wxCoord x, wxCoord y)
|
||||
{AddToList(new pdcDrawPointOp(x,y));}
|
||||
void DrawPoint(const wxPoint& pt)
|
||||
{ DrawPoint(pt.x, pt.y); }
|
||||
|
||||
void DrawPolygon(int n, wxPoint points[],
|
||||
wxCoord xoffset = 0, wxCoord yoffset = 0,
|
||||
wxPolygonFillMode fillStyle = wxODDEVEN_RULE)
|
||||
{AddToList(new pdcDrawPolygonOp(n,points,xoffset,yoffset,fillStyle));}
|
||||
|
||||
void DrawPolyPolygon(int n, int count[], wxPoint points[],
|
||||
wxCoord xoffset = 0, wxCoord yoffset = 0,
|
||||
wxPolygonFillMode fillStyle = wxODDEVEN_RULE)
|
||||
{AddToList(new pdcDrawPolyPolygonOp(n,count,points,xoffset,yoffset,fillStyle));}
|
||||
|
||||
void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
||||
{AddToList(new pdcDrawRectangleOp(x, y, width, height));}
|
||||
void DrawRectangle(const wxPoint& pt, const wxSize& sz)
|
||||
{ DrawRectangle(pt.x, pt.y, sz.x, sz.y); }
|
||||
void DrawRectangle(const wxRect& rect)
|
||||
{ DrawRectangle(rect.x, rect.y, rect.width, rect.height); }
|
||||
|
||||
void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height,
|
||||
double radius)
|
||||
{AddToList(new pdcDrawRoundedRectangleOp(x,y,width,height,radius));}
|
||||
void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz,
|
||||
double radius)
|
||||
{ DrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); }
|
||||
void DrawRoundedRectangle(const wxRect& r, double radius)
|
||||
{ DrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); }
|
||||
|
||||
void DrawCircle(wxCoord x, wxCoord y, wxCoord radius)
|
||||
{ DrawEllipse(x - radius, y - radius, 2*radius, 2*radius); }
|
||||
void DrawCircle(const wxPoint& pt, wxCoord radius)
|
||||
{ DrawCircle(pt.x, pt.y, radius); }
|
||||
|
||||
void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
||||
{AddToList(new pdcDrawEllipseOp(x,y,width,height));}
|
||||
void DrawEllipse(const wxPoint& pt, const wxSize& sz)
|
||||
{ DrawEllipse(pt.x, pt.y, sz.x, sz.y); }
|
||||
void DrawEllipse(const wxRect& rect)
|
||||
{ DrawEllipse(rect.x, rect.y, rect.width, rect.height); }
|
||||
|
||||
void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
|
||||
{AddToList(new pdcDrawIconOp(icon,x,y));}
|
||||
void DrawIcon(const wxIcon& icon, const wxPoint& pt)
|
||||
{ DrawIcon(icon, pt.x, pt.y); }
|
||||
|
||||
void DrawLines(int n, wxPoint points[],
|
||||
wxCoord xoffset = 0, wxCoord yoffset = 0)
|
||||
{AddToList(new pdcDrawLinesOp(n,points,xoffset,yoffset));}
|
||||
|
||||
void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
|
||||
bool useMask = false)
|
||||
{AddToList(new pdcDrawBitmapOp(bmp,x,y,useMask));}
|
||||
void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt,
|
||||
bool useMask = false)
|
||||
{ DrawBitmap(bmp, pt.x, pt.y, useMask); }
|
||||
|
||||
void DrawText(const wxString& text, wxCoord x, wxCoord y)
|
||||
{AddToList(new pdcDrawTextOp(text, x, y));}
|
||||
void DrawText(const wxString& text, const wxPoint& pt)
|
||||
{ DrawText(text, pt.x, pt.y); }
|
||||
|
||||
void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
|
||||
{AddToList(new pdcDrawRotatedTextOp(text,x,y,angle));}
|
||||
void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle)
|
||||
{ DrawRotatedText(text, pt.x, pt.y, angle); }
|
||||
|
||||
// this version puts both optional bitmap and the text into the given
|
||||
// rectangle and aligns is as specified by alignment parameter; it also
|
||||
// will emphasize the character with the given index if it is != -1
|
||||
void DrawLabel(const wxString& text,
|
||||
const wxBitmap& image,
|
||||
const wxRect& rect,
|
||||
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
|
||||
int indexAccel = -1)
|
||||
{AddToList(new pdcDrawLabelOp(text,image,rect,alignment,indexAccel));}
|
||||
|
||||
void DrawLabel(const wxString& text, const wxRect& rect,
|
||||
int alignment = wxALIGN_LEFT | wxALIGN_TOP,
|
||||
int indexAccel = -1)
|
||||
{ DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); }
|
||||
|
||||
/*?????? I don't think that the source dc would stick around
|
||||
void Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
|
||||
wxDC *source, wxCoord xsrc, wxCoord ysrc,
|
||||
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
|
||||
{AddToList(new pdcBlitOp(xdest,ydest,width,height,source,xsrc,
|
||||
ysrc,rop,useMask,xsrcMask,ysrcMask));}
|
||||
void Blit(const wxPoint& destPt, const wxSize& sz,
|
||||
wxDC *source, const wxPoint& srcPt,
|
||||
int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition)
|
||||
{
|
||||
Blit(destPt.x, destPt.y, sz.x, sz.y, source, srcPt.x, srcPt.y,
|
||||
rop, useMask, srcPtMask.x, srcPtMask.y);
|
||||
}
|
||||
??????*/
|
||||
|
||||
#if wxUSE_SPLINES
|
||||
void DrawSpline(int n, wxPoint points[])
|
||||
{AddToList(new pdcDrawSplineOp(n,points));}
|
||||
#endif // wxUSE_SPLINES
|
||||
|
||||
#if wxUSE_PALETTE
|
||||
void SetPalette(const wxPalette& palette)
|
||||
{AddToList(new pdcSetPaletteOp(palette));}
|
||||
#endif // wxUSE_PALETTE
|
||||
|
||||
void SetLogicalFunction(wxRasterOperationMode function)
|
||||
{AddToList(new pdcSetLogicalFunctionOp(function));}
|
||||
void SetFont(const wxFont& font)
|
||||
{AddToList(new pdcSetFontOp(font));}
|
||||
void SetPen(const wxPen& pen)
|
||||
{AddToList(new pdcSetPenOp(pen));}
|
||||
void SetBrush(const wxBrush& brush)
|
||||
{AddToList(new pdcSetBrushOp(brush));}
|
||||
void SetBackground(const wxBrush& brush)
|
||||
{AddToList(new pdcSetBackgroundOp(brush));}
|
||||
void SetBackgroundMode(int mode)
|
||||
{AddToList(new pdcSetBackgroundModeOp(mode));}
|
||||
void SetTextBackground(const wxColour& colour)
|
||||
{AddToList(new pdcSetTextBackgroundOp(colour));}
|
||||
void SetTextForeground(const wxColour& colour)
|
||||
{AddToList(new pdcSetTextForegroundOp(colour));}
|
||||
|
||||
void Clear()
|
||||
{AddToList(new pdcClearOp());}
|
||||
void BeginDrawing()
|
||||
{AddToList(new pdcBeginDrawingOp());}
|
||||
void EndDrawing()
|
||||
{AddToList(new pdcEndDrawingOp());}
|
||||
|
||||
protected:
|
||||
// ------------------------------------------------------------------------
|
||||
// protected helper methods
|
||||
void AddToList(pdcOp *newOp);
|
||||
pdcObject *FindObject(int id, bool create=false);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Data members
|
||||
//
|
||||
int m_currId; // id to use for operations done on the PseudoDC
|
||||
pdcObject *m_lastObject; // used to find last used object quickly
|
||||
pdcObjectList m_objectlist; // list of objects
|
||||
pdcObjectHash m_objectIndex; //id->object lookup index
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
16
unittests/test_pseudodc.py
Normal file
16
unittests/test_pseudodc.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import unittest
|
||||
import wtc
|
||||
import wx
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class pseudodc_Tests(wtc.WidgetTestCase):
|
||||
|
||||
# TODO: Remove this test and add real ones.
|
||||
def test_pseudodc1(self):
|
||||
self.fail("Unit tests for pseudodc not implemented yet.")
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user