00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #pragma warning(disable:4786)
00012
00013 #include "a2dprec.h"
00014
00015 #ifdef __BORLANDC__
00016 #pragma hdrstop
00017 #endif
00018
00019 #ifndef WX_PRECOMP
00020 #include "wx/wx.h"
00021 #endif
00022
00023 #include <wx/wfstream.h>
00024 #include <math.h>
00025
00026 #if wxART2D_USE_CANEXTOBJ
00027 #include "wx/canextobj/eval.h"
00028 #endif //wxART2D_USE_CANEXTOBJ
00029
00030 #include "wx/curves/meta.h"
00031
00032 #include "wx/canvas/canglob.h"
00033 #include "wx/canvas/canobj.h"
00034 #include "wx/canvas/candoc.h"
00035 #include "wx/canvas/drawer.h"
00036 #include "wx/canvas/canvas.h"
00037 #include "wx/canvas/cancom.h"
00038
00039 #if wxART2D_USE_EDITOR
00040 #include "wx/editor/edit.h"
00041 #endif //wxART2D_USE_EDITOR
00042
00043
00044
00045
00046
00047 IMPLEMENT_DYNAMIC_CLASS(a2dCurvesArea, a2dPolygonLClipper)
00048 IMPLEMENT_DYNAMIC_CLASS(a2dCurvesAreaList, a2dObject)
00049 IMPLEMENT_DYNAMIC_CLASS(a2dCanvasXYDisplayGroupAreas, a2dCanvasObject)
00050 IMPLEMENT_DYNAMIC_CLASS(a2dCanvasXYDisplayGroup, a2dCanvasXYDisplayGroupAreas)
00051
00052
00053 #ifdef wxUSE_INTPOINT
00054 #define wxMAX_COORDINATE INT_MAX
00055 #define wxMIN_COORDINATE INT_MIN
00056 #else
00057 #define wxMAX_COORDINATE 100e99
00058 #define wxMIN_COORDINATE 100e-99
00059 #endif
00060
00061 a2dBboxHash::a2dBboxHash(void)
00062 : a2dObject()
00063 {
00064 }
00065 a2dBboxHash::a2dBboxHash(const a2dBboxHash& other, CloneOptions options)
00066 : a2dObject(other)
00067 {
00068 }
00069
00070 a2dObject* a2dBboxHash::Clone(CloneOptions options) const
00071 {
00072 return new a2dBboxHash(*this, options);
00073 }
00074
00075 a2dPropertyIdCanvasObject* a2dCurvesArea::PROPID_curvesarea = NULL;
00076 a2dPropertyIdString* a2dCurvesArea::PROPID_text = NULL;
00077
00078
00079 INITIALIZE_PROPERTIES( a2dCurvesArea, a2dPolygonLClipper )
00080 {
00081 A2D_PROPID_D( a2dPropertyIdCanvasObject, curvesarea, 0 );
00082 A2D_PROPID_D( a2dPropertyIdString, text, wxT("") );
00083 return true;
00084 }
00085
00086 a2dCurvesArea::a2dCurvesArea(const wxString curveAreaName)
00087 : a2dPolygonLClipper(), m_group(NULL)
00088 {
00089 m_showyaxis = true;
00090 SetName(curveAreaName);
00091
00092 a2dBoundingBox extbox(0,0, 1,1);
00093 SetInternalBoundaries( extbox, 0, 0, 1, 1 );
00094
00095 m_axisY = new a2dCurveAxisLin( 0, true );
00096 m_axisY->SetCurvesArea(this);
00097 m_colour = wxNullColour;
00098
00099 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00100
00101 CurrentSmartPointerOwner = this;
00102 #endif
00103 }
00104
00105 a2dCurvesArea::a2dCurvesArea(const a2dCurvesArea& other, CloneOptions options)
00106 : a2dPolygonLClipper(other, options), m_group(NULL)
00107 {
00108 m_showyaxis = other.m_showyaxis;
00109
00110 if( options & clone_members )
00111 m_axisY = (a2dCurveAxis*) other.m_axisY->Clone( CloneOptions( options & ~ clone_seteditcopy ) );
00112 else
00113 m_axisY = other.m_axisY;
00114 m_axisY->SetCurvesArea(this);
00115
00116 m_intrect = other.m_intrect;
00117 m_colour = other.m_colour;
00118
00119 a2dCanvasObjectList::iterator iter = GetChildObjectList()->begin();
00120 while( iter != GetChildObjectList()->end() )
00121 {
00122 a2dCurveObject* item = wxDynamicCast( (*iter).Get(), a2dCurveObject );
00123 if ( item )
00124 item->SetCurvesArea( this );
00125 ++iter;
00126 }
00127
00128 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00129
00130 CurrentSmartPointerOwner = this;
00131 #endif
00132 }
00133
00134 a2dCurvesArea::~a2dCurvesArea()
00135 {
00136 if(m_markerShow2 != (a2dMarkerShow*)NULL)
00137 {
00138 m_markerShow2->SetRelease(true);
00139 }
00140 if(m_markerShow != (a2dMarkerShow*)NULL)
00141 {
00142 m_markerShow->SetRelease(true);
00143 }
00144 m_axisY->ReleaseChildObjects();
00145 }
00146
00147 a2dObject* a2dCurvesArea::Clone(CloneOptions options) const
00148 {
00149 return new a2dCurvesArea(*this, options);
00150 }
00151
00152 wxString a2dCurvesArea::GetAxisText() const
00153 {
00154
00155 const a2dNamedProperty *p = PROPID_text->GetPropertyListOnly( this );
00156 if (p)
00157 return p->StringValueRepresentation();
00158 return GetName();
00159 }
00160
00161 bool a2dCurvesArea::SetAxisText(const wxString& name)
00162 {
00163 PROPID_text->SetPropertyToObject( this, name );
00164 return true;
00165 }
00166
00167 void a2dCurvesArea::World2Curve( double xw, double yw, double& xcurve, double& ycurve )
00168 {
00169 a2dAffineMatrix mat = m_iworld;
00170 mat.Invert();
00171 mat.TransformPoint( xw, yw, xcurve, ycurve );
00172 }
00173
00174 void a2dCurvesArea::Curve2World( double xcurve, double ycurve, double& xw, double& yw )
00175 {
00176 m_iworld.TransformPoint( xcurve, ycurve, xw, yw );
00177 }
00178
00179 void a2dCurvesArea::SetBoundaries(const a2dBoundingBox& extbox)
00180 {
00181 a2dBoundingBox box( extbox.GetMinX() , extbox.GetMinY(), extbox.GetMaxX() , extbox.GetMaxY() );
00182 SetClippingFromBox( box );
00183 }
00184
00185 void a2dCurvesArea::UpdateInternalBoundaries(const a2dBoundingBox& extbox)
00186 {
00187 m_iworld.Identity();
00188 m_iworld.Translate(m_intrect.GetMinX() - extbox.GetMinX(), m_intrect.GetMinY() - extbox.GetMinY());
00189
00190 wxASSERT_MSG( extbox.GetWidth() != 0, wxT("pixel size can not be zero") );
00191 wxASSERT_MSG( extbox.GetHeight() != 0, wxT("pixel size can not be zero") );
00192
00193 m_iworld.Scale(m_intrect.GetWidth() / extbox.GetWidth(), m_intrect.GetHeight() / extbox.GetHeight(),
00194 m_intrect.GetMinX(), m_intrect.GetMinY());
00195
00196
00197 m_iworld.Invert();
00198 if(m_axisY)
00199 m_axisY->SetPending(true);
00200 SetPending(true);
00201 }
00202
00203 void a2dCurvesArea::AddCurve(a2dCurve* curve, const wxString curvename )
00204 {
00205 if ( !curvename.IsEmpty() )
00206 curve->SetName( curvename );
00207 Append( curve );
00208 curve->SetCurvesArea( this );
00209 }
00210
00211 void a2dCurvesArea::AddMarker(a2dMarker* marker )
00212 {
00213 Append( marker);
00214 marker->SetCurvesArea( this );
00215 }
00216
00217 void a2dCurvesArea::RemoveMarker(a2dMarker* marker )
00218 {
00219 ReleaseChild( marker );
00220 }
00221
00222 void a2dCurvesArea::InsertCurve( size_t before, a2dCurve* curve, const wxString curvename )
00223 {
00224 if ( !curvename.IsEmpty() )
00225 curve->SetName( curvename );
00226
00227 Insert( before, curve );
00228 }
00229
00230 a2dCurve* a2dCurvesArea::GetCurve( const wxString curvename )
00231 {
00232 forEachIn( a2dCanvasObjectList, GetChildObjectList() )
00233 {
00234 a2dCanvasObject *obj = *iter;
00235 if(obj->GetName() == curvename)
00236 return (a2dCurve*)obj;
00237 }
00238 return NULL;
00239 }
00240
00241 a2dBoundingBox a2dCurvesArea::GetCurvesBoundaries()
00242 {
00243 a2dBoundingBox curvebox;
00244
00245 forEachIn( a2dCanvasObjectList, GetChildObjectList() )
00246 {
00247 a2dCurve* curve = wxDynamicCast( (a2dCanvasObject*)*iter, a2dCurve );
00248 if ( curve )
00249 curvebox.Expand( curve->GetCurveBoundaries() );
00250 }
00251
00252 if ( !curvebox.GetValid() )
00253 {
00254
00255 curvebox.Expand(0,0);
00256 }
00257
00258 return curvebox;
00259 }
00260
00261 bool a2dCurvesArea::ProcessCanvasObjectEvent( a2dIterC& ic, a2dHitEvent& hitEvent )
00262 {
00263 a2dPolygonLClipper::ProcessCanvasObjectEvent( ic, hitEvent );
00264 m_axisY->ProcessCanvasObjectEvent( ic, hitEvent );
00265 return hitEvent.m_processed;
00266 }
00267
00268 void a2dCurvesArea::DoWalker( wxObject* parent, a2dWalkerIOHandler& handler )
00269 {
00270 handler.WalkTask( parent, this, a2dWalker_a2dDerivedCanvasObjectStart );
00271 a2dPolygonLClipper::DoWalker( parent, handler );
00272
00273 if (m_axisY)
00274 m_axisY->Walker( this, handler );
00275
00276 handler.WalkTask( parent, this, a2dWalker_a2dDerivedCanvasObjectEnd );
00277 }
00278
00279 a2dCanvasObject* a2dCurvesArea::IsHitCurvesWorld ( a2dIterC& ic, a2dHitEvent& hitEvent )
00280 {
00281 return ChildIsHitWorld( ic, hitEvent );
00282 }
00283
00284
00285 a2dBoundingBox& a2dCurvesArea::Expand(a2dBoundingBox& bbox)
00286 {
00287 bbox.Expand(m_axisY->GetBbox());
00288 return bbox;
00289 }
00290
00291 void a2dCurvesArea::DoAddPending( a2dIterC& ic )
00292 {
00293 a2dPolygonLClipper::DoAddPending( ic );
00294 m_axisY->AddPending( ic );
00295 }
00296
00297 void a2dCurvesArea::DependencyPending( a2dWalkerIOHandler* handler )
00298 {
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 m_axisY->DependencyPending( handler );
00320 if(m_axisY->GetPending() && !GetPending())
00321 SetPending(true);
00322 a2dPolygonLClipper::DependencyPending( handler );
00323 if(GetPending() && m_group && !m_group->GetPending())
00324 m_group->SetPending(true);
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 void a2dCurvesArea::DoUpdateViewDependentObjects( a2dIterC& ic )
00338 {
00339 a2dPolygonLClipper::DoUpdateViewDependentObjects( ic );
00340 m_axisY->UpdateViewDependentObjects( ic );
00341 }
00342
00343
00344 bool a2dCurvesArea::Update( UpdateMode mode )
00345 {
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 bool retCode = a2dPolygonLClipper::Update( mode );
00365 retCode = m_axisY->Update(mode) || retCode;
00366 return retCode;
00367 }
00368
00369
00370 bool a2dCurvesArea::DoUpdate( UpdateMode mode, const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox )
00371 {
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 bool retCode = false;
00392
00393
00394 m_flags.m_HasToolObjectsBelow = m_flags.m_HasToolObjectsBelow
00395 || m_axisY->GetHasToolObjectsBelow();
00396
00397 m_flags.m_HasSelectedObjectsBelow = m_flags.m_HasSelectedObjectsBelow
00398 || m_axisY->GetHasSelectedObjectsBelow();
00399 return retCode;
00400 }
00401
00402 void a2dCurvesArea::SetAxes(const a2dBoundingBox& extbox, double x, double y, double& zerox, double& zeroy, double& ixmin, double& ixmax)
00403 {
00404 GetCurveAreaTransform().TransformPoint(x, y, zerox, zeroy);
00405 ixmin = m_intrect.GetMinX();
00406 ixmax = m_intrect.GetMaxX();
00407
00408 if ( zerox < extbox.GetMinX())
00409 zerox = extbox.GetMinX();
00410 else if ( zerox > extbox.GetMaxX() )
00411 zerox = extbox.GetMaxX();
00412
00413 m_axisY->SetPosXY(zerox, extbox.GetMinY());
00414 m_axisY->SetLength( extbox.GetHeight() );
00415
00416 m_axisY->SetBoundaries( m_intrect.GetMinY(), m_intrect.GetMaxY() );
00417 m_axisY->Update(a2dCanvasObject::updatemask_normal);
00418 if(m_group && !m_group->GetPending())
00419 m_group->SetPending(true);
00420 }
00421
00422 bool a2dCurvesArea::IsCurvesHighlighted() const
00423 {
00424 const a2dCanvasObjectList* curvesList = GetCurves();
00425 const_forEachIn( a2dCanvasObjectList, curvesList )
00426 {
00427 a2dCurve* curve = wxDynamicCast( (a2dCanvasObject*)*iter, a2dCurve );
00428 if ( curve && curve->IsHighlighted())
00429 return true;
00430 }
00431 return false;
00432 }
00433
00434 void a2dCurvesArea::SetMarkerShow(a2dMarkerShow* showm)
00435 {
00436 m_markerShow = showm;
00437 }
00438
00439
00440 void a2dCurvesArea::SetMarkerShow2(a2dMarkerShow* showm)
00441 {
00442 m_markerShow2 = showm;
00443 }
00444
00445 a2dMarker* a2dCurvesArea::GetCursorMarker() const
00446 {
00447 const_forEachIn( a2dCanvasObjectList, GetChildObjectList() )
00448 {
00449 a2dMarker* marker = wxDynamicCast((a2dCanvasObject*)*iter, a2dMarker);
00450 if ( marker )
00451 return marker;
00452 }
00453 return NULL;
00454 }
00455
00456 void a2dCurvesArea::SetGroup(a2dCanvasXYDisplayGroupAreas* aGroup)
00457 {
00458 m_group = aGroup;
00459 if(m_group)
00460 {
00461 UpdateInternalBoundaries(m_group->GetPlotAreaRect());
00462 if(m_group->GetCanvasDocument())
00463 {
00464 SetCanvasDocument(m_group->GetCanvasDocument());
00465 if(m_axisY)
00466 m_axisY->SetCanvasDocument(m_group->GetCanvasDocument());
00467 }
00468 }
00469 }
00470
00471 void a2dCurvesArea::SetShowYaxis(bool showyaxis)
00472 {
00473 m_showyaxis = showyaxis;
00474 if(m_axisY) m_axisY->SetPending(true);
00475 SetPending(true);
00476
00477 }
00478
00479
00480 #if wxART2D_USE_CVGIO
00481 void a2dCurvesArea::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList* towrite )
00482 {
00483 a2dPolygonLClipper::DoSave( parent, out, xmlparts, towrite );
00484
00485 if ( xmlparts == a2dXmlSer_attrib )
00486 {
00487 out.WriteAttribute( wxT("showyaxis") , m_showyaxis );
00488 out.WriteNewLine();
00489
00490 out.WriteAttribute( wxT("ixmin") , m_intrect.GetMinX() );
00491 out.WriteAttribute( wxT("iymin") , m_intrect.GetMinY() );
00492 out.WriteAttribute( wxT("ixmax") , m_intrect.GetMaxX() );
00493 out.WriteAttribute( wxT("iymax") , m_intrect.GetMaxY() );
00494 out.WriteNewLine();
00495 }
00496 else
00497 {
00498 out.WriteStartElement( wxT("derived") );
00499 m_axisY->Save( this, out, towrite);
00500 out.WriteEndElement();
00501 }
00502 }
00503
00504 void a2dCurvesArea::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
00505 {
00506 a2dPolygonLClipper::DoLoad( parent, parser, xmlparts );
00507
00508 if ( xmlparts == a2dXmlSer_attrib )
00509 {
00510 m_showyaxis = parser.RequireAttributeValueBool( wxT("showyaxis") );
00511
00512 m_intrect.SetMin( parser.RequireAttributeValueDouble( wxT("ixmin") ),
00513 parser.RequireAttributeValueDouble( wxT("iymin") ) );
00514 m_intrect.SetMax( parser.RequireAttributeValueDouble( wxT("ixmax") ),
00515 parser.RequireAttributeValueDouble( wxT("iymax") ) );
00516
00517
00518
00519 }
00520 else
00521 {
00522 parser.Require( START_TAG, wxT("derived") );
00523 parser.Next();
00524
00525 m_axisY->Load( parent, parser );
00526 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_axisY );
00527
00528 parser.Require( END_TAG, wxT("derived") );
00529 parser.Next();
00530 }
00531 }
00532 #endif
00533
00534 #include <wx/arrimpl.cpp>
00535 WX_DEFINE_OBJARRAY(a2dCurvesAreaListBase);
00536
00537 a2dCurvesAreaList::a2dCurvesAreaList()
00538 : m_group(NULL)
00539 {
00540 m_autoshowyaxes = false;
00541 a2dBoundingBox extbox(0,0,1,1);
00542 a2dSmrtPtr<a2dCurvesArea> curvesarea = new a2dCurvesArea();
00543 curvesarea->SetInternalBoundaries(extbox, 0, 0, 1, 1 );
00544 Add(curvesarea);
00545 curvesarea->SetGroup(m_group);
00546 m_leftAxisY = curvesarea;
00547 }
00548
00549 a2dCurvesAreaList::a2dCurvesAreaList( const a2dCurvesAreaList &other, a2dObject::CloneOptions options)
00550 : m_group(NULL)
00551 {
00552 m_autoshowyaxes = other.m_autoshowyaxes;
00553 for(size_t i=0; i < other.GetCount(); i++)
00554 {
00555 a2dSmrtPtr<a2dCurvesArea> area = (a2dCurvesArea*)(other.Item(i).Get()->Clone(a2dObject::CloneOptions( options & ~ a2dObject::clone_seteditcopy )));
00556 Add( area );
00557 area->SetGroup(m_group);
00558 if(other[i].Get() == other.m_leftAxisY)
00559 m_leftAxisY = area;
00560 if(other[i].Get() == other.m_rightAxisY)
00561 m_rightAxisY = area;
00562 }
00563 }
00564
00565 a2dCurvesAreaList::~a2dCurvesAreaList()
00566 {
00567 Clear();
00568 }
00569
00570 a2dObject* a2dCurvesAreaList::Clone(a2dObject::CloneOptions options) const
00571 {
00572 a2dCurvesAreaList* cloneArea = new a2dCurvesAreaList(*this, options);
00573 return cloneArea;
00574 }
00575
00576 a2dCurvesArea* a2dCurvesAreaList::GetCurvesArea(const wxString& curvesAreaName)
00577 {
00578 a2dCurvesArea* emptyArea = NULL;
00579 for(size_t i=0; i < GetCount(); i++)
00580 {
00581 a2dCurvesArea* area = Item(i);
00582 if(area->GetName().IsEmpty())
00583 emptyArea = area;
00584 else if(area->GetName() == curvesAreaName)
00585 return area;
00586 }
00587 if(emptyArea != NULL && !curvesAreaName.IsEmpty())
00588 emptyArea->SetName(curvesAreaName);
00589 return emptyArea;
00590 }
00591
00592 a2dCurvesArea* a2dCurvesAreaList::GetCurvesArea(const wxString& curvesAreaName) const
00593 {
00594 a2dCurvesArea* emptyArea = NULL;
00595 for(size_t i=0; i < GetCount(); i++)
00596 {
00597 a2dCurvesArea* area = Item(i);
00598 if(area->GetName() == curvesAreaName)
00599 return area;
00600 }
00601 return emptyArea;
00602 }
00603
00604 void a2dCurvesAreaList::SetBoundaries(const a2dBoundingBox& extbox)
00605 {
00606 for(size_t i=0; i < GetCount(); i++)
00607 {
00608 a2dCurvesArea* area = Item(i);
00609 area->SetBoundaries(extbox);
00610 }
00611 }
00612
00613 bool a2dCurvesAreaList::ProcessCanvasObjectEvent( a2dIterC& ic, a2dHitEvent& hitEvent )
00614 {
00615 for(size_t i=0; i < GetCount(); i++)
00616 {
00617 a2dCurvesArea* area = Item(i);
00618 area->ProcessCanvasObjectEvent(ic, hitEvent );
00619 }
00620 return hitEvent.m_processed;
00621 }
00622
00623 void a2dCurvesAreaList::DoWalker( wxObject* parent, a2dWalkerIOHandler& handler )
00624 {
00625 handler.WalkTask( parent, this, a2dWalker_a2dDerivedCanvasObjectStart );
00626 a2dObject::DoWalker( parent, handler );
00627
00628 for(size_t i=0; i < GetCount(); i++)
00629 {
00630 a2dCurvesArea* area = Item(i);
00631 if (area)
00632 area->Walker( this, handler );
00633
00634 }
00635 handler.WalkTask( parent, this, a2dWalker_a2dDerivedCanvasObjectEnd );
00636 }
00637
00638 a2dCanvasObject* a2dCurvesAreaList::IsHitCurvesWorld (a2dCurvesArea* &area, a2dIterC& ic, a2dHitEvent& hitEvent )
00639 {
00640 for(size_t i=0; i < GetCount(); i++)
00641 {
00642 area = Item(i);
00643 a2dCanvasObject* curve = area->IsHitCurvesWorld ( ic, hitEvent );
00644 if(curve)
00645 return curve;
00646 }
00647 return NULL;
00648 }
00649
00650 int a2dCurvesAreaList::AppendInternalBoundaries(a2dBboxHash* irectHash)
00651 {
00652 for(size_t i=0; i < GetCount(); i++)
00653 {
00654 a2dCurvesArea* area = Item(i);
00655 const a2dBoundingBox& aRect = area->GetInternalBoundaries();
00656 (*irectHash)[area->GetName()] = aRect;
00657 }
00658 return GetCount();
00659 }
00660
00661 int a2dCurvesAreaList::AppendCurvesBoundaries(a2dBboxHash* irectHash)
00662 {
00663 for(size_t i=0; i < GetCount(); i++)
00664 {
00665 a2dCurvesArea* area = Item(i);
00666 a2dBoundingBox abox = area->GetCurvesBoundaries();
00667 a2dBoundingBox aRect(abox);
00668 (*irectHash)[area->GetName()] = aRect;
00669 }
00670 return GetCount();
00671 }
00672
00673 a2dBoundingBox& a2dCurvesAreaList::Expand(a2dBoundingBox& bbox) const
00674 {
00675
00676
00677
00678
00679
00680
00681
00682 if(m_leftAxisY)
00683 m_leftAxisY->Expand(bbox);
00684 if(m_rightAxisY)
00685 m_rightAxisY->Expand(bbox);
00686 return bbox;
00687 }
00688
00689 void a2dCurvesAreaList::AddPending( a2dIterC& ic )
00690 {
00691 for(size_t i=0; i < GetCount(); i++)
00692 {
00693 a2dCurvesArea* area = Item(i);
00694 area->AddPending(ic);
00695 }
00696 }
00697
00698 bool a2dCurvesAreaList::Update( a2dCanvasObject::UpdateMode mode )
00699 {
00700 bool retCode = false;
00701 a2dCurvesArea* leftAxisY = NULL;
00702 a2dCurvesArea* rightAxisY = NULL;
00703 bool leftOK = m_leftAxisY != (a2dCurvesArea*)NULL ? m_leftAxisY->IsCurvesHighlighted() : false;
00704 bool rightOK = m_rightAxisY != (a2dCurvesArea*)NULL ? m_rightAxisY->IsCurvesHighlighted() : false;
00705 for(size_t i=0; i < GetCount(); i++)
00706 {
00707 a2dCurvesArea* area = Item(i);
00708
00709 if(m_autoshowyaxes)
00710 area->SetShowYaxis(false);
00711
00712 retCode = area->Update(mode) || retCode;
00713 if(m_autoshowyaxes)
00714 {
00715 if(!leftOK || !rightOK)
00716 {
00717 if(area->IsCurvesHighlighted())
00718 {
00719 if(!leftAxisY)
00720 leftAxisY = area;
00721 else if(!rightAxisY)
00722 rightAxisY = area;
00723 }
00724 }
00725 }
00726 }
00727
00728 if(m_autoshowyaxes)
00729 {
00730 if(!leftOK)
00731 {
00732 if(leftAxisY)
00733 {
00734 if(leftAxisY != m_rightAxisY)
00735 {
00736 m_leftAxisY = leftAxisY;
00737 leftOK = true;
00738 }
00739 }
00740 if(!leftOK && rightAxisY)
00741 {
00742 if(rightAxisY != m_rightAxisY)
00743 {
00744 m_leftAxisY = rightAxisY;
00745 leftOK = true;
00746 }
00747 }
00748 }
00749 if(!rightOK)
00750 {
00751 if(rightAxisY)
00752 {
00753 if(rightAxisY != m_leftAxisY)
00754 {
00755 m_rightAxisY = rightAxisY;
00756 rightOK = true;
00757 }
00758 }
00759 if(!rightOK && leftAxisY)
00760 {
00761 if(leftAxisY != m_leftAxisY)
00762 {
00763 m_rightAxisY = leftAxisY;
00764 rightOK = true;
00765 }
00766 }
00767 }
00768 }
00769 if(m_leftAxisY != (a2dCurvesArea*)NULL)
00770 {
00771 if(m_autoshowyaxes)
00772 {
00773 m_leftAxisY->SetShowYaxis(true);
00774 m_leftAxisY->GetAxisY()->SetInvertTic(false);
00775 retCode = m_leftAxisY->Update(mode) || retCode;
00776 }
00777 }
00778 if(m_rightAxisY != (a2dCurvesArea*)NULL)
00779 {
00780 if(m_autoshowyaxes)
00781 {
00782 m_rightAxisY->SetShowYaxis(true);
00783 m_rightAxisY->GetAxisY()->SetInvertTic(true);
00784 retCode = m_rightAxisY->Update(mode) || retCode;
00785 }
00786 }
00787 return retCode;
00788 }
00789
00790 void a2dCurvesAreaList::SetAxes(const a2dBoundingBox& extbox, double x, double y, double& zerox, double& zeroy, double& ixmin, double& ixmax)
00791 {
00792
00793 double tzerox, tzeroy, tixmin, tixmax;
00794 for(size_t i=0; i < GetCount(); i++)
00795 {
00796 a2dCurvesArea* area = Item(i);
00797 if(area != m_leftAxisY && area != m_rightAxisY)
00798 area->SetAxes(extbox, area->GetAxisY()->GetPosition(), y, tzerox, tzeroy, tixmin, tixmax);
00799 }
00800
00801 if(m_leftAxisY != (a2dCurvesArea*)NULL)
00802 {
00803 if(m_autoshowyaxes)
00804 m_leftAxisY->SetAxes(extbox, m_leftAxisY->m_intrect.GetMinX(), m_leftAxisY->m_intrect.GetMinY(), zerox, zeroy, ixmin, ixmax);
00805 else
00806 m_leftAxisY->SetAxes(extbox, m_leftAxisY->GetAxisY()->GetPosition(), y, zerox, zeroy, ixmin, ixmax);
00807
00808 }
00809 if(m_rightAxisY != (a2dCurvesArea*)NULL)
00810 {
00811 if(m_autoshowyaxes)
00812 m_rightAxisY->SetAxes(extbox, m_rightAxisY->m_intrect.GetMaxX(), m_rightAxisY->m_intrect.GetMinY(), tzerox, tzeroy, tixmin, tixmax);
00813 else
00814 m_rightAxisY->SetAxes(extbox, m_rightAxisY->GetAxisY()->GetPosition(), y, tzerox, tzeroy, tixmin, tixmax);
00815 }
00816 }
00817
00818 void a2dCurvesAreaList::RenderAxesY ( a2dIterC& ic, OVERLAP clipparent )
00819 {
00820 if(m_leftAxisY != (a2dCurvesArea*)NULL)
00821 {
00822 if(m_leftAxisY->m_showyaxis)
00823 m_leftAxisY->m_axisY->Render( ic, clipparent );
00824 }
00825 if(m_rightAxisY != (a2dCurvesArea*)NULL)
00826 {
00827 if(m_rightAxisY->m_showyaxis)
00828 m_rightAxisY->m_axisY->Render( ic, clipparent );
00829 }
00830 }
00831
00832 void a2dCurvesAreaList::Render ( a2dIterC& ic, OVERLAP clipparent )
00833 {
00834 for(size_t i=0; i < GetCount(); i++)
00835 {
00836 a2dCurvesArea* area = Item(i);
00837 ic.GetDrawer2D()->SetDrawerFill( *a2dTRANSPARENT_FILL );
00838 ic.GetDrawer2D()->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
00839 area->Render(ic, clipparent);
00840 }
00841 }
00842
00843 void a2dCurvesAreaList::SetShowLeftYaxis(const wxString& curveAreaName, bool showyaxis)
00844 {
00845
00846
00847 for(size_t i=0; i < GetCount(); i++)
00848 {
00849 a2dCurvesArea* area = Item(i);
00850 if(area->GetName() == curveAreaName)
00851 {
00852 if(area != m_leftAxisY)
00853 {
00854 if(m_leftAxisY != (a2dCurvesArea*) NULL)
00855 m_leftAxisY->SetShowYaxis(false);
00856 m_leftAxisY = area;
00857 }
00858 m_leftAxisY->SetShowYaxis(showyaxis);
00859 if(m_autoshowyaxes)
00860 m_leftAxisY->GetAxisY()->SetInvertTic(false);
00861 break;
00862 }
00863 }
00864 }
00865
00866 void a2dCurvesAreaList::SetShowRightYaxis(const wxString& curveAreaName, bool showyaxis)
00867 {
00868
00869
00870 for(size_t i=0; i < GetCount(); i++)
00871 {
00872 a2dCurvesArea* area = Item(i);
00873 if(area->GetName() == curveAreaName)
00874 {
00875 if(area != m_rightAxisY)
00876 {
00877 if(m_rightAxisY != (a2dCurvesArea*) NULL)
00878 {
00879 if(m_autoshowyaxes)
00880 m_rightAxisY->GetAxisY()->SetInvertTic(false);
00881 m_rightAxisY->SetShowYaxis(false);
00882 }
00883 m_rightAxisY = area;
00884 }
00885 m_rightAxisY->SetShowYaxis(showyaxis);
00886 if(m_autoshowyaxes)
00887 m_rightAxisY->GetAxisY()->SetInvertTic(true);
00888 break;
00889 }
00890 }
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 inline double a2dInternal_BoundsRound(double val, bool tics)
00903 {
00904 double abs_val = fabs(val);
00905 if(abs_val < 1E-10)
00906 return 0.;
00907 double expon = log10(abs_val);
00908 int toInt = int(expon < 0 ? expon - 1 : expon);
00909 double standardized = val*pow(10.,-toInt);
00910 if(tics)
00911 {
00912 int sign = val < 0. ? -1 : 1;
00913 double abs_standardized = fabs(standardized);
00914 if(abs_standardized <=1.0001)
00915 return pow(10.,toInt)*sign;
00916 else if(abs_standardized <=1.2501)
00917 return 1.25*pow(10.,toInt)*sign;
00918 else if(abs_standardized <=2.0001)
00919 return 2.*pow(10.,toInt)*sign;
00920 else if(abs_standardized <=2.5001)
00921 return 2.5*pow(10.,toInt)*sign;
00922 else if(abs_standardized <=5.0001)
00923 return 5.*pow(10.,toInt)*sign;
00924 return 10.*pow(10.,toInt)*sign;
00925 }
00926
00927 double expand = val < 0. ? -0.5 : 0.5;
00928 return double((int(standardized+expand))*pow(10.,toInt));
00929 }
00930
00931 double a2dBoundsRound(double val)
00932 {
00933 return a2dInternal_BoundsRound(val,false);
00934 }
00935
00936 double a2dTicsRound(double val)
00937 {
00938 return a2dInternal_BoundsRound(val,true);
00939 }
00940
00941 void a2dCurvesAreaList::SetTicY( int numLines )
00942 {
00943 if(numLines<2)
00944 numLines = 2;
00945
00946 double numLines2 = numLines/2;
00947 int precision = 0;
00948 for(size_t i=0; i < GetCount(); i++)
00949 {
00950 a2dCurvesArea* area = Item(i);
00951 a2dBoundingBox newRect = area->m_intrect;
00952
00953
00954
00955 double curHeight = newRect.GetHeight();
00956 double meanY = newRect.GetMinY() + curHeight/2.;
00957 double newHeight = a2dTicsRound(curHeight/(double)numLines)*numLines;
00958 double aTic = newHeight / (double)numLines;
00959 wxASSERT(aTic > 1E-12);
00960 double newMeanY = int((meanY/aTic)+(meanY<0. ? -0.5 : 0.5))*aTic;
00961 double newMinY = newMeanY-newHeight/2.;
00962 if(newRect.GetMinY() == 0. && newMinY < 0.)
00963 newMinY = 0.;
00964
00965 newRect.SetMinY( newMinY );
00966 double newMaxY = newMinY + newHeight;
00967 newRect.SetMaxY( newMaxY );
00968 area->SetInternalBoundaries(m_group->GetPlotAreaRect(),newRect);
00969 a2dCurveAxis* axisY = area->GetAxisY();
00970 axisY->SetTic(aTic);
00971 precision = m_group->SetAxisTicPrecision(axisY,newMinY,newMaxY);
00972 }
00973 if(precision)
00974 m_group->SetCommonTicPrecision(precision);
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 void a2dCurvesAreaList::DependencyPending( a2dWalkerIOHandler* handler )
01038 {
01039 for(size_t i=0; i < GetCount(); i++)
01040 {
01041 a2dCurvesArea* area = Item(i);
01042
01043 area->DependencyPending( handler );
01044 }
01045 }
01046
01047 bool a2dCurvesAreaList::GetPending(void)
01048 {
01049 bool retCode = false;
01050 for(size_t i=0; i < GetCount(); i++)
01051 {
01052 a2dCurvesArea* area = Item(i);
01053 retCode = retCode || area->GetPending();
01054 }
01055 return retCode;
01056 }
01057
01058 void a2dCurvesAreaList::UpdateViewDependentObjects( a2dIterC& ic )
01059 {
01060 for(size_t i=0; i < GetCount(); i++)
01061 {
01062 a2dCurvesArea* area = Item(i);
01063 area->UpdateViewDependentObjects( ic );
01064 }
01065 }
01066
01067 void a2dCurvesAreaList::SetCursor(a2dCursor* cursor)
01068 {
01069 cursor->RemoveMarkers();
01070 for(size_t i=0; i < GetCount(); i++)
01071 {
01072 a2dCurvesArea* area = Item(i);
01073 a2dMarker* marker = area->GetCursorMarker();
01074 if(marker)
01075 cursor->AddMarker(marker);
01076 }
01077 }
01078
01079 bool a2dCurvesAreaList::GetHasSelectedObjectsBelow()
01080 {
01081 bool retCode = false;
01082 for(size_t i=0; i < GetCount() && !retCode; i++)
01083 {
01084 a2dCurvesArea* area = Item(i);
01085 retCode = retCode || area->GetHasSelectedObjectsBelow();
01086 }
01087 return retCode;
01088 }
01089
01090 bool a2dCurvesAreaList::GetHasToolObjectsBelow()
01091 {
01092 bool retCode = false;
01093 for(size_t i=0; i < GetCount() && !retCode; i++)
01094 {
01095 a2dCurvesArea* area = Item(i);
01096 retCode = retCode || area->GetHasToolObjectsBelow();
01097 }
01098 return retCode;
01099 }
01100
01101 void a2dCurvesAreaList::SetClippingFromBox(a2dBoundingBox& bbox)
01102 {
01103 for(size_t i=0; i < GetCount(); i++)
01104 {
01105 a2dCurvesArea* area = Item(i);
01106 area->SetClippingFromBox(bbox);
01107 }
01108 }
01109
01110 void a2dCurvesAreaList::SetGroup(a2dCanvasXYDisplayGroupAreas* aGroup)
01111 {
01112 m_group = aGroup;
01113 for(size_t i=0; i < GetCount(); i++)
01114 {
01115 a2dCurvesArea* area = Item(i);
01116 area->SetGroup(aGroup);
01117 }
01118 }
01119
01120 #if wxART2D_USE_CVGIO
01121 void a2dCurvesAreaList::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList* towrite )
01122 {
01123 a2dObject::DoSave( parent, out, xmlparts, towrite );
01124
01125
01126 if ( xmlparts == a2dXmlSer_attrib )
01127 {
01128 }
01129 else
01130 {
01131 out.WriteStartElement( wxT("derived") );
01132
01133 for(size_t i=0; i < GetCount(); i++)
01134 {
01135 a2dCurvesArea* area = Item(i);
01136 area->Save(this, out, towrite);
01137 }
01138
01139 out.WriteEndElement();
01140 }
01141 }
01142
01143 void a2dCurvesAreaList::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
01144 {
01145 a2dObject::DoLoad( parent, parser, xmlparts );
01146
01147
01148 if ( xmlparts == a2dXmlSer_attrib )
01149 {
01150 }
01151 else
01152 {
01153 parser.Require( START_TAG, wxT("derived") );
01154 parser.Next();
01155
01156
01157 wxASSERT(0);
01158
01159 parser.Require( END_TAG, wxT("derived") );
01160 parser.Next();
01161 }
01162 }
01163 #endif
01164
01165
01166
01167
01168 const a2dPropertyIdRefObject a2dCanvasXYDisplayGroupAreas::PROPID_strokegrid( wxT("strokegrid"), a2dPropertyId::flag_none, 0 );
01169 const a2dPropertyIdRefObject a2dCanvasXYDisplayGroupAreas::PROPID_fillAxisArea( wxT("fillAxisArea"), a2dPropertyId::flag_none, 0 );
01170
01171
01172 A2D_BEGIN_EVENT_TABLE(a2dCanvasXYDisplayGroupAreas,a2dCanvasObject)
01173 A2D_EVT_CANVASOBJECT_MOUSE_EVENT( a2dCanvasXYDisplayGroupAreas::OnCanvasObjectMouseEvent )
01174 A2D_EVT_CHAR( a2dCanvasXYDisplayGroupAreas::OnChar )
01175 A2D_END_EVENT_TABLE()
01176
01177 void a2dCanvasXYDisplayGroupAreas::DoWalker( wxObject* parent, a2dWalkerIOHandler& handler )
01178 {
01179 handler.WalkTask( parent, this, a2dWalker_a2dDerivedCanvasObjectStart );
01180 a2dCanvasObject::DoWalker( parent, handler );
01181
01182 if (m_axesarealist)
01183 m_axesarealist->Walker( this, handler );
01184
01185 if( m_axisX )
01186 m_axisX->Walker( this, handler );
01187
01188
01189 if( m_cursor )
01190 m_cursor->Walker( this, handler );
01191
01192 handler.WalkTask( parent, this, a2dWalker_a2dDerivedCanvasObjectEnd );
01193 }
01194
01195 void a2dCanvasXYDisplayGroupAreas::DoAddPending( a2dIterC& ic )
01196 {
01197 a2dCanvasObject::DoAddPending( ic );
01198
01199 m_axisX->AddPending( ic );
01200 if(m_cursor)
01201 m_cursor->AddPending( ic );
01202 m_axesarealist->AddPending(ic);
01203 }
01204
01205 bool a2dCanvasXYDisplayGroupAreas::DoStartEdit( wxUint16 editmode, wxEditStyle editstyle )
01206 {
01207 if ( m_flags.m_editable )
01208 {
01209 PROPID_IncludeChildren->SetPropertyToObject( this, false );
01210 PROPID_Allowrotation->SetPropertyToObject( this, false );
01211 PROPID_Allowskew->SetPropertyToObject( this, false );
01212
01213 return a2dCanvasObject::DoStartEdit( editmode, editstyle );
01214 }
01215
01216 return false;
01217 }
01218
01219 bool a2dCanvasXYDisplayGroupAreas::ProcessCanvasObjectEvent( a2dIterC& ic, a2dHitEvent& hitEvent )
01220 {
01221 if ( ic.GetCanvasView()->GetCaptured() == this )
01222 {
01223 a2dCanvasObject::ProcessCanvasObjectEvent( ic, hitEvent );
01224 return hitEvent.m_processed;
01225 }
01226
01227 hitEvent.m_isHit = false;
01228
01229
01230 ic.GetInverseTransform().TransformPoint( hitEvent.m_x, hitEvent.m_y, hitEvent.m_relx, hitEvent.m_rely );
01231 if ( GetBbox().PointInBox(hitEvent.m_relx, hitEvent.m_rely, m_worldExtend + ic.GetHitMarginWorld() + ic.ExtendDeviceToWorld( m_pixelExtend ) ) )
01232 {
01233 a2dIterCU cu( ic, this );
01234
01235 m_axesarealist->ProcessCanvasObjectEvent( ic, hitEvent );
01236 m_axisX->ProcessCanvasObjectEvent( ic, hitEvent );
01237 }
01238
01239 a2dCanvasObject::ProcessCanvasObjectEvent( ic, hitEvent );
01240
01241 return hitEvent.m_processed;
01242 }
01243
01244
01245 void a2dCanvasXYDisplayGroupAreas::OnChar(wxKeyEvent& event)
01246 {
01247 if ( m_flags.m_editingCopy )
01248 {
01249 switch(event.GetKeyCode())
01250 {
01251 case WXK_LEFT:
01252 {
01253 ChangeCursorPos(-1);
01254 }
01255 break;
01256 case WXK_PAGEDOWN:
01257 {
01258 ChangeCursorPos(-10);
01259 }
01260 break;
01261 case WXK_HOME:
01262 {
01263 ChangeCursorPos(-1024);
01264 }
01265 break;
01266 case WXK_RIGHT:
01267 {
01268 ChangeCursorPos(1);
01269 }
01270 break;
01271 case WXK_PAGEUP:
01272 {
01273 ChangeCursorPos(10);
01274 }
01275 break;
01276 case WXK_END:
01277 {
01278 ChangeCursorPos(1024);
01279 }
01280 break;
01281 default:
01282 event.Skip();
01283 break;
01284 }
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311 }
01312 else
01313 event.Skip();
01314 }
01315
01316 void a2dCanvasXYDisplayGroupAreas::OnCanvasObjectMouseEvent( a2dCanvasObjectMouseEvent& event )
01317 {
01318 a2dIterC* ic = event.GetIterC();
01319
01320 if ( m_flags.m_editingCopy )
01321 {
01322
01323 double xw,yw;
01324 xw = event.GetX();
01325 yw = event.GetY();
01326
01327 a2dAffineMatrix atWorld = ic->GetTransform();
01328
01329 if ( event.GetMouseEvent().LeftDown() )
01330 {
01331 if ( event.GetMouseEvent().m_shiftDown )
01332 {
01333 #if wxART2D_USE_EDITOR
01334 a2dCanvasXYDisplayGroupAreas* original = wxStaticCast( PROPID_Original->GetPropertyValue( this ).Get(), a2dCanvasXYDisplayGroupAreas );
01335 a2dIterCU cu( *ic, original );
01336
01337 ic->SetCorridorPath( true, NULL );
01338
01339 a2dStToolContr* controller = wxStaticCast( PROPID_Controller->GetPropertyValue( this ).Get(), a2dStToolContr );
01340 a2dDrawRectangleTool* drawrec = new a2dDrawRectangleTool( controller );
01341 controller->PushTool( drawrec );
01342 drawrec->SetEditAtEnd( true );
01343 #else //wxART2D_USE_EDITOR
01344 wxMessageBox( wxT("Need editor module enabled for this") );
01345 #endif //wxART2D_USE_EDITOR
01346
01347 SetPending( true );
01348 ic->GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
01349 }
01350 else if ( event.GetMouseEvent().m_controlDown )
01351 {
01352 #if wxART2D_USE_EDITOR
01353 a2dCanvasXYDisplayGroupAreas* original = wxStaticCast( PROPID_Original->GetPropertyValue( this ).Get(), a2dCanvasXYDisplayGroupAreas );
01354 a2dIterCU cu( *ic, original );
01355
01356 ic->SetCorridorPath( true, NULL );
01357
01358 a2dStToolContr* controller = wxStaticCast( PROPID_Controller->GetPropertyValue( this ).Get(), a2dStToolContr );
01359 a2dDrawPolygonLTool* draw = new a2dDrawPolygonLTool( controller );
01360 controller->PushTool( draw );
01361 draw->SetEditAtEnd( true );
01362 #else //wxART2D_USE_EDITOR
01363 wxMessageBox( wxT("Need editor module enabled for this") );
01364 #endif //wxART2D_USE_EDITOR
01365
01366 SetPending( true );
01367 ic->GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
01368 }
01369 else
01370 {
01371 a2dHitEvent hitevent = a2dHitEvent(xw, yw, false);
01372 if ( IsHitWorld( *ic, hitevent ) )
01373 {
01374
01375
01376 a2dCanvasXYDisplayGroupAreas* original = wxStaticCast( PROPID_Original->GetPropertyValue( this ).Get(), a2dCanvasXYDisplayGroupAreas );
01377
01378 a2dHitEvent hitinfo( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
01379 hitinfo.m_xyRelToChildren = true;
01380 a2dCanvasObject* marker = original->ChildIsHitWorld( *ic, hitinfo );
01381 if ( marker && marker->GetEditable() )
01382 {
01383 #if wxART2D_USE_EDITOR
01384 a2dIterCU cu( *ic, original );
01385 a2dStToolContr* controller = wxStaticCast( PROPID_Controller->GetPropertyValue( this ).Get(), a2dStToolContr );
01386
01387 ic->SetCorridorPath( true, NULL );
01388 controller->StartEditingObject( marker, *ic );
01389
01390 #else //wxART2D_USE_EDITOR
01391 wxMessageBox( wxT("Need editor module enabled for this") );
01392 #endif //wxART2D_USE_EDITOR
01393
01394 SetPending( true );
01395 ic->GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
01396 event.Skip();
01397 return;
01398 }
01399
01400 a2dIterCU cu( *ic, original );
01401
01402 a2dCurvesArea* curvesarea;
01403 a2dHitEvent hitinfocurve( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
01404 hitinfocurve.m_xyRelToChildren = true;
01405 a2dCanvasObject* curve = original->m_axesarealist->IsHitCurvesWorld( curvesarea, *ic, hitinfocurve );
01406 if ( curve && curve->GetEditable() )
01407 {
01408 #if wxART2D_USE_EDITOR
01409
01410 a2dStToolContr* controller = wxStaticCast( PROPID_Controller->GetPropertyValue( this ).Get(), a2dStToolContr );
01411
01412 ic->SetCorridorPath( true, NULL );
01413 controller->StartEditingObject( curve, *ic );
01414
01415 #else //wxART2D_USE_EDITOR
01416 wxMessageBox( wxT("Need editor module enabled for this") );
01417 #endif //wxART2D_USE_EDITOR
01418
01419 SetPending( true );
01420 ic->GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
01421 event.Skip();
01422 return;
01423 }
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 a2dHitEvent hitinfomarker( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
01451 hitinfomarker.m_xyRelToChildren = true;
01452 a2dCanvasObject* axisMarker = original->m_axisX->ChildIsHitWorld( *ic, hitinfomarker );
01453 if ( axisMarker && axisMarker->GetEditable() )
01454 {
01455 #if wxART2D_USE_EDITOR
01456 a2dIterCU cu2( *ic, original->m_axisX );
01457
01458 a2dStToolContr* controller = wxStaticCast( PROPID_Controller->GetPropertyValue( this ).Get(), a2dStToolContr );
01459
01460 ic->SetCorridorPath( true, NULL );
01461 controller->StartEditingObject( axisMarker, *ic );
01462
01463 #else //wxART2D_USE_EDITOR
01464 wxMessageBox( wxT("Need editor module enabled for this") );
01465 #endif //wxART2D_USE_EDITOR
01466
01467 SetPending( true );
01468 ic->GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
01469 event.Skip();
01470 return;
01471 }
01472
01473 else
01474 event.Skip();
01475 }
01476 else
01477 EndEdit();
01478 }
01479 }
01480 else if ( event.GetMouseEvent().LeftDClick() )
01481 {
01482 EndEdit();
01483 }
01484 else if ( event.GetMouseEvent().Moving() )
01485 {
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504 event.Skip();
01505 }
01506 else
01507 event.Skip();
01508 }
01509 else
01510 event.Skip();
01511 }
01512
01513 a2dCanvasXYDisplayGroupAreas::a2dCanvasXYDisplayGroupAreas( double x, double y )
01514 : a2dCanvasObject(), m_plotrect(0,0,1,1)
01515 {
01516 m_lworld.Translate(x,y);
01517
01518 m_layer = wxLAYER_DEFAULT;
01519 m_cursorOnlyByCurves = true;
01520
01521 m_showgrid = true;
01522 m_showxaxis = true;
01523 m_autoTicYPrecision = true;
01524
01525 m_strokegrid = a2dStroke(wxColour(10,17,25),16,a2dSTROKE_LONG_DASH );
01526 m_fillAxisArea = *a2dTRANSPARENT_FILL;
01527 m_strokeAxisArea = *a2dTRANSPARENT_STROKE;
01528
01529 m_axesarealist = new a2dCurvesAreaList();
01530 m_axesarealist->SetGroup(this);
01531
01532 m_axisX = new a2dCurveAxisLin();
01533 }
01534
01535 a2dCanvasXYDisplayGroupAreas::~a2dCanvasXYDisplayGroupAreas()
01536 {
01537
01538 m_axisX->ReleaseChildObjects();
01539 if(m_cursor) {
01540 m_cursor->RemoveMarkers();
01541 m_cursor = NULL;
01542 }
01543
01544
01545
01546
01547
01548
01549
01550
01551 }
01552
01553 a2dCanvasXYDisplayGroupAreas::a2dCanvasXYDisplayGroupAreas( const a2dCanvasXYDisplayGroupAreas &other, CloneOptions options )
01554 :a2dCanvasObject( other, options )
01555 {
01556 m_cursorOnlyByCurves = other.m_cursorOnlyByCurves;
01557 m_showgrid = other.m_showgrid;
01558 m_showxaxis = other.m_showxaxis;
01559 m_autoTicYPrecision = other.m_autoTicYPrecision;
01560
01561 if( options & clone_members )
01562 {
01563 m_axisX = (a2dCurveAxis*) other.m_axisX->Clone( CloneOptions( options & ~ clone_seteditcopy ) );
01564 if(other.m_cursor)
01565 m_cursor = (a2dCursor*) other.m_cursor->Clone( CloneOptions( options & ~ clone_seteditcopy ) );
01566 m_strokegrid = other.m_strokegrid;
01567 m_fillAxisArea = other.m_fillAxisArea;
01568 m_strokeAxisArea = other.m_strokeAxisArea;
01569 }
01570 else
01571 {
01572 m_axisX = other.m_axisX;
01573 m_cursor = other.m_cursor;
01574 m_strokegrid = other.m_strokegrid;
01575 m_fillAxisArea = other.m_fillAxisArea;
01576 m_strokeAxisArea = other.m_strokeAxisArea;
01577 }
01578
01579 m_plotrect = other.m_plotrect;
01580
01581 if( options & clone_members )
01582 m_axesarealist = (a2dCurvesAreaList*) other.m_axesarealist->Clone( CloneOptions( options & ~ clone_seteditcopy ) );
01583 else
01584 m_axesarealist = other.m_axesarealist;
01585 m_axesarealist->SetGroup(this);
01586 if(m_axisX && GetCanvasDocument())
01587 m_axisX->SetCanvasDocument(GetCanvasDocument());
01588
01589 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
01590
01591 CurrentSmartPointerOwner = this;
01592 #endif
01593 }
01594
01595 a2dObject* a2dCanvasXYDisplayGroupAreas::Clone( CloneOptions options ) const
01596 {
01597 return new a2dCanvasXYDisplayGroupAreas( *this, options );
01598 }
01599
01600 a2dCurvesArea* a2dCanvasXYDisplayGroupAreas::AddCurvesArea(const wxString& curveAreaName )
01601 {
01602 a2dSmrtPtr<a2dCurvesArea> curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01603 if(curvesarea == (a2dCurvesArea*)NULL)
01604 {
01605 curvesarea = new a2dCurvesArea(curveAreaName);
01606 wxASSERT_MSG(curvesarea != (a2dCurvesArea*)NULL, wxString::Format(wxT("can't create curves area with name '%s' "), curveAreaName.c_str()) );
01607
01608 curvesarea->SetBoundaries(m_plotrect);
01609 m_axesarealist->Add(curvesarea);
01610 curvesarea->SetGroup(this);
01611
01612 if(m_axesarealist->m_leftAxisY == (a2dCurvesArea*)NULL)
01613 m_axesarealist->m_leftAxisY = curvesarea;
01614 else if(m_axesarealist->m_rightAxisY == (a2dCurvesArea*)NULL)
01615 {
01616 m_axesarealist->m_rightAxisY = curvesarea;
01617 if(m_axesarealist->GetAutoShowYAxes())
01618 m_axesarealist->m_rightAxisY->GetAxisY()->SetInvertTic(true);
01619 }
01620 else
01621 {
01622 m_axesarealist->m_rightAxisY->SetShowYaxis(false);
01623
01624 m_axesarealist->m_rightAxisY = curvesarea;
01625 if(m_axesarealist->GetAutoShowYAxes())
01626 m_axesarealist->m_rightAxisY->GetAxisY()->SetInvertTic(true);
01627 }
01628 SetPending(true);
01629 }
01630 return curvesarea;
01631 }
01632
01633 void a2dCanvasXYDisplayGroupAreas::AddCurveToArea(const wxString& curveAreaName, a2dCurve* curve, const wxString curvename )
01634 {
01635 a2dSmrtPtr<a2dCurvesArea> curvesarea = AddCurvesArea(curveAreaName);
01636 if(curvesarea)
01637 {
01638 curvesarea->AddCurve(curve, curvename);
01639 SetPending(true);
01640 }
01641 }
01642
01643 void a2dCanvasXYDisplayGroupAreas::InsertCurveToArea( const wxString& curveAreaName, size_t before, a2dCurve* curve, const wxString curvename )
01644 {
01645 a2dSmrtPtr<a2dCurvesArea> curvesarea = AddCurvesArea(curveAreaName);
01646 if(curvesarea)
01647 {
01648 curvesarea->InsertCurve(before, curve, curvename);
01649 SetPending(true);
01650 }
01651 }
01652
01653 void a2dCanvasXYDisplayGroupAreas::AddMarkerToArea(const wxString& curveAreaName, a2dMarker* marker )
01654 {
01655 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01656 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01657 if(curvesarea)
01658 {
01659 curvesarea->AddMarker(marker);
01660 SetPending(true);
01661 }
01662 if(m_cursor)
01663 m_cursor->AddMarker(marker);
01664 }
01665
01666 void a2dCanvasXYDisplayGroupAreas::RemoveMarkerFromArea(const wxString& curveAreaName, a2dMarker* marker )
01667 {
01668 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01669 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01670 if(curvesarea)
01671 {
01672 curvesarea->RemoveMarker(marker);
01673 SetPending(true);
01674 }
01675 if(m_cursor)
01676 m_cursor->RemoveMarker(marker);
01677 }
01678
01679 void a2dCanvasXYDisplayGroupAreas::SetCursor(a2dCursor* cursor)
01680 {
01681 a2dCursor* oldcursor = m_cursor;
01682 m_cursor = NULL;
01683 if(oldcursor)
01684 ReleaseChild(m_cursor);
01685 m_cursor = cursor;
01686
01687 if(m_cursor)
01688 m_axesarealist->SetCursor(m_cursor);
01689
01690 SetPending(true);
01691 }
01692
01693 void a2dCanvasXYDisplayGroupAreas::ChangeCursorPos(double step)
01694 {
01695 if(!m_cursor)
01696 return;
01697 a2dCurvesArea* baseArea = m_axesarealist->GetBaseCurvesArea();
01698 double newposx, tempposy;
01699 a2dAffineMatrix mat = baseArea->GetCurveAreaTransform();
01700 a2dBoundingBox ibox = baseArea->GetInternalBoundaries();
01701 mat.Invert();
01702 mat.TransformPoint(m_cursor->GetPosX(),ibox.GetMinY(),newposx,tempposy);
01703
01704 double currentPosition = newposx;
01705 double smallStep = step/(fabs(step));
01706 newposx += step;
01707 if(newposx < ibox.GetMinX())
01708 {
01709 newposx = ibox.GetMinX();
01710 smallStep = 1;
01711 }
01712 if(newposx > ibox.GetMaxX())
01713 {
01714 newposx = ibox.GetMaxX();
01715 smallStep = -1;
01716 }
01717 if(m_cursorOnlyByCurves)
01718 {
01719 bool currentPositionOK = m_cursor->CheckPosition(currentPosition);
01720 double newposition = newposx;
01721 while(!m_cursor->CheckPosition(newposx))
01722 {
01723 newposx += smallStep;
01724 if(newposx < ibox.GetMinX() || newposx > ibox.GetMaxX())
01725 {
01726 newposx = newposition;
01727 while(!m_cursor->CheckPosition(newposx))
01728 {
01729 newposx -= smallStep;
01730 if(newposx < ibox.GetMinX() || newposx > ibox.GetMaxX())
01731 {
01732 if(currentPositionOK)
01733 return;
01734 newposx = newposition;
01735 m_cursor->SetPosition(newposx,tempposy,baseArea->GetCurveAreaTransform());
01736 return;
01737 }
01738 }
01739 }
01740 }
01741 }
01742 m_cursor->SetPosition(newposx,tempposy,baseArea->GetCurveAreaTransform());
01743 }
01744
01745 a2dCurve* a2dCanvasXYDisplayGroupAreas::GetCurveFromArea(const wxString& curveAreaName, const wxString curvename )
01746 {
01747 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01748 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curve by name '%s' "), curveAreaName.c_str()));
01749 if(curvesarea)
01750 return curvesarea->GetCurve(curvename);
01751 return NULL;
01752 }
01753
01754 a2dCanvasObjectList* a2dCanvasXYDisplayGroupAreas::GetCurvesFromArea(const wxString& curveAreaName)
01755 {
01756 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01757 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01758 if(curvesarea)
01759 return curvesarea->GetCurves();
01760 return NULL;
01761 }
01762
01763 a2dBoundingBox a2dCanvasXYDisplayGroupAreas::GetCurvesBoundariesFromArea(const wxString& curveAreaName)
01764 {
01765 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01766 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01767 if(curvesarea)
01768 {
01769 return curvesarea->GetCurvesBoundaries();
01770 }
01771 a2dBoundingBox ibbox;
01772 return ibbox;
01773 }
01774
01775 a2dCurveAxis* a2dCanvasXYDisplayGroupAreas::GetAreaAxisY(const wxString& curveAreaName) const
01776 {
01777 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01778 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01779 return curvesarea->GetAxisY();
01780 }
01781
01782 void a2dCanvasXYDisplayGroupAreas::SetAreaAxisY( const wxString& curveAreaName, a2dCurveAxis* axisY )
01783 {
01784 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01785 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01786 curvesarea->SetAxisY(axisY);
01787 SetPending(true);
01788 }
01789
01790 void a2dCanvasXYDisplayGroupAreas::SetShowLeftYaxis(const wxString& curveAreaName, bool showyaxis)
01791 {
01792 m_axesarealist->SetShowLeftYaxis(curveAreaName, showyaxis);
01793 SetPending(true);
01794 }
01795
01796 void a2dCanvasXYDisplayGroupAreas::SetShowRightYaxis(const wxString& curveAreaName, bool showyaxis)
01797 {
01798 m_axesarealist->SetShowRightYaxis(curveAreaName, showyaxis);
01799 SetPending(true);
01800 }
01801
01802 void a2dCanvasXYDisplayGroupAreas::SetGridStroke( const a2dStroke& stroke)
01803 {
01804 m_strokegrid = stroke;
01805 SetPending(true);
01806 }
01807
01808 void a2dCanvasXYDisplayGroupAreas::SetAxisAreaFill( const a2dFill& fill)
01809 {
01810 m_fillAxisArea = fill;
01811 SetPending(true);
01812 }
01813
01814 void a2dCanvasXYDisplayGroupAreas::SetAxisAreaStroke( const a2dStroke& stroke)
01815 {
01816 m_strokeAxisArea = stroke;
01817 SetPending(true);
01818 }
01819
01820 void a2dCanvasXYDisplayGroupAreas::SetBoundaries(const a2dBoundingBox& extbox)
01821 {
01822 SetPending(true);
01823 m_plotrect = extbox;
01824
01825 m_axesarealist->SetBoundaries(extbox);
01826 }
01827
01828 void a2dCanvasXYDisplayGroupAreas::SetInternalBoundaries( double ximin, double yimin, double ximax, double yimax, const wxString& curveAreaName )
01829 {
01830 a2dCurvesArea* curvesarea = AddCurvesArea(curveAreaName);
01831 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curve area by name '%s' "), curveAreaName.c_str()));
01832 if(curvesarea)
01833 {
01834 curvesarea->SetInternalBoundaries(m_plotrect, ximin, yimin, ximax, yimax);
01835 }
01836 SetPending(true);
01837 }
01838
01839 void a2dCanvasXYDisplayGroupAreas::SetInternalXBoundaries(double ximin, double ximax)
01840 {
01841 for(size_t i=0; i < m_axesarealist->GetCount(); i++)
01842 {
01843 a2dCurvesArea* area = m_axesarealist->Item(i);
01844 a2dBoundingBox newRect = area->GetInternalBoundaries();
01845 newRect.SetMinX( ximin );
01846 newRect.SetMaxX( ximax );
01847 area->SetInternalBoundaries(m_plotrect,newRect);
01848 }
01849 }
01850
01851 a2dBoundingBox a2dCanvasXYDisplayGroupAreas::GetInternalBoundaries(const wxString& curveAreaName) const
01852 {
01853 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01854 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01855 if(curvesarea)
01856 {
01857 return curvesarea->GetInternalBoundaries();
01858 }
01859 a2dBoundingBox ibbox;
01860 return ibbox;
01861 }
01862
01863 int a2dCanvasXYDisplayGroupAreas::AppendInternalBoundaries(a2dBboxHash* irectHash)
01864 {
01865 return m_axesarealist->AppendInternalBoundaries(irectHash);
01866 }
01867
01868 int a2dCanvasXYDisplayGroupAreas::AppendCurvesBoundaries(a2dBboxHash* irectHash)
01869 {
01870 return m_axesarealist->AppendCurvesBoundaries(irectHash);
01871 }
01872
01873 a2dAffineMatrix a2dCanvasXYDisplayGroupAreas::GetCurvesAreaTransform(const wxString& curveAreaName)
01874 {
01875 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
01876 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
01877 if(curvesarea)
01878 {
01879 return curvesarea->GetCurveAreaTransform();
01880 }
01881 a2dAffineMatrix amatrix;
01882 return amatrix;
01883 }
01884
01885 void a2dCanvasXYDisplayGroupAreas::DependencyPending( a2dWalkerIOHandler* handler )
01886 {
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902 if ( m_flags.m_HighLight )
01903 {
01904 bool pendingchild = false;
01905 pendingchild = pendingchild || m_axesarealist->GetPending();
01906 pendingchild = pendingchild || m_axisX->GetPending();
01907 if(m_cursor)
01908 pendingchild = pendingchild || m_cursor->GetPending();
01909
01910 if ( !m_flags.m_pending )
01911 SetPending( pendingchild );
01912 }
01913 a2dCanvasObject::DependencyPending( handler );
01914 }
01915
01916 void a2dCanvasXYDisplayGroupAreas::DoUpdateViewDependentObjects( a2dIterC& ic )
01917 {
01918 a2dCanvasObject::DoUpdateViewDependentObjects( ic );
01919 m_axesarealist->UpdateViewDependentObjects( ic );
01920 m_axisX->UpdateViewDependentObjects( ic );
01921 if(m_cursor)
01922 m_cursor->UpdateViewDependentObjects( ic );
01923 }
01924
01925 a2dBoundingBox a2dCanvasXYDisplayGroupAreas::GetPlotAreaBbox() const
01926 {
01927 return m_plotrect;
01928 }
01929
01930 a2dBoundingBox a2dCanvasXYDisplayGroupAreas::DoGetUnTransformedBbox( a2dBboxFlags flags ) const
01931 {
01932 a2dBoundingBox bbox = GetPlotAreaBbox();
01933
01934 bbox.Expand( m_axisX->GetBbox() );
01935 m_axesarealist->Expand(bbox);
01936
01937
01938
01939 return bbox;
01940 }
01941
01942 bool a2dCanvasXYDisplayGroupAreas::DoUpdate( UpdateMode mode, const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox )
01943 {
01944 bool calc = false;
01945
01946 calc = m_axesarealist->Update( mode );
01947 calc = m_axisX->Update( mode ) || calc;
01948 if(m_cursor)
01949 calc = m_cursor->Update( mode ) || calc;
01950
01951
01952 m_flags.m_HasToolObjectsBelow = m_flags.m_HasToolObjectsBelow
01953 || m_axesarealist->GetHasToolObjectsBelow()
01954 || m_axisX->GetHasToolObjectsBelow();
01955
01956
01957 m_flags.m_HasSelectedObjectsBelow = m_flags.m_HasSelectedObjectsBelow
01958 || m_axesarealist->GetHasSelectedObjectsBelow()
01959 || m_axisX->GetHasSelectedObjectsBelow();
01960
01961
01962 if ( !m_bbox.GetValid() || calc )
01963 {
01964 if ( m_flags.m_isOnCorridorPath || m_flags.m_editingCopy )
01965 {
01966 a2dBoundingBox bbox = GetPlotAreaBbox();
01967 bbox.Enlarge( bbox.GetWidth()/10 );
01968 m_axesarealist->SetClippingFromBox( bbox );
01969 }
01970 else
01971 {
01972 a2dBoundingBox bbox = GetPlotAreaBbox();
01973 m_axesarealist->SetClippingFromBox( bbox );
01974 }
01975
01976
01977 double zerox, zeroy;
01978 double ixmin, ixmax;
01979 m_axesarealist->SetAxes(m_plotrect, 0, m_axisX->GetPosition(), zerox, zeroy, ixmin, ixmax);
01980
01981 if ( zerox < m_plotrect.GetMinX())
01982 zerox = m_plotrect.GetMinX();
01983 else if ( zerox > m_plotrect.GetMaxX() )
01984 zerox = m_plotrect.GetMaxX();
01985
01986 if ( zeroy < m_plotrect.GetMinY() )
01987 zeroy = m_plotrect.GetMinY();
01988 else if ( zeroy > m_plotrect.GetMaxY() )
01989 zeroy = m_plotrect.GetMaxY();
01990
01991 if(m_cursor)
01992 {
01993 a2dCurvesArea* baseArea = m_axesarealist->GetBaseCurvesArea();
01994 a2dBoundingBox ibox = baseArea->GetInternalBoundaries();
01995 a2dAffineMatrix mat = baseArea->GetCurveAreaTransform();
01996 m_cursor->SetHSize(m_plotrect.GetHeight());
01997 m_cursor->SetWSize(m_plotrect.GetWidth());
01998
01999 m_cursor->UpdatePosition(m_plotrect.GetMinX(),m_plotrect.GetMinY(), mat);
02000 m_cursor->Update(a2dCanvasObject::updatemask_normal);
02001 }
02002
02003 m_axisX->SetPosXY( m_plotrect.GetMinX(), zeroy );
02004 m_axisX->SetLength( m_plotrect.GetWidth() );
02005 m_axisX->SetBoundaries( ixmin, ixmax );
02006
02007 m_bbox = DoGetUnTransformedBbox();
02008 m_bbox.MapBbox(m_lworld);
02009
02010 return true;
02011 }
02012
02013 return false;
02014 }
02015
02016 void a2dCanvasXYDisplayGroupAreas::DoRender( a2dIterC& ic, OVERLAP clipparent )
02017 {
02018
02019 a2dBoundingBox bbox = DoGetUnTransformedBbox();
02020 ic.GetDrawer2D()->DrawRoundedRectangle( bbox.GetMinX(), bbox.GetMinY(), bbox.GetWidth(), bbox.GetHeight() ,0 );
02021
02022
02023
02024 ic.GetDrawer2D()->SetDrawerFill( m_fillAxisArea );
02025 ic.GetDrawer2D()->SetDrawerStroke( m_strokeAxisArea );
02026 ic.GetDrawer2D()->DrawRoundedRectangle( m_plotrect.GetMinX(), m_plotrect.GetMinY(), m_plotrect.GetWidth(), m_plotrect.GetHeight(), 0 );
02027
02028 if (m_showgrid)
02029 DrawGrid( ic );
02030
02031 if(m_cursor)
02032 m_cursor->Render( ic, clipparent);
02033
02034 if (m_showxaxis)
02035 m_axisX->Render( ic, clipparent );
02036 m_axesarealist->RenderAxesY( ic, clipparent );
02037
02038 m_axesarealist->Render( ic, clipparent );
02039 }
02040
02041 void a2dCanvasXYDisplayGroupAreas::DrawGrid( a2dIterC& ic )
02042 {
02043 double ticx = m_axisX->GetTic();
02044 double ticy = m_axesarealist->GetTicY();
02045
02046 double x;
02047 double y;
02048
02049 double ticstartx;
02050 double ticstarty;
02051
02052 a2dSmrtPtr<a2dCurvesArea> baseArea = m_axesarealist->GetBaseCurvesArea();
02053 a2dBoundingBox intrect = baseArea->GetInternalBoundaries();
02054
02055 ic.GetDrawer2D()->SetDrawerFill( *a2dTRANSPARENT_FILL );
02056 ic.GetDrawer2D()->SetDrawerStroke( m_strokegrid );
02057
02058 a2dAffineMatrix mat = m_axesarealist->GetBaseCurvesArea()->GetCurveAreaTransform();
02059
02060 ticstartx = floor( intrect.GetMinX() / ticx + 0.5) * ticx;
02061 if ( (ticx > 0. && ticstartx <= intrect.GetMinX()) || (ticx < 0. && ticstartx >= intrect.GetMinX()) )
02062 ticstartx += ticx;
02063 ticstarty = floor( intrect.GetMinY() / ticy + 0.5) * ticy;
02064 if ( (ticy > 0. && ticstarty <= intrect.GetMinY()) || (ticy < 0. && ticstarty >= intrect.GetMinY()) )
02065 ticstarty += ticy;
02066
02067
02068 for ( x = ticstartx; (ticx > 0. && x < intrect.GetMaxX()) || (ticx < 0. && x > intrect.GetMaxX()) ; x = x+ticx)
02069 {
02070 double xw, yw;
02071
02072 mat.TransformPoint(x, 0, xw, yw);
02073 ic.GetDrawer2D()->DrawLine( xw, m_plotrect.GetMinY(), xw, m_plotrect.GetMaxY() );
02074 }
02075
02076 for ( y = ticstarty; (ticy > 0. && y < intrect.GetMaxY()) || (ticy < 0. && y > intrect.GetMaxY()) ; y = y+ticy)
02077 {
02078 double xw, yw;
02079
02080 mat.TransformPoint(0, y, xw, yw);
02081 ic.GetDrawer2D()->DrawLine( m_plotrect.GetMinX(), yw, m_plotrect.GetMaxX(), yw );
02082 }
02083 }
02084
02085 bool a2dCanvasXYDisplayGroupAreas::DoIsHitWorld( a2dIterC& WXUNUSED(ic), a2dHitEvent& hitEvent )
02086 {
02087 hitEvent.m_how = a2dHit::stock_fill;
02088 return true;
02089 }
02090
02091 wxString a2dCanvasXYDisplayGroupAreas::GetLeftAxisText() const
02092 {
02093 return m_axesarealist->m_leftAxisY != (a2dCurvesArea*)NULL
02094 ? m_axesarealist->m_leftAxisY->GetAxisText() : wxT("");
02095 }
02096
02097 wxString a2dCanvasXYDisplayGroupAreas::GetRightAxisText() const
02098 {
02099 return m_axesarealist->m_rightAxisY != (a2dCurvesArea*)NULL
02100 ? m_axesarealist->m_rightAxisY->GetAxisText() : wxT("");
02101 }
02102
02103 void a2dCanvasXYDisplayGroupAreas::SetAxisText(const wxString& curveAreaName, const wxString& text, const wxColour& color)
02104 {
02105 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
02106 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curve by name '%s' "), curveAreaName.c_str()));
02107 curvesarea->SetAxisText(text);
02108 curvesarea->SetColor(color);
02109 }
02110
02111 void a2dCanvasXYDisplayGroupAreas::ClearCurvesAreas()
02112 {
02113 m_axesarealist->m_leftAxisY = (a2dCurvesArea*) NULL;
02114 m_axesarealist->m_rightAxisY = (a2dCurvesArea*) NULL;
02115 if(m_cursor)
02116 m_cursor->RemoveMarkers();
02117 m_axesarealist->Empty();
02118 }
02119
02120 void a2dCanvasXYDisplayGroupAreas::SetAreaMarkerShow(const wxString& curveAreaName, a2dMarkerShow* showm)
02121 {
02122 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
02123 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
02124 curvesarea->SetMarkerShow(showm);
02125 SetPending(true);
02126 }
02127
02128 void a2dCanvasXYDisplayGroupAreas::SetAreaMarkerShow2(const wxString& curveAreaName, a2dMarkerShow* showm)
02129 {
02130 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
02131 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
02132 curvesarea->SetMarkerShow2(showm);
02133 SetPending(true);
02134 }
02135
02136 a2dMarkerShow* a2dCanvasXYDisplayGroupAreas::GetAreaMarkerShow(const wxString& curveAreaName) const
02137 {
02138 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
02139 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
02140 return curvesarea->GetMarkerShow();
02141 }
02142
02143 a2dMarkerShow* a2dCanvasXYDisplayGroupAreas::GetAreaMarkerShow2(const wxString& curveAreaName) const
02144 {
02145 a2dCurvesArea* curvesarea = m_axesarealist->GetCurvesArea(curveAreaName);
02146 wxASSERT_MSG(curvesarea != NULL, wxString::Format(wxT("not found curves area by name '%s' "), curveAreaName.c_str()));
02147 return curvesarea->GetMarkerShow2();
02148 }
02149
02150 void a2dCanvasXYDisplayGroupAreas::SetTicY(int numLines)
02151 {
02152 m_axesarealist->SetTicY(numLines);
02153 }
02154
02155 int a2dCanvasXYDisplayGroupAreas::SetAxisTicPrecision(a2dCurveAxis* axisY, double newMinY, double newMaxY)
02156 {
02157 if(m_autoTicYPrecision)
02158 {
02159 double aTic = axisY->GetTic();
02160 double abs_tic = fabs(aTic);
02161 int precision = 1;
02162 double maxVal = wxMax(fabs(newMinY),fabs(newMaxY));
02163 if( maxVal > 999999. )
02164 {
02165 axisY->SetTicFormat(wxT("%.6e"));
02166 precision = 5;
02167 }
02168 else if(abs_tic<=1E-6)
02169 {
02170 axisY->SetTicFormat(wxT("%.6e"));
02171 if(precision != 5)
02172 precision = 4;
02173 }
02174 else if(abs_tic<=1E-4)
02175 {
02176 axisY->SetTicFormat(wxT("%.4e"));
02177 if(precision != 4 && precision != 5)
02178 precision = 3;
02179 }
02180 else if(abs_tic<=0.026)
02181 {
02182 axisY->SetTicFormat(wxT("%.3f"));
02183 if(precision != 1)
02184 precision = 2;
02185 }
02186 else if(abs_tic>=1.)
02187 {
02188 if(int(abs_tic)*10 == int(abs_tic*10.) )
02189 axisY->SetTicFormat(wxT("%.0f"));
02190 else if(int(abs_tic*10)*10 == int(abs_tic*100.))
02191 axisY->SetTicFormat(wxT("%.1f"));
02192 else
02193 axisY->SetTicFormat(wxT("%.2f"));
02194 }
02195 else
02196 axisY->SetTicFormat(wxT("%.2f"));
02197 return precision;
02198 }
02199 return 0;
02200 }
02201
02202 void a2dCanvasXYDisplayGroupAreas::SetCommonTicPrecision(int precision)
02203 {
02204 if(m_autoTicYPrecision)
02205 {
02206 wxString commonTicFormat;
02207 switch(precision)
02208 {
02209 default:
02210 case 1: commonTicFormat = wxT("-99.99"); break;
02211 case 2: commonTicFormat = wxT("-99.999"); break;
02212 case 3: commonTicFormat = wxT("-9.9999E+99"); break;
02213 case 4: case 5: commonTicFormat = wxT("-9.999999E+99"); break;
02214 }
02215 for(size_t i=0; i < m_axesarealist->GetCount(); i++)
02216 {
02217 a2dCurvesArea* area = m_axesarealist->Item(i);
02218 area->GetAxisY()->SetCommonTicFormat(commonTicFormat);
02219 }
02220 }
02221 }
02222
02223 #if wxART2D_USE_CVGIO
02224 void a2dCanvasXYDisplayGroupAreas::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
02225 {
02226 a2dCanvasObject::DoSave( parent, out, xmlparts, towrite );
02227 if ( xmlparts == a2dXmlSer_attrib )
02228 {
02229 out.WriteAttribute( wxT("cursorOnlyByCurves") , m_cursorOnlyByCurves );
02230 out.WriteAttribute( wxT("showgrid") , m_showgrid );
02231 out.WriteAttribute( wxT("showxaxis") , m_showxaxis );
02232 out.WriteAttribute( wxT("autoTicYPrecision") , m_autoTicYPrecision );
02233 out.WriteNewLine();
02234
02235 out.WriteAttribute( _T("xmin") , m_plotrect.GetMinX() );
02236 out.WriteAttribute( wxT("ymin") , m_plotrect.GetMinY() );
02237 out.WriteAttribute( _T("xmax") , m_plotrect.GetMaxX() );
02238 out.WriteAttribute( wxT("ymax") , m_plotrect.GetMaxY() );
02239 out.WriteNewLine();
02240 }
02241 else
02242 {
02243 out.WriteStartElement( wxT("derived") );
02244
02245 m_strokegrid.Save( this, out, towrite );
02246 m_fillAxisArea.Save( this, out, towrite );
02247 m_strokeAxisArea.Save( this, out, towrite );
02248
02249 m_axesarealist->Save( this, out, towrite);
02250
02251 m_axisX->Save( this, out, towrite);
02252
02253
02254 if(m_cursor)
02255 m_cursor->Save( this, out, towrite);
02256
02257 out.WriteEndElement();
02258 }
02259 }
02260
02261 void a2dCanvasXYDisplayGroupAreas::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
02262 {
02263 a2dCanvasObject::DoLoad( parent, parser, xmlparts );
02264 if ( xmlparts == a2dXmlSer_attrib )
02265 {
02266 m_cursorOnlyByCurves = parser.RequireAttributeValueBool( wxT("cursorOnlyByCurves") );
02267 m_showgrid = parser.RequireAttributeValueBool( wxT("showgrid") );
02268 m_showxaxis = parser.RequireAttributeValueBool( wxT("showxaxis") );
02269 m_autoTicYPrecision = parser.RequireAttributeValueBool( wxT("autoTicYPrecision") );
02270
02271 m_plotrect.SetMin( parser.RequireAttributeValueDouble( wxT("xmin") ),
02272 parser.RequireAttributeValueDouble( wxT("ymin") ) );
02273 m_plotrect.SetMax( parser.RequireAttributeValueDouble( wxT("xmax") ),
02274 parser.RequireAttributeValueDouble( wxT("ymax") ) );
02275 }
02276 else
02277 {
02278 parser.Require( START_TAG, wxT("derived") );
02279 parser.Next();
02280
02281
02282 m_strokegrid = m_strokegrid;
02283 m_fillAxisArea = m_fillAxisArea;
02284 m_strokeAxisArea = m_strokeAxisArea;
02285
02286 m_strokegrid.Load( parent, parser );
02287 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_strokegrid );
02288 m_fillAxisArea.Load( parent, parser );
02289 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_fillAxisArea );
02290 m_strokeAxisArea.Load( parent, parser );
02291 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_strokeAxisArea );
02292
02293 m_axesarealist->Load( parent, parser );
02294 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_axesarealist );
02295
02296 m_axisX->Load( parent, parser );
02297 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_axisX );
02298
02299 if ( parser.HasAttribute( wxT("cursor") ) )
02300 {
02301 parser.ResolveOrAdd( (a2dSmrtPtr<class a2dObject>*) &m_cursor, parser.GetAttributeValue( wxT("cursor") ) );
02302 }
02303
02304 parser.Require( END_TAG, wxT("derived") );
02305 parser.Next();
02306 }
02307 }
02308
02309 a2dCanvasXYDisplayGroup::a2dCanvasXYDisplayGroup( double x, double y )
02310 : a2dCanvasXYDisplayGroupAreas(x, y)
02311 {
02312 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
02313
02314 CurrentSmartPointerOwner = this;
02315 #endif
02316 }
02317
02318 a2dCanvasXYDisplayGroup::~a2dCanvasXYDisplayGroup()
02319 {
02320 }
02321
02322 a2dCanvasXYDisplayGroup::a2dCanvasXYDisplayGroup( const a2dCanvasXYDisplayGroup &other, CloneOptions options )
02323 :a2dCanvasXYDisplayGroupAreas( other, options )
02324 {
02325
02326 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
02327
02328 CurrentSmartPointerOwner = this;
02329 #endif
02330 }
02331
02332 a2dObject* a2dCanvasXYDisplayGroup::Clone( CloneOptions options ) const
02333 {
02334 return new a2dCanvasXYDisplayGroup( *this, options );
02335 }
02336
02337
02338 #endif //wxART2D_USE_CVGIO
02339