00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015 #undef DEBUG
00016 #include <Python.h>
00017 #include "wx/wxPython/wxPython.h"
00018 #include "wx/wxPython/pseudodc.h"
00019
00020
00021 #include <wx/listimpl.cpp>
00022 WX_DEFINE_LIST(pdcOpList);
00023 WX_DEFINE_LIST(pdcObjectList);
00024
00025
00026
00027
00028 wxColour &MakeColourGrey(const wxColour &c)
00029 {
00030 static wxColour rval;
00031 rval.Set(byte((230-c.Red())*0.7+c.Red()),
00032 byte((230-c.Green())*0.7+c.Green()),
00033 byte((230-c.Blue())*0.7+c.Blue()));
00034 return rval;
00035 }
00036 wxBrush &GetGreyBrush(wxBrush &brush)
00037 {
00038 static wxBrush b;
00039 wxColour c;
00040 b = brush;
00041 c = MakeColourGrey(brush.GetColour());
00042 b.SetColour(c);
00043 return b;
00044 }
00045
00046 wxPen &GetGreyPen(wxPen &pen)
00047 {
00048 static wxPen p;
00049 wxColour c;
00050 p = pen;
00051 c = MakeColourGrey(pen.GetColour());
00052 p.SetColour(c);
00053 return p;
00054 }
00055
00056 void GreyOutImage(wxImage &img)
00057 {
00058 unsigned char *data = img.GetData();
00059 unsigned char r,g,b;
00060 unsigned char mr,mg,mb;
00061 int i, tst;
00062 int len = img.GetHeight()*img.GetWidth()*3;
00063 if (img.HasMask())
00064 {
00065 mr = img.GetMaskRed();
00066 mg = img.GetMaskGreen();
00067 mb = img.GetMaskBlue();
00068 }
00069 tst=0;
00070 for (i=0;i<len;i+=3)
00071 {
00072 r=data[i]; g=data[i+1]; b=data[i+2];
00073 if (!img.HasMask() ||
00074 r!=mr || g!=mg || b!=mb)
00075 {
00076 if (!tst)
00077 {
00078 tst=1;
00079 }
00080 r = (unsigned char)((230.0-r)*0.7+r);
00081 g = (unsigned char)((230.0-g)*0.7+g);
00082 b = (unsigned char)((230.0-b)*0.7+b);
00083 data[i]=r; data[i+1]=g; data[i+2]=b;
00084 }
00085 }
00086 }
00087
00088 wxIcon &GetGreyIcon(wxIcon &icon)
00089 {
00090 wxBitmap bmp;
00091 bmp.CopyFromIcon(icon);
00092 wxImage img = bmp.ConvertToImage();
00093 GreyOutImage(img);
00094 wxBitmap bmp2(img,32);
00095 static wxIcon rval;
00096 rval.CopyFromBitmap(bmp2);
00097 return rval;
00098 }
00099
00100 wxBitmap &GetGreyBitmap(wxBitmap &bmp)
00101 {
00102 wxImage img = bmp.ConvertToImage();
00103 GreyOutImage(img);
00104 static wxBitmap rval(img,32);
00105 return rval;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115 pdcDrawPolyPolygonOp::pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
00116 wxCoord xoffset, wxCoord yoffset, int fillStyle)
00117 {
00118 m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
00119 int total_n=0;
00120 if (n)
00121 {
00122 m_count = new int[n];
00123 for(int i=0; i<n; i++)
00124 {
00125 total_n+=count[i];
00126 m_count[i]=count[i];
00127 }
00128 if (total_n)
00129 {
00130 m_points = new wxPoint[total_n];
00131 for(int j=0; j<total_n; j++)
00132 m_points[j] = points[j];
00133 }
00134 else m_points=NULL;
00135 }
00136 else
00137 {
00138 m_points=NULL;
00139 m_count=NULL;
00140 }
00141 m_totaln = total_n;
00142 }
00143
00144
00145
00146
00147 pdcDrawPolyPolygonOp::~pdcDrawPolyPolygonOp()
00148 {
00149 if (m_points) delete m_points;
00150 if (m_count) delete m_count;
00151 m_points=NULL;
00152 m_count=NULL;
00153 }
00154
00155
00156
00157
00158 pdcDrawLinesOp::pdcDrawLinesOp(int n, wxPoint points[],
00159 wxCoord xoffset, wxCoord yoffset)
00160 {
00161 m_n=n; m_xoffset=xoffset; m_yoffset=yoffset;
00162 if (n)
00163 {
00164 m_points = new wxPoint[n];
00165 for (int i=0; i<n; i++)
00166 m_points[i] = points[i];
00167 }
00168 else m_points=NULL;
00169 }
00170
00171
00172
00173
00174 pdcDrawLinesOp::~pdcDrawLinesOp()
00175 {
00176 if (m_points) delete m_points;
00177 m_points=NULL;
00178 }
00179
00180
00181
00182
00183 pdcDrawPolygonOp::pdcDrawPolygonOp(int n, wxPoint points[],
00184 wxCoord xoffset, wxCoord yoffset, int fillStyle)
00185 {
00186 m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
00187 if (n)
00188 {
00189 m_points = new wxPoint[n];
00190 for (int i=0; i<n; i++)
00191 m_points[i] = points[i];
00192 }
00193 else m_points=NULL;
00194 }
00195
00196
00197
00198
00199 pdcDrawPolygonOp::~pdcDrawPolygonOp()
00200 {
00201 if (m_points) delete m_points;
00202 m_points=NULL;
00203 }
00204
00205 #if wxUSE_SPLINES
00206
00207
00208
00209 pdcDrawSplineOp::pdcDrawSplineOp(int n, wxPoint points[])
00210 {
00211 m_n=n;
00212 if (n)
00213 {
00214 m_points = new wxPoint[n];
00215 for(int i=0; i<n; i++)
00216 m_points[i] = points[i];
00217 }
00218 else m_points=NULL;
00219 }
00220
00221
00222
00223
00224 pdcDrawSplineOp::~pdcDrawSplineOp()
00225 {
00226 if (m_points) delete m_points;
00227 m_points=NULL;
00228 }
00229 #endif // wxUSE_SPLINES
00230
00231
00232
00233
00234
00235
00236
00237 void pdcObject::DrawToDC(wxDC *dc)
00238 {
00239 pdcOpList::Node *node = m_oplist.GetFirst();
00240 while(node)
00241 {
00242 node->GetData()->DrawToDC(dc, m_greyedout);
00243 node = node->GetNext();
00244 }
00245 }
00246
00247
00248
00249
00250 void pdcObject::Translate(wxCoord dx, wxCoord dy)
00251 {
00252 pdcOpList::Node *node = m_oplist.GetFirst();
00253 while(node)
00254 {
00255 node->GetData()->Translate(dx,dy);
00256 node = node->GetNext();
00257 }
00258 if (m_bounded)
00259 {
00260 m_bounds.x += dx;
00261 m_bounds.y += dy;
00262 }
00263 }
00264
00265
00266
00267
00268
00269 void pdcObject::SetGreyedOut(bool greyout)
00270 {
00271 m_greyedout=greyout;
00272 if (greyout)
00273 {
00274 pdcOpList::Node *node = m_oplist.GetFirst();
00275 pdcOp *obj;
00276 while(node)
00277 {
00278
00279 obj = node->GetData();
00280 obj->CacheGrey();
00281 node = node->GetNext();
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293 wxPseudoDC::~wxPseudoDC()
00294 {
00295
00296 RemoveAll();
00297
00298 }
00299
00300
00301
00302
00303 void wxPseudoDC::RemoveAll(void)
00304 {
00305 m_objectlist.Clear();
00306 m_currId = -1;
00307 m_lastObjNode = NULL;
00308 }
00309
00310
00311
00312
00313 int wxPseudoDC::GetLen(void)
00314 {
00315 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00316 int len=0;
00317 while (pt)
00318 {
00319 len += pt->GetData()->GetLen();
00320 pt = pt->GetNext();
00321 }
00322 return len;
00323 }
00324
00325
00326
00327
00328
00329
00330 pdcObjectList::Node *wxPseudoDC::FindObjNode(int id, bool create)
00331 {
00332
00333 if (m_lastObjNode && m_lastObjNode->GetData()->GetId() == id)
00334 return m_lastObjNode;
00335
00336 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00337 while (pt)
00338 {
00339 if (pt->GetData()->GetId() == id)
00340 {
00341
00342
00343 m_lastObjNode = pt;
00344 return pt;
00345 }
00346 pt = pt->GetNext();
00347 }
00348
00349 if (create)
00350 {
00351
00352 m_lastObjNode = m_objectlist.Append(new pdcObject(id));
00353 return m_lastObjNode;
00354 }
00355
00356 return NULL;
00357 }
00358
00359
00360
00361
00362 void wxPseudoDC::AddToList(pdcOp *newOp)
00363 {
00364 pdcObjectList::Node *pt = FindObjNode(m_currId, true);
00365 pt->GetData()->AddOp(newOp);
00366 }
00367
00368
00369
00370
00371 void wxPseudoDC::ClearId(int id)
00372 {
00373 pdcObjectList::Node *pt = FindObjNode(id);
00374 if (pt) pt->GetData()->Clear();
00375 }
00376
00377
00378
00379
00380 void wxPseudoDC::RemoveId(int id)
00381 {
00382 pdcObjectList::Node *pt = FindObjNode(id);
00383 if (pt)
00384 {
00385 if (m_lastObjNode == pt)
00386 m_lastObjNode = NULL;
00387 m_objectlist.DeleteNode(pt);
00388 }
00389 }
00390
00391
00392
00393
00394 void wxPseudoDC::SetIdBounds(int id, wxRect& rect)
00395 {
00396 pdcObjectList::Node *pt = FindObjNode(id, true);
00397 pt->GetData()->SetBounds(rect);
00398 }
00399
00400
00401
00402
00403 void wxPseudoDC::GetIdBounds(int id, wxRect& rect)
00404 {
00405 pdcObjectList::Node *pt = FindObjNode(id);
00406 if (pt && pt->GetData()->IsBounded())
00407 rect = pt->GetData()->GetBounds();
00408 else
00409 rect.x = rect.y = rect.width = rect.height = 0;
00410 }
00411
00412
00413
00414
00415 void wxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy)
00416 {
00417 pdcObjectList::Node *pt = FindObjNode(id);
00418 if (pt) pt->GetData()->Translate(dx,dy);
00419 }
00420
00421
00422
00423
00424 void wxPseudoDC::DrawIdToDC(int id, wxDC *dc)
00425 {
00426 pdcObjectList::Node *pt = FindObjNode(id);
00427 if (pt) pt->GetData()->DrawToDC(dc);
00428 }
00429
00430
00431
00432
00433 void wxPseudoDC::SetIdGreyedOut(int id, bool greyout)
00434 {
00435 pdcObjectList::Node *pt = FindObjNode(id);
00436 if (pt) pt->GetData()->SetGreyedOut(greyout);
00437 }
00438
00439
00440
00441
00442 bool wxPseudoDC::GetIdGreyedOut(int id)
00443 {
00444 pdcObjectList::Node *pt = FindObjNode(id);
00445 if (pt) return pt->GetData()->GetGreyedOut();
00446 else return false;
00447 }
00448
00449
00450
00451
00452
00453 PyObject *wxPseudoDC::FindObjectsByBBox(wxCoord x, wxCoord y)
00454 {
00455
00456 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00457 pdcObject *obj;
00458 PyObject* pyList = NULL;
00459 pyList = PyList_New(0);
00460 wxRect r;
00461 while (pt)
00462 {
00463 obj = pt->GetData();
00464 r = obj->GetBounds();
00465 if (obj->IsBounded() && r.Contains(x,y))
00466 {
00467 PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
00468 PyList_Insert(pyList, 0, pyObj);
00469 Py_DECREF(pyObj);
00470 }
00471 pt = pt->GetNext();
00472 }
00473
00474 return pyList;
00475 }
00476
00477
00478
00479
00480 PyObject *wxPseudoDC::FindObjects(wxCoord x, wxCoord y,
00481 wxCoord radius, const wxColor& bg)
00482 {
00483
00484 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00485 pdcObject *obj;
00486 PyObject* pyList = NULL;
00487 pyList = PyList_New(0);
00488 wxBrush bgbrush(bg);
00489 wxPen bgpen(bg);
00490
00491 if (radius == 0)
00492 {
00493 wxBitmap bmp(4,4,24);
00494 wxMemoryDC memdc;
00495 wxColor pix;
00496 wxRect viewrect(x-2,y-2,4,4);
00497
00498 memdc.SelectObject(bmp);
00499 memdc.SetBackground(bgbrush);
00500 memdc.Clear();
00501 memdc.SetDeviceOrigin(2-x,2-y);
00502 while (pt)
00503 {
00504 obj = pt->GetData();
00505 if (obj->IsBounded() && obj->GetBounds().Contains(x,y))
00506 {
00507
00508 memdc.SetBrush(bgbrush);
00509 memdc.SetPen(bgpen);
00510 memdc.DrawRectangle(viewrect);
00511
00512 obj->DrawToDC(&memdc);
00513 memdc.GetPixel(x,y,&pix);
00514
00515 if (pix != bg)
00516 {
00517 PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
00518 PyList_Insert(pyList, 0, pyObj);
00519 Py_DECREF(pyObj);
00520 }
00521 }
00522 pt = pt->GetNext();
00523 }
00524 memdc.SelectObject(wxNullBitmap);
00525 }
00526 else
00527 {
00528 wxRect viewrect(x-radius,y-radius,2*radius,2*radius);
00529 wxBitmap maskbmp(2*radius,2*radius,24);
00530 wxMemoryDC maskdc;
00531
00532 maskdc.SelectObject(maskbmp);
00533 maskdc.SetBackground(*wxBLACK_BRUSH);
00534 maskdc.Clear();
00535 maskdc.SetBrush(*wxWHITE_BRUSH);
00536 maskdc.SetPen(*wxWHITE_PEN);
00537 maskdc.DrawCircle(radius,radius,radius);
00538
00539 wxBitmap bmp(2*radius,2*radius,24);
00540 wxMemoryDC memdc;
00541 memdc.SelectObject(bmp);
00542
00543 memdc.SetDeviceOrigin(radius-x,radius-y);
00544
00545 wxRegion rgn2;
00546 while (pt)
00547 {
00548 obj = pt->GetData();
00549 if (obj->IsBounded() && viewrect.Intersects(obj->GetBounds()))
00550 {
00551
00552
00553 memdc.SetBrush(bgbrush);
00554 memdc.SetPen(bgpen);
00555 memdc.DrawRectangle(viewrect);
00556
00557 obj->DrawToDC(&memdc);
00558
00559 memdc.SetLogicalFunction(wxXOR);
00560 memdc.SetBrush(bgbrush);
00561 memdc.SetPen(bgpen);
00562 memdc.DrawRectangle(viewrect);
00563 memdc.SetLogicalFunction(wxCOPY);
00564 #ifdef __WXMAC__
00565
00566
00567 memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxCOPY);
00568 #else
00569
00570 memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxAND);
00571 #endif
00572
00573 memdc.SelectObject(wxNullBitmap);
00574 rgn2.Clear();
00575 rgn2.Union(bmp, *wxBLACK);
00576
00577 memdc.SelectObject(bmp);
00578 if (!rgn2.IsEmpty())
00579 {
00580 PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
00581 PyList_Insert(pyList, 0, pyObj);
00582 Py_DECREF(pyObj);
00583 }
00584 }
00585 pt = pt->GetNext();
00586 }
00587 maskdc.SelectObject(wxNullBitmap);
00588 memdc.SelectObject(wxNullBitmap);
00589 }
00590
00591 return pyList;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 void wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect)
00601 {
00602 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00603 pdcObject *obj;
00604 while (pt)
00605 {
00606 obj = pt->GetData();
00607 if (!obj->IsBounded() || rect.Intersects(obj->GetBounds()))
00608 obj->DrawToDC(dc);
00609 pt = pt->GetNext();
00610 }
00611 }
00612 void wxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region)
00613 {
00614 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00615 pdcObject *obj;
00616 while (pt)
00617 {
00618 obj = pt->GetData();
00619 if (!obj->IsBounded() ||
00620 (region.Contains(obj->GetBounds()) != wxOutRegion))
00621 obj->DrawToDC(dc);
00622 pt = pt->GetNext();
00623 }
00624 }
00625
00626
00627
00628
00629 void wxPseudoDC::DrawToDC(wxDC *dc)
00630 {
00631 pdcObjectList::Node *pt = m_objectlist.GetFirst();
00632 while (pt)
00633 {
00634 pt->GetData()->DrawToDC(dc);
00635 pt = pt->GetNext();
00636 }
00637 }
00638