00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "a2dprec.h"
00012
00013 #ifdef __BORLANDC__
00014 #pragma hdrstop
00015 #endif
00016
00017 #ifndef WX_PRECOMP
00018 #include "wx/wx.h"
00019 #endif
00020
00021 #include "wx/canvas/canmod.h"
00022
00023 #include "wx/editor/edit.h"
00024
00025 #include <wx/wfstream.h>
00026 #include <math.h>
00027
00028 IMPLEMENT_CLASS(a2dRecursiveEditTool, a2dObjectEditTool)
00029
00030 const a2dCommandId a2dRecursiveEditTool::COMID_PushTool_RecursiveEdit( wxT("PushTool_RecursiveEdit") );
00031 const a2dCommandId a2dMultiEditTool::COMID_PushTool_MultiEdit( wxT("PushTool_MultiEdit") );
00032
00033
00034 A2D_BEGIN_EVENT_TABLE(a2dRecursiveEditTool,a2dObjectEditTool)
00035 A2D_EVT_COM_EVENT( a2dRecursiveEditTool::OnComEvent )
00036 A2D_EVT_MOUSE_EVENTS(a2dRecursiveEditTool::OnMouseEvent)
00037 A2D_EVT_IDLE( a2dRecursiveEditTool::OnIdle )
00038 A2D_EVT_CHAR( a2dRecursiveEditTool::OnChar )
00039 A2D_EVT_UNDO( a2dRecursiveEditTool::OnUndoEvent )
00040 A2D_EVT_REDO( a2dRecursiveEditTool::OnRedoEvent )
00041 A2D_EVT_KEY_UP( a2dRecursiveEditTool::OnKeyUp)
00042 A2D_END_EVENT_TABLE()
00043
00044 a2dRecursiveEditTool::a2dRecursiveEditTool( a2dStToolContr* controller, a2dIterC& ic, int editmode, bool SingleClickToEnd )
00045 :a2dObjectEditTool(controller, ic, editmode, SingleClickToEnd )
00046 {
00047 m_oneshot = false;
00048 }
00049
00050 a2dRecursiveEditTool::a2dRecursiveEditTool(a2dStToolContr* controller, int editmode, bool SingleClickToEnd )
00051 :a2dObjectEditTool(controller, editmode, SingleClickToEnd )
00052 {
00053 m_oneshot = false;
00054 }
00055
00056 a2dRecursiveEditTool::~a2dRecursiveEditTool()
00057 {
00058 }
00059
00060 void a2dRecursiveEditTool::OnMouseEvent(wxMouseEvent& event)
00061 {
00062 if (!m_active || m_halted )
00063 {
00064 event.Skip();
00065 return;
00066 }
00067
00068 m_x = event.GetX();
00069 m_y = event.GetY();
00070
00071
00072 double xw,yw;
00073 MouseToToolWorld( m_x, m_y, xw, yw );
00074 m_xwprev = xw;
00075 m_ywprev = yw;
00076
00077 if ( event.Dragging() )
00078 {
00079
00080 }
00081 else if ( event.Moving() && !GetBusy() )
00082 {
00083 a2dCanvasObject* hit = GetCanvasView()->IsHitWorld( xw, yw );
00084 if ( hit && hit->GetDraggable() )
00085 GetCanvasView()->SetCursor( m_toolBusyCursor );
00086 else
00087 GetCanvasView()->SetCursor( m_toolcursor );
00088
00089 }
00090
00091 if ( event.LeftDClick() )
00092 {
00093 if ( GetBusy() )
00094 FinishBusyMode();
00095 else
00096 StopTool();
00097 }
00098 else if (event.LeftDown() && !GetBusy() )
00099 {
00100
00101 a2dIterC ic( GetCanvasView() );
00102 a2dIterCU cu( ic, m_corridor.GetInverseTransform() );
00103 a2dHitEvent hitevent = a2dHitEvent( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
00104 m_original = m_parentobject->ChildIsHitWorld( ic, hitevent );
00105
00106 if ( !m_original.Get() )
00107 return;
00108
00109 if ( !EnterBusyMode() )
00110 return;
00111
00112 RedirectToEditObject( event );
00113 }
00114 else if (event.LeftDown() && GetBusy() )
00115 {
00116
00117
00118
00119
00120
00121 if ( RedirectToEditObject( event ) || m_stop || m_halted )
00122 return;
00123
00124
00125
00126 if ( !m_oneshot )
00127 {
00128 a2dCanvasObject* neweditobject = NULL;
00129 a2dIterC ic( GetCanvasView() );
00130 a2dIterCU cu( ic, m_corridor.GetInverseTransform() );
00131 a2dHitEvent hitevent = a2dHitEvent( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
00132 neweditobject = m_parentobject->ChildIsHitWorld( ic, hitevent );
00133
00134 if ( neweditobject == m_original || neweditobject == m_canvasobject)
00135
00136 return;
00137
00138 if ( !neweditobject )
00139 {
00140 if ( m_SingleClickToEnd )
00141 {
00142 FinishBusyMode();
00143
00144 a2dToolList::const_iterator iter = m_controller->GetToolList().begin();
00145 iter++;
00146
00147 if ( iter != m_controller->GetToolList().end() )
00148 {
00149
00150 a2dRecursiveEditTool *c = wxDynamicCast( (*iter).Get(), a2dRecursiveEditTool );
00151 if (c)
00152 StopTool();
00153 }
00154 }
00155
00156
00157 return;
00158 }
00159
00160 if (!neweditobject->GetEditable() )
00161 return;
00162
00163
00164
00165 FinishBusyMode();
00166
00167 m_original = neweditobject;
00168
00169 if ( !EnterBusyMode() )
00170 return;
00171
00172 RedirectToEditObject( event );
00173 }
00174 else
00175 {
00176 a2dCanvasObject* neweditobject = NULL;
00177 a2dIterC ic( GetCanvasView() );
00178 a2dIterCU cu( ic, m_corridor.GetInverseTransform() );
00179 a2dHitEvent hitevent = a2dHitEvent( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
00180 neweditobject = m_parentobject->ChildIsHitWorld( ic, hitevent );
00181
00182 if ( !neweditobject && !m_SingleClickToEnd || neweditobject == m_original || neweditobject == m_canvasobject)
00183
00184 return;
00185
00186 StopTool();
00187 }
00188 }
00189 else if (event.LeftUp() && GetBusy() )
00190 {
00191 if ( !RedirectToEditObject( event ) )
00192 event.Skip();
00193 }
00194 else if ( GetBusy() )
00195 {
00196 if ( !RedirectToEditObject( event ) )
00197 event.Skip();
00198 }
00199 else
00200 {
00201 event.Skip();
00202 }
00203 }
00204
00205
00206 void a2dRecursiveEditTool::OnComEvent( a2dComEvent& event )
00207 {
00208 if (GetBusy())
00209 {
00210 if ( event.GetEventComId() == &a2dStTool::sm_toolBeforePush )
00211 {
00212
00213 if ( GetBusy() && !m_halted )
00214 {
00215 m_halted = true;
00216 CleanupToolObjects();
00217 }
00218 m_pending = true;
00219 }
00220 else if ( event.GetEventComId() == &a2dCanvasView::sm_changedShowObject )
00221 {
00222 a2dCanvasObject* newtop = wxStaticCast( event.GetProperty()->GetRefObject(), a2dCanvasObject );
00223 if ( newtop )
00224 {
00225 AbortBusyMode();
00226 a2dCorridor corridor;
00227 corridor.push_back( newtop );
00228 SetCorridor( corridor );
00229 }
00230 else
00231 StopTool();
00232 }
00233 else
00234 event.Skip();
00235 }
00236
00237 event.Skip();
00238 }
00239
00240
00241
00242
00243
00244
00245
00246 class A2DCANVASDLLEXP a2dCommand_AddObjectToGroup: public a2dCommand
00247 {
00248
00249 public:
00250
00251
00252
00253 static const a2dCommandId Id;
00254
00255 a2dCommand_AddObjectToGroup( a2dMultiEditTool* tool = NULL, a2dCanvasObject* object = NULL );
00256
00257 ~a2dCommand_AddObjectToGroup(void);
00258
00259 bool Do();
00260 bool Undo();
00261
00262 inline a2dCanvasCommandProcessor *GetCanvasCmp() { return wxStaticCast( m_cmp, a2dCanvasCommandProcessor); }
00263
00264 a2dCanvasObject *GetCanvasObject() { return m_canvasobject; }
00265
00266 protected:
00267 a2dCanvasObjectPtr m_canvasobject;
00268 a2dMultiEditTool* m_tool;
00269 };
00270
00271
00272
00273
00274
00275
00276 class A2DCANVASDLLEXP a2dCommand_ReleaseObjectFromGroup: public a2dCommand
00277 {
00278 public:
00279
00280
00281
00282
00283 static const a2dCommandId Id;
00284
00285 a2dCommand_ReleaseObjectFromGroup( a2dMultiEditTool* tool = NULL, a2dCanvasObject* object = NULL );
00286
00287 ~a2dCommand_ReleaseObjectFromGroup(void);
00288
00289 bool Do();
00290 bool Undo();
00291
00292 inline a2dCanvasCommandProcessor *GetCanvasCmp() { return wxStaticCast( m_cmp, a2dCanvasCommandProcessor); }
00293
00294 protected:
00295
00296 a2dCanvasObjectPtr m_canvasobject;
00297 int m_index;
00298 a2dMultiEditTool* m_tool;
00299 };
00300
00301 const a2dCommandId a2dCommand_AddObjectToGroup::Id( wxT("AddObjectToGroup") );
00302 const a2dCommandId a2dCommand_ReleaseObjectFromGroup::Id( wxT("ReleaseObjectFromGroup") );
00303
00304
00305
00306
00307 a2dCommand_AddObjectToGroup::a2dCommand_AddObjectToGroup( a2dMultiEditTool* tool, a2dCanvasObject* object ):
00308 a2dCommand( true, a2dCommand_AddObjectToGroup::Id )
00309 {
00310 m_canvasobject = object;
00311 m_tool = tool;
00312 }
00313
00314 a2dCommand_AddObjectToGroup::~a2dCommand_AddObjectToGroup(void)
00315 {
00316 }
00317
00318 bool a2dCommand_AddObjectToGroup::Do(void)
00319 {
00320 m_tool->AddToGroup( m_canvasobject );
00321 return true;
00322 }
00323
00324 bool a2dCommand_AddObjectToGroup::Undo(void)
00325 {
00326 m_tool->RemoveFromGroup( m_canvasobject, 0 );
00327 return true;
00328 }
00329
00330
00331
00332
00333 a2dCommand_ReleaseObjectFromGroup::a2dCommand_ReleaseObjectFromGroup( a2dMultiEditTool* tool, a2dCanvasObject *object ):
00334 a2dCommand( true, a2dCommand_ReleaseObjectFromGroup::Id )
00335 {
00336 m_canvasobject = object;
00337
00338 m_index = 0;
00339 m_tool = tool;
00340 }
00341
00342 a2dCommand_ReleaseObjectFromGroup::~a2dCommand_ReleaseObjectFromGroup(void)
00343 {
00344 }
00345
00346 bool a2dCommand_ReleaseObjectFromGroup::Do(void)
00347 {
00348 m_tool->RemoveFromGroup( m_canvasobject, m_index );
00349
00350 if ( m_index == -1 )
00351 a2dDocviewGlobals->ReportError( a2dError_canvasObjectRelease );
00352
00353 return true;
00354 }
00355
00356 bool a2dCommand_ReleaseObjectFromGroup::Undo(void)
00357 {
00358 m_tool->AddToGroup( m_canvasobject );
00359 return true;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 class A2DCANVASDLLEXP a2dMultiSelectGroup: public a2dCanvasObject
00372 {
00373 A2D_DECLARE_EVENT_TABLE()
00374
00375 public:
00376
00377
00378 a2dMultiSelectGroup();
00379
00380
00381 ~a2dMultiSelectGroup(){};
00382
00383 a2dMultiSelectGroup( const a2dMultiSelectGroup &other, CloneOptions options );
00384
00385 a2dCanvasObject* CloneShallow();
00386
00387
00388 a2dObject* Clone( CloneOptions options ) const;
00389
00390 virtual a2dCanvasObject* StartEdit( a2dBaseTool* tool, wxUint16 editmode, wxEditStyle editstyle = wxEDITSTYLE_COPY );
00391
00392 protected:
00393
00394 virtual void RenderChildObjects( a2dIterC& ic, RenderChild& whichchilds, a2dAffineMatrix* tworld, OVERLAP clipparent );
00395
00396 void OnCanvasObjectMouseEvent( a2dCanvasObjectMouseEvent& event );
00397
00398 void OnHandleEvent(a2dHandleMouseEvent &event);
00399
00400
00401 private:
00402
00403 a2dMultiSelectGroup( const a2dMultiSelectGroup &other );
00404 };
00405
00406 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dMultiSelectGroup>;
00407
00408
00409 A2D_BEGIN_EVENT_TABLE( a2dMultiSelectGroup, a2dCanvasObject )
00410 A2D_EVT_CANVASOBJECT_MOUSE_EVENT( a2dMultiSelectGroup::OnCanvasObjectMouseEvent )
00411 A2D_EVT_CANVASHANDLE_MOUSE_EVENT( a2dMultiSelectGroup::OnHandleEvent )
00412 A2D_END_EVENT_TABLE()
00413
00414 a2dMultiSelectGroup::a2dMultiSelectGroup():a2dCanvasObject()
00415 {
00416 m_childobjects = new a2dCanvasObjectList();
00417 }
00418
00419 a2dMultiSelectGroup::a2dMultiSelectGroup( const a2dMultiSelectGroup &other, CloneOptions options )
00420 :a2dCanvasObject( other, options )
00421 {
00422 }
00423
00424 a2dObject* a2dMultiSelectGroup::Clone( CloneOptions options ) const
00425 {
00426 return new a2dMultiSelectGroup( *this, options );
00427 }
00428
00429 a2dCanvasObject* a2dMultiSelectGroup::CloneShallow()
00430 {
00431 a2dMultiSelectGroup* newgr = new a2dMultiSelectGroup();
00432 for( a2dCanvasObjectList::iterator iter = m_childobjects->begin(); iter != m_childobjects->end(); ++iter )
00433 {
00434 a2dCanvasObject *obj = *iter;
00435 newgr->Append( obj );
00436 }
00437 return newgr;
00438 }
00439
00440 void a2dMultiSelectGroup::OnHandleEvent(a2dHandleMouseEvent &event)
00441 {
00442 a2dIterC* ic = event.GetIterC();
00443
00444 if ( m_flags.m_editingCopy && m_flags.m_editable )
00445 {
00446 a2dRestrictionEngine *restrictEngine = a2dCanvasGlobals->GetRestrictionEngine();
00447
00448 a2dHandle* draghandle = event.GetCanvasHandle();
00449
00450
00451 double xw,yw;
00452 xw = event.GetX();
00453 yw = event.GetY();
00454
00455
00456
00457 double xwi;
00458 double ywi;
00459 ic->GetInverseTransform().TransformPoint( xw, yw, xwi, ywi );
00460
00461 bool __includeChildren__ = PROPID_IncludeChildren->GetPropertyValue( this );
00462 a2dBoundingBox untrans;
00463 if ( __includeChildren__ )
00464 untrans = GetUnTransformedBbox( a2dCANOBJ_BBOX_CHILDREN | a2dCANOBJ_BBOX_EDIT );
00465 else
00466 untrans = GetUnTransformedBbox( a2dCANOBJ_BBOX_EDIT );
00467
00468 double xmin,ymin,xmax,ymax,w,h;
00469 xmin = untrans.GetMinX();
00470 ymin = untrans.GetMinY();
00471 xmax = untrans.GetMaxX();
00472 ymax = untrans.GetMaxY();
00473 w = untrans.GetWidth();
00474 h = untrans.GetHeight();
00475
00476 a2dAffineMatrix origworld = m_lworld;
00477 double x1,y1,x2,y2;
00478
00479 a2dCanvasObject* original = PROPID_Original->GetPropertyValue( this );
00480
00481 if ( event.GetMouseEvent().LeftDown() )
00482 {
00483 if (restrictEngine )
00484 restrictEngine->SetRestrictPoint( xw, yw );
00485 }
00486 else if (event.GetMouseEvent().LeftUp() )
00487 {
00488 if ( m_lworld != original->GetTransformMatrix() )
00489 {
00490 for( a2dCanvasObjectList::iterator iter = original->GetChildObjectList()->begin(); iter != original->GetChildObjectList()->end(); iter++ )
00491 {
00492 a2dCanvasObject* obj = *iter;
00493 a2dAffineMatrix newtrans = m_lworld;
00494 newtrans *= obj->GetTransformMatrix();
00495 m_root->GetCommandProcessor()->Submit( new a2dCommand_SetCanvasProperty( obj, a2dCanvasObject::PROPID_TransformMatrix, newtrans ) );
00496 }
00497 for( a2dCanvasObjectList::iterator iter2 = GetChildObjectList()->begin(); iter2 != GetChildObjectList()->end(); iter2++ )
00498 {
00499 a2dCanvasObject* obj = *iter2;
00500 if ( obj->GetBin2() )
00501 {
00502 a2dAffineMatrix newtrans = m_lworld;
00503 newtrans *= obj->GetTransformMatrix();
00504 obj->SetTransformMatrix( newtrans );
00505 }
00506 }
00507
00508 SetTransformMatrix();
00509 }
00510 }
00511 else if ( event.GetMouseEvent().Dragging() )
00512 {
00513 if (restrictEngine )
00514 restrictEngine->RestrictPoint( xw, yw );
00515 ic->GetInverseTransform().TransformPoint( xw, yw, xwi, ywi );
00516
00517 if ( draghandle->GetName() == wxT("handle1") )
00518 {
00519
00520 double dx,dy;
00521 dx = xwi-xmin;
00522 dy = ywi-ymin;
00523
00524 double sx;
00525 double sy;
00526 if ( w )
00527 sx = (w-dx/2)/w;
00528 else
00529 sx = 0;
00530 if ( h )
00531 sy = (h-dy/2)/h;
00532 else
00533 sy = 0;
00534
00535 origworld.TransformPoint( xmax,ymax, x2, y2 );
00536
00537
00538 SetTransformMatrix();
00539 Scale(sx,sy);
00540 Transform( origworld );
00541 m_lworld.TransformPoint( xmax, ymax, x1, y1 );
00542 Translate(x2-x1, y2-y1);
00543 }
00544 else if ( draghandle->GetName() == wxT("handle2") )
00545 {
00546
00547 double dx,dy;
00548 dx = xwi-xmin;
00549 dy = ywi-ymax;
00550
00551 double sx;
00552 double sy;
00553 if ( w )
00554 sx = (w-dx/2)/w;
00555 else
00556 sx = 0;
00557 if ( h )
00558 sy = (h+dy/2)/h;
00559 else
00560 sy = 0;
00561
00562 origworld.TransformPoint( xmax, ymin, x2, y2 );
00563
00564
00565 SetTransformMatrix();
00566 Scale(sx,sy);
00567 Transform( origworld );
00568 m_lworld.TransformPoint( xmax, ymin, x1, y1 );
00569 Translate(x2-x1, y2-y1);
00570 }
00571 else if ( draghandle->GetName() == wxT("handle3") )
00572 {
00573
00574 double dx,dy;
00575 dx = xwi-xmax;
00576 dy = ywi-ymax;
00577
00578 double sx;
00579 double sy;
00580 if ( w )
00581 sx = (w+dx/2)/w;
00582 else
00583 sx = 0;
00584 if ( h )
00585 sy = (h+dy/2)/h;
00586 else
00587 sy = 0;
00588
00589 origworld.TransformPoint( xmin, ymin, x2, y2 );
00590
00591
00592 SetTransformMatrix();
00593 Scale(sx,sy);
00594 Transform( origworld );
00595 m_lworld.TransformPoint( xmin, ymin, x1, y1 );
00596 Translate(x2-x1, y2-y1);
00597 }
00598 else if ( draghandle->GetName() == wxT("handle4") )
00599 {
00600
00601 double dx,dy;
00602 dx = xwi-xmax;
00603 dy = ywi-ymin;
00604
00605 double sx;
00606 double sy;
00607 if ( w )
00608 sx = (w+dx/2)/w;
00609 else
00610 sx = 0;
00611 if ( h )
00612 sy = (h-dy/2)/h;
00613 else
00614 sy = 0;
00615
00616 origworld.TransformPoint( xmin, ymax, x2, y2 );
00617
00618
00619 SetTransformMatrix();
00620 Scale(sx,sy);
00621 Transform( origworld );
00622 m_lworld.TransformPoint( xmin, ymax, x1, y1 );
00623 Translate(x2-x1, y2-y1);
00624 }
00625 else if ( draghandle->GetName() == wxT("rotate") )
00626 {
00627 double xr, yr;
00628 m_lworld.TransformPoint( xmin + w/2, ymin + h/2, xr, yr );
00629
00630
00631 double dx,dy;
00632
00633 dx = xw - xr;
00634 dy = yw - yr;
00635 double angn;
00636 if (!dx && !dy)
00637 angn=0;
00638 else
00639 angn= wxRadToDeg(atan2(dy,dx));
00640
00641 m_lworld = m_lworld.Rotate(angn-m_lworld.GetRotation(), xr, yr );
00642
00643
00644
00645
00646
00647 }
00648 else if ( draghandle->GetName() == wxT("skewx") )
00649 {
00650
00651 double dx,dy;
00652
00653 dx = xwi-(xmin + w*3/4);
00654 dy = ywi-(ymin + h/2);
00655
00656 origworld.TransformPoint( xmin + w/2, ymin + h/2, x2, y2 );
00657
00658
00659 SetTransformMatrix();
00660 SkewX( wxRadToDeg(atan2(dx,dy)) );
00661 Transform( origworld );
00662 m_lworld.TransformPoint( xmin + w/2, ymin + h/2, x1, y1 );
00663 Translate(x2-x1, y2-y1);
00664 }
00665 else if ( draghandle->GetName() == wxT("skewy") )
00666 {
00667
00668 double dx,dy;
00669
00670 dx = xwi-(xmin + w/2);
00671 dy = ywi-(ymin + h*3/4);
00672
00673 origworld.TransformPoint( xmin + w/2, ymin + h/2, x2, y2 );
00674
00675
00676 SetTransformMatrix();
00677 SkewY( wxRadToDeg(atan2(dy,dx)) );
00678 Transform( origworld );
00679 m_lworld.TransformPoint( xmin + w/2, ymin + h/2, x1, y1 );
00680 Translate(x2-x1, y2-y1);
00681 }
00682 else if ( draghandle->GetName() == wxT("handle12") )
00683 {
00684
00685 double dx;
00686
00687 dx = xwi-xmin;
00688
00689 double sx;
00690 if ( w )
00691 sx = (w-dx/2)/w;
00692 else
00693 sx = 0;
00694
00695 origworld.TransformPoint( xmax, ymax, x2, y2 );
00696
00697
00698 SetTransformMatrix();
00699 Scale( sx, 1 );
00700 Transform( origworld );
00701 m_lworld.TransformPoint( xmax, ymax, x1, y1 );
00702 Translate(x2-x1, y2-y1);
00703 }
00704 else if ( draghandle->GetName() == wxT("handle23") )
00705 {
00706
00707 double dy;
00708
00709 dy = ywi-ymax;
00710
00711 double sy;
00712 if ( h )
00713 sy = (h+dy/2)/h;
00714 else
00715 sy = 0;
00716
00717 origworld.TransformPoint( xmax, ymin, x2, y2 );
00718
00719
00720 SetTransformMatrix();
00721 Scale( 1, sy );
00722 Transform( origworld );
00723 m_lworld.TransformPoint( xmax, ymin, x1, y1 );
00724 Translate(x2-x1, y2-y1);
00725 }
00726 else if ( draghandle->GetName() == wxT("handle34") )
00727 {
00728
00729 double dx;
00730
00731 dx = xwi-xmax;
00732
00733 double sx;
00734 if ( w )
00735 sx = (w+dx/2)/w;
00736 else
00737 sx = 0;
00738
00739 origworld.TransformPoint( xmin, ymin, x2, y2 );
00740
00741
00742 SetTransformMatrix();
00743 Scale( sx, 1 );
00744 Transform( origworld );
00745 m_lworld.TransformPoint( xmin, ymin, x1, y1 );
00746 Translate(x2-x1, y2-y1);
00747 }
00748 else if ( draghandle->GetName() == wxT("handle41") )
00749 {
00750
00751 double dy;
00752
00753 dy = ywi - ymin;
00754
00755 double sy;
00756 if ( h )
00757 sy = (h-dy/2)/h;
00758 else
00759 sy = 0;
00760
00761 origworld.TransformPoint( xmin, ymax, x2, y2 );
00762
00763
00764 SetTransformMatrix();
00765 Scale( 1, sy );
00766 Transform( origworld );
00767 m_lworld.TransformPoint( xmin, ymax, x1, y1 );
00768 Translate(x2-x1, y2-y1);
00769 }
00770 else
00771 event.Skip();
00772 SetPending( true );
00773 }
00774 }
00775 }
00776
00777 void a2dMultiSelectGroup::OnCanvasObjectMouseEvent( a2dCanvasObjectMouseEvent& event )
00778 {
00779 a2dIterC* ic = event.GetIterC();
00780 ic->SetPerLayerMode( false );
00781
00782 if ( event.GetMouseEvent().RightDown() )
00783 {
00784
00785
00786
00787 a2dCanvasObjectMouseEvent popup( ic, this, wxEVT_CANVASOBJECT_POPUPMENU_EVENT, event.GetX(), event.GetY(), event.m_mouseevent );
00788 popup.SetEventObject( this );
00789
00790 if ( !this->ProcessEvent( popup ) )
00791 event.Skip();
00792 }
00793
00794
00795 else if ( m_flags.m_editingCopy && m_flags.m_editable )
00796 {
00797 a2dRestrictionEngine *restrictEngine = a2dCanvasGlobals->GetRestrictionEngine();
00798 a2dCanvasObject* original = PROPID_Original->GetPropertyValue( this );
00799 a2dCanvasObject* parent = PROPID_Parent->GetPropertyValue( this );
00800
00801 static double xshift;
00802 static double yshift;
00803
00804 double xw,yw;
00805 xw = event.GetX();
00806 yw = event.GetY();
00807
00808 double xh,yh;
00809 ic->GetInverseTransform().TransformPoint(xw, yw, xh, yh);
00810
00811 if ( event.GetMouseEvent().Moving() )
00812 {
00813 ic->GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
00814 }
00815 else if ( event.GetMouseEvent().LeftDClick() )
00816 {
00817
00818
00819 EndEdit();
00820 }
00821 else if (event.GetMouseEvent().LeftDown() )
00822 {
00823
00824
00825
00826 a2dHitEvent hitevent = a2dHitEvent( xw, yw, false );
00827 if ( IsHitWorld( *ic, hitevent ) )
00828 {
00829 if (restrictEngine )
00830 restrictEngine->SetRestrictPoint( xw, yw );
00831
00832 if ( 1 )
00833 {
00834 a2dCanvasObject* hit = NULL;
00835 if ( hit && hit->GetEditable())
00836 {
00837 a2dIterCU cu( *ic, original );
00838 a2dToolContr* controller = wxStaticCast( PROPID_Controller->GetPropertyValue( this ).Get(), a2dToolContr );
00839
00840
00841
00842
00843 ic->SetCorridorPath( true, NULL );
00844 controller->StartEditingObject( hit, *ic );
00845 }
00846
00847
00848 else if ( IsDraggable() )
00849 {
00850
00851
00852 ic->SetCorridorPathCaptureObject( this );
00853 xshift = GetPosX()-xh;
00854 yshift = GetPosY()-yh;
00855 }
00856 }
00857 }
00858
00859
00860 else
00861 {
00862 EndEdit();
00863 }
00864 }
00865 else if (event.GetMouseEvent().LeftUp() && ic->GetCanvasView()->GetCaptured() )
00866 {
00867
00868 ic->SetCorridorPathCaptureObject( NULL );
00869 ic->GetCanvasView()->GetCanvas()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
00870
00871 if ( original->GetTransformMatrix() != m_lworld )
00872 {
00873 for( a2dCanvasObjectList::iterator iter = original->GetChildObjectList()->begin(); iter != original->GetChildObjectList()->end(); iter++ )
00874 {
00875 a2dCanvasObject* obj = *iter;
00876 a2dAffineMatrix newtrans = m_lworld;
00877 newtrans *= obj->GetTransformMatrix();
00878 m_root->GetCommandProcessor()->Submit( new a2dCommand_SetCanvasProperty( obj, a2dCanvasObject::PROPID_TransformMatrix, newtrans ) );
00879 }
00880 for( a2dCanvasObjectList::iterator iter2 = GetChildObjectList()->begin(); iter2 != GetChildObjectList()->end(); iter2++ )
00881 {
00882 a2dCanvasObject* obj = *iter2;
00883 if ( obj->GetBin2() )
00884 {
00885 a2dAffineMatrix newtrans = m_lworld;
00886 newtrans *= obj->GetTransformMatrix();
00887 obj->SetTransformMatrix( newtrans );
00888 }
00889 }
00890
00891 SetTransformMatrix();
00892 }
00893 }
00894 else if ( IsDraggable() && event.GetMouseEvent().Dragging() && ic->GetCanvasView()->GetCaptured() )
00895 {
00896 double x,y;
00897 x = xh + xshift;
00898 y = yh + yshift;
00899
00900 if(restrictEngine)
00901 {
00902
00903 SetPosXY( x, y );
00904
00905 a2dPoint2D point;
00906 double dx, dy;
00907 if ( restrictEngine->RestrictCanvasObjectAtVertexes( this, point, dx, dy ) )
00908 {
00909
00910 x += dx;
00911 y += dy;
00912 }
00913 }
00914 SetPosXY( x, y );
00915 }
00916 else
00917 event.Skip();
00918 }
00919 else
00920 event.Skip();
00921
00922 }
00923 void a2dMultiSelectGroup::RenderChildObjects( a2dIterC& ic, RenderChild& whichchilds, a2dAffineMatrix* WXUNUSED(tworld), OVERLAP clipparent )
00924 {
00925
00926 ic.GetDrawer2D()->SetDrawStyle( a2dWIREFRAME_ZERO_WIDTH );
00927 a2dCanvasObject::RenderChildObjects( ic, whichchilds, clipparent );
00928
00929 }
00930
00931 a2dCanvasObject* a2dMultiSelectGroup::StartEdit( a2dBaseTool* tool, wxUint16 editmode, wxEditStyle editstyle )
00932 {
00933 if ( m_flags.m_editable )
00934 {
00935 a2dCanvasObjectPtr editcopy;
00936
00937 if( editstyle & wxEDITSTYLE_CONNECTED )
00938 editcopy = TClone( clone_flat | clone_seteditcopy | clone_setoriginal | clone_reconnectable );
00939 else
00940 editcopy = TClone( clone_flat | clone_seteditcopy | clone_setoriginal );
00941
00942 editcopy->DoConnect( false );
00943 SetSnapTo( false );
00944 editcopy->SetSnapTo( false );
00945 SetSelected( false );
00946 editcopy->SetSelected( false );
00947
00948 if ( ! PROPID_Allowrotation->GetPropertyValue( this ) )
00949 PROPID_Allowrotation->SetPropertyToObject( editcopy, true );
00950 if ( ! PROPID_Allowsizing->GetPropertyValue( this ) )
00951 PROPID_Allowsizing->SetPropertyToObject( editcopy, true );
00952 if ( ! PROPID_Allowskew->GetPropertyValue( this ) )
00953 PROPID_Allowskew->SetPropertyToObject( editcopy, true );
00954 PROPID_Parent->SetPropertyToObject( editcopy, tool->GetParentObject() );
00955 editcopy->SetEditingRender( true );
00956
00957 editcopy->Update( updatemask_force );
00958
00959 m_flags.m_editing = true;
00960
00961 PROPID_Editmode->SetPropertyToObject( editcopy, editmode );
00962 PROPID_Editstyle->SetPropertyToObject( editcopy, (wxUint16) editstyle );
00963
00964
00965 PROPID_IncludeChildren->SetPropertyToObject( editcopy, true );
00966 PROPID_Controller->SetPropertyToObject( editcopy, tool->GetToolController() );
00967 PROPID_ViewSpecific->SetPropertyToObject( editcopy, tool->GetCanvasView() );
00968
00969 PROPID_FirstEventInObject->SetPropertyToObject( editcopy, true );
00970
00971 if ( !editcopy->DoStartEdit( editmode, editstyle ) )
00972 {
00973 EndEdit();
00974 return NULL;
00975 }
00976
00977
00978 tool->AddEditobject( editcopy );
00979
00980 return editcopy;
00981 }
00982
00983 return NULL;
00984 }
00985
00986 IMPLEMENT_CLASS(a2dMultiEditTool, a2dObjectEditTool)
00987
00988 A2D_BEGIN_EVENT_TABLE(a2dMultiEditTool,a2dObjectEditTool)
00989 A2D_EVT_COM_EVENT( a2dMultiEditTool::OnComEvent )
00990 A2D_EVT_MOUSE_EVENTS(a2dMultiEditTool::OnMouseEvent)
00991 A2D_EVT_IDLE( a2dMultiEditTool::OnIdle )
00992 A2D_EVT_CHAR( a2dMultiEditTool::OnChar )
00993 A2D_EVT_UNDO( a2dMultiEditTool::OnUndoEvent )
00994 A2D_EVT_REDO( a2dMultiEditTool::OnRedoEvent )
00995 A2D_END_EVENT_TABLE()
00996
00997 a2dMultiEditTool::a2dMultiEditTool(a2dStToolContr* controller ):a2dObjectEditTool(controller)
00998 {
00999 a2dDocviewGlobals->GetEventDistributer()->Register( this );
01000 GetCanvasView()->SetMouseEvents(false);
01001 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
01002 m_oneshot = false;
01003 }
01004
01005 a2dMultiEditTool::~a2dMultiEditTool()
01006 {
01007 a2dDocviewGlobals->GetEventDistributer()->Unregister( this );
01008
01009 if ( GetCanvasView() )
01010 GetCanvasView()->SetMouseEvents(true);
01011 }
01012
01013 void a2dMultiEditTool::DoStopTool( bool abort )
01014 {
01015 a2dCanvasObjectPtr keepit = m_canvasobject;
01016
01017
01018
01019
01020 a2dBaseTool::DoStopTool( abort );
01021
01022 if ( GetCanvasView() )
01023 GetCanvasView()->GetCanvasDocument()->AddPendingUpdatesOldNew();
01024
01025 m_parentobject->SetSpecificFlags( false, a2dCanvasOFlags::HighLight );
01026
01027
01028
01029 }
01030
01031 bool a2dMultiEditTool::AddToGroup( a2dCanvasObject* canvasobject )
01032 {
01033 a2dAffineMatrix inverse = m_canvasobject->GetTransformMatrix();
01034 inverse.Invert();
01035 canvasobject->Transform( inverse );
01036 m_original->Append( canvasobject );
01037 m_canvasobject->Append( canvasobject );
01038 m_canvasobject->Update( a2dCanvasObject::updatemask_force );
01039 m_canvasobject->ReStartEdit( 0 );
01040 return true;
01041 }
01042
01043 bool a2dMultiEditTool::RemoveFromGroup( a2dCanvasObject* canvasobject, int index )
01044 {
01045 m_canvasobject->ReleaseChild( canvasobject, false, false, true );
01046 m_original->ReleaseChild( canvasobject, false, false, true );
01047 m_canvasobject->Update( a2dCanvasObject::updatemask_force );
01048 m_original->Update( a2dCanvasObject::updatemask_force );
01049 m_canvasobject->ReStartEdit( 0 );
01050 return true;
01051 }
01052
01053 void a2dMultiEditTool::OnMouseEvent(wxMouseEvent& event)
01054 {
01055 if (!m_active)
01056 {
01057 event.Skip();
01058 return;
01059 }
01060
01061 m_x = event.GetX();
01062 m_y = event.GetY();
01063
01064
01065 double xw = GetDrawer2D()->DeviceToWorldX( m_x );
01066 double yw = GetDrawer2D()->DeviceToWorldY( m_y );
01067 m_xwprev = xw;
01068 m_ywprev = yw;
01069
01070 if ( event.Moving() && !GetBusy() )
01071 {
01072 if ( GetCanvasView()->IsHitWorld( xw, yw ) )
01073 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
01074 else
01075 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
01076
01077 }
01078
01079 if (event.LeftDown() && !GetBusy() )
01080 {
01081 a2dCanvasObject* hitobject = GetCanvasView()->IsHitWorld( xw,yw );
01082
01083 if ( !hitobject )
01084 return;
01085
01086 a2dAffineMatrix inverse = hitobject->GetTransformMatrix();
01087 m_original = new a2dMultiSelectGroup();
01088 m_original->Append( hitobject );
01089 m_original->SetVisible( false );
01090
01091 if ( !EditStart() )
01092 return;
01093
01094 RedirectToEditObject( event );
01095
01096 }
01097 else if (event.LeftDown() && GetBusy() )
01098 {
01099 a2dCanvasObject* hitobject = NULL;
01100 hitobject = GetCanvasView()->IsHitWorld( xw,yw );
01101
01102 if ( hitobject == m_canvasobject || hitobject == m_original )
01103 {
01104
01105 a2dAffineMatrix selectworld = m_original->GetTransformMatrix();
01106 a2dIterC ic( GetCanvasView() );
01107 a2dIterCU cu( ic, selectworld );
01108 a2dHitEvent hitevent = a2dHitEvent( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
01109 hitobject = m_canvasobject->ChildIsHitWorld( ic, hitevent );
01110 if ( hitobject )
01111 {
01112 if ( !event.m_shiftDown )
01113 {
01114 RedirectToEditObject( event );
01115 }
01116 else
01117 {
01118 if ( m_original->Find( hitobject ) )
01119 {
01120 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
01121 doc->GetCommandProcessor()->Submit( new a2dCommand_ReleaseObjectFromGroup( this, hitobject ) );
01122 }
01123 }
01124 return;
01125 }
01126 }
01127
01128 {
01129
01130 if ( !m_oneshot )
01131 {
01132 hitobject = GetCanvasView()->IsHitWorld( xw,yw );
01133
01134 if ( !hitobject )
01135 {
01136 RedirectToEditObject( event );
01137 return;
01138 }
01139
01140 if (!hitobject->GetEditable() || hitobject == m_canvasobject )
01141 {
01142 return;
01143 }
01144
01145 if ( event.m_shiftDown )
01146 {
01147 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
01148 doc->GetCommandProcessor()->Submit( new a2dCommand_AddObjectToGroup( this, hitobject ) );
01149 }
01150 else
01151 {
01152 }
01153 }
01154 else
01155 {
01156 FinishBusyMode();
01157
01158 }
01159 }
01160 }
01161 else if ( event.LeftDClick() && GetBusy() )
01162 {
01163 if ( GetBusy() )
01164 FinishBusyMode();
01165 else
01166 StopTool();
01167 }
01168 else if ( GetBusy() )
01169 {
01170 if ( event.RightDown() )
01171 event.Skip();
01172 else
01173 RedirectToEditObject( event );
01174 }
01175 else
01176 {
01177 event.Skip();
01178 }
01179 }
01180
01181 bool a2dMultiEditTool::RedirectToEditObject( wxMouseEvent& event )
01182 {
01183 if ( !m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01184 return false;
01185
01186 bool isHit;
01187 bool processed = false;
01188
01189 int margin = a2dCanvasGlobals->GetHitMarginDevice();
01190
01191 a2dAffineMatrix cWorld;
01192
01193 processed = GetCanvasView()->ProcessCanvasObjectEvent( event, isHit, m_xwprev, m_ywprev, margin );
01194
01195 wxPoint pos = m_stcontroller->GetMousePosition();
01196 GetCanvasView()->UpdateCrossHair( pos.x, pos.y );
01197
01198
01199 if ( m_original && !m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01200 {
01201 if ( m_halted )
01202 CleanupToolObjects();
01203 else
01204 FinishBusyMode();
01205 }
01206
01207 return processed;
01208 }
01209
01210 bool a2dMultiEditTool::StartEditing( a2dCanvasObject* startobject )
01211 {
01212 m_original = new a2dMultiSelectGroup();
01213 m_original->Append( startobject );
01214 m_original->SetVisible( false );
01215 EditStart();
01216 return true;
01217 }
01218
01219 bool a2dMultiEditTool::StartEditingSelected()
01220 {
01221 a2dCanvasObjectList* objects = m_parentobject->GetChildObjectList();
01222 a2dCanvasObjectList* objs = objects->Clone( a2dCanvasOFlags::SELECTED, a2dObject::clone_flat );
01223
01224 m_original = new a2dMultiSelectGroup();
01225 m_original->SetVisible( false );
01226 forEachIn( a2dCanvasObjectList, objs )
01227 {
01228 a2dCanvasObject *obj = *iter;
01229 m_original->Append( obj );
01230 }
01231 delete objs;
01232 EditStart();
01233 return true;
01234 }
01235
01236 bool a2dMultiEditTool::EditStart()
01237 {
01238
01239 m_parentobject->Append( m_original );
01240
01241
01242 m_original->Update( a2dCanvasObject::updatemask_force );
01243
01244
01245
01246
01247 EnterBusyMode();
01248
01249 return true;
01250 }
01251
01252 void a2dMultiEditTool::CleanupToolObjects()
01253 {
01254 SetEditObject( NULL );
01255
01256 if ( GetBusy() )
01257 {
01258 if ( m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01259 m_canvasobject->EndEdit();
01260
01261 if ( GetCanvasView() )
01262 GetCanvasView()->SetCursor(*wxSTANDARD_CURSOR);
01263
01264 m_original->SetSelected( m_preserve_select );
01265 a2dCanvasObjectList* objects = m_original->GetChildObjectList();
01266
01267 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
01268 doc->GetCommandProcessor()->GetCurrentGroup()->ClearCommandsById( a2dCommand_AddObjectToGroup::Id );
01269 doc->GetCommandProcessor()->GetCurrentGroup()->ClearCommandsById( a2dCommand_ReleaseObjectFromGroup::Id );
01270
01271 m_parentobject->ReleaseChild( m_original, false, false, true );
01272
01273 m_original->AdjustPinLocation();
01274 m_connectedwirecopies.UpdateImmediate( true, this );
01275
01276 if ( !m_halted )
01277 CloseCommandGroup();
01278
01279 if (m_disableOtherViews && GetCanvasView() )
01280 {
01281 GetCanvasView()->GetCanvasDocument()->EnableAllViews( true, GetCanvasView() );
01282 }
01283 }
01284 a2dStTool::CleanupToolObjects();
01285
01286 m_connectedwirecopies.clear();
01287 m_original = 0;
01288 m_canvasobject = 0;
01289 }
01290
01291 void a2dMultiEditTool::OnIdle( wxIdleEvent &event )
01292 {
01293 if ( m_original )
01294 {
01295 if ( m_pending )
01296 {
01297
01298
01299 }
01300 }
01301 else
01302 a2dStTool::OnIdle( event );
01303 }
01304
01305 void a2dMultiEditTool::OnChar(wxKeyEvent& event)
01306 {
01307 event.Skip();
01308 }
01309
01310 void a2dMultiEditTool::OnComEvent( a2dComEvent& event )
01311 {
01312 event.Skip();
01313 }
01314
01315
01316 void a2dMultiEditTool::SetActive(bool active)
01317 {
01318 if ( active )
01319 {
01320 if ( m_halted )
01321 {
01322 m_halted = false;
01323
01324
01325 CreateToolObjects();
01326 m_active = true;
01327 }
01328 m_pending = true;
01329 a2dBaseTool::SetActive( active );
01330 }
01331 else
01332 {
01333
01334
01335
01336
01337 m_pending = true;
01338 a2dBaseTool::SetActive( active );
01339 }
01340 }
01341
01342 void a2dMultiEditTool::OnUndoEvent( a2dCommandProcessorEvent& WXUNUSED(event) )
01343 {
01344 if (GetBusy() && !m_halted )
01345 {
01346
01347 wxUint16 editmode = a2dCanvasObject::PROPID_Editmode->GetPropertyValue( m_canvasobject );
01348 ReStartEdit( editmode );
01349 }
01350 }
01351
01352 void a2dMultiEditTool::OnRedoEvent( a2dCommandProcessorEvent& event )
01353 {
01354 OnUndoEvent( event );
01355 }
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366 DEFINE_EVENT_TYPE( a2dObjectEditTool::sm_toolStartEditObject )
01367
01368 IMPLEMENT_CLASS(a2dObjectEditTool, a2dStTool)
01369
01370 const a2dCommandId a2dObjectEditTool::COMID_PushTool_ObjectEdit( wxT("PushTool_ObjectEdit") );
01371
01372 A2D_BEGIN_EVENT_TABLE(a2dObjectEditTool,a2dStTool)
01373 A2D_EVT_COM_EVENT( a2dObjectEditTool::OnComEvent )
01374 A2D_EVT_MOUSE_EVENTS(a2dObjectEditTool::OnMouseEvent)
01375 A2D_EVT_IDLE( a2dObjectEditTool::OnIdle )
01376 A2D_EVT_CHAR( a2dObjectEditTool::OnChar )
01377 A2D_EVT_UNDO( a2dObjectEditTool::OnUndoEvent )
01378 A2D_EVT_REDO( a2dObjectEditTool::OnRedoEvent )
01379 A2D_EVT_DO( a2dRecursiveEditTool::OnDoEvent )
01380 A2D_EVT_KEY_UP( a2dObjectEditTool::OnKeyUp)
01381 A2D_EVT_KEY_DOWN( a2dObjectEditTool::OnKeyDown)
01382 A2D_END_EVENT_TABLE()
01383
01384 a2dObjectEditTool::a2dObjectEditTool(a2dStToolContr* controller, a2dIterC& ic, int editmode, bool SingleClickToEnd )
01385 :a2dStTool(controller)
01386 {
01387 m_mode = editmode;
01388
01389 GetCanvasView()->SetMouseEvents(false);
01390 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
01391 m_canvasobject = 0;
01392 m_halted = false;
01393 m_oneshot = true;
01394 m_triggerRestart = false;
01395
01396 m_SingleClickToEnd = SingleClickToEnd;
01397
01398 m_disableOtherViews = false;
01399
01400
01401
01402 SetContext( ic, NULL );
01403 }
01404
01405 a2dObjectEditTool::a2dObjectEditTool(a2dStToolContr* controller, int editmode, bool SingleClickToEnd )
01406 :a2dStTool(controller)
01407 {
01408 m_corridor = a2dCorridor( *GetCanvasView() );
01409 m_parentobject = m_corridor.back();
01410
01411 m_original = NULL;
01412 m_mode = editmode;
01413
01414 GetCanvasView()->SetMouseEvents(false);
01415 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
01416 m_canvasobject = 0;
01417 m_halted = false;
01418 m_oneshot = true;
01419 m_triggerRestart = false;
01420
01421 m_SingleClickToEnd = SingleClickToEnd;
01422
01423 m_disableOtherViews = false;
01424
01425 if ( m_parentobject != GetCanvasView()->GetShowObject() )
01426 m_parentobject->SetSpecificFlags( true, a2dCanvasOFlags::HighLight );
01427 }
01428
01429 bool a2dObjectEditTool::SetContext( a2dIterC& ic, a2dCanvasObject* objectToEdit )
01430 {
01431 m_corridor = a2dCorridor( ic );
01432 m_parentobject = m_corridor.back();
01433
01434 StartToEdit( objectToEdit );
01435
01436
01437 m_corridor = a2dCorridor( ic );
01438
01439 return true;
01440 }
01441
01442 void a2dObjectEditTool::StartToEdit( a2dCanvasObject* objectToEdit )
01443 {
01444 m_original = objectToEdit;
01445
01446 if ( m_parentobject != GetCanvasView()->GetShowObject() )
01447 m_parentobject->SetSpecificFlags( true, a2dCanvasOFlags::HighLight );
01448
01449 bool ret = true;
01450 if ( m_original )
01451 ret = EnterBusyMode();
01452
01453 wxASSERT_MSG( !objectToEdit || (objectToEdit && m_canvasobject), _("wanted object can not be edited") );
01454
01455
01456 }
01457
01458 a2dObjectEditTool::~a2dObjectEditTool()
01459 {
01460 if ( GetCanvasView() )
01461 GetCanvasView()->SetMouseEvents(true);
01462 }
01463
01464 void a2dObjectEditTool::SetEditObject( a2dCanvasObject* objectToEdit )
01465 {
01466 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
01467
01468 if ( doc )
01469 {
01470 a2dComEvent event( this, objectToEdit, &sm_toolComEventSetEditObject );
01471 ProcessEvent( event );
01472 }
01473 }
01474
01475 void a2dObjectEditTool::SetMode( int mode )
01476 {
01477 m_canvasobject->EndEdit();
01478 GetCanvasView()->Update( a2dCANVIEW_UPDATE_OLDNEW );
01479
01480 m_mode = mode;
01481 if (m_mode > 2) m_mode = 0;
01482
01483 CreateToolObjects();
01484 }
01485
01486 void a2dObjectEditTool::DoStopTool( bool abort )
01487 {
01488 a2dCanvasObjectPtr keepit = m_canvasobject;
01489
01490
01491
01492
01493 a2dBaseTool::DoStopTool( abort );
01494
01495 if ( GetCanvasView() )
01496 GetCanvasView()->GetCanvasDocument()->AddPendingUpdatesOldNew();
01497
01498 m_parentobject->SetSpecificFlags( false, a2dCanvasOFlags::HighLight );
01499
01500
01501
01502 }
01503
01504 void a2dObjectEditTool::AdjustRenderOptions()
01505 {
01506 switch( m_stcontroller->GetDragMode() )
01507 {
01508 case wxDRAW_RECTANGLE:
01509 m_renderOriginal = true;
01510 m_renderEditcopy = false;
01511 m_renderEditcopyOnTop = false;
01512 m_renderEditcopyEdit = true;
01513 m_renderEditcopyRectangle = false;
01514 break;
01515
01516 case wxDRAW_ONTOP:
01517 m_renderOriginal = false;
01518 m_renderEditcopy = false;
01519 m_renderEditcopyOnTop = true;
01520 m_renderEditcopyEdit = false;
01521 m_renderEditcopyRectangle = false;
01522 break;
01523
01524 case wxDRAW_REDRAW:
01525 wxASSERT_MSG( 0, _("m_renderEditcopy is not yet implemented, m_renderEditcopyOnTop used instead") );
01526 m_renderOriginal = false;
01527 m_renderEditcopy = false;
01528 m_renderEditcopyOnTop = true;
01529 m_renderEditcopyEdit = false;
01530 m_renderEditcopyRectangle = false;
01531 break;
01532 default:
01533 ;
01534 }
01535 }
01536
01537 bool a2dObjectEditTool::EnterBusyMode()
01538 {
01539 return a2dStTool::EnterBusyMode();
01540 }
01541
01542 void a2dObjectEditTool::FinishBusyMode()
01543 {
01544 if (m_oneshot && !m_halted )
01545 {
01546 m_parentobject->SetSpecificFlags( false, a2dCanvasOFlags::HighLight );
01547 }
01548 a2dStTool::FinishBusyMode();
01549 }
01550
01551 void a2dObjectEditTool::AbortBusyMode()
01552 {
01553 a2dStTool::AbortBusyMode();
01554 }
01555
01556 void a2dObjectEditTool::OnMouseEvent(wxMouseEvent& event)
01557 {
01558 if (!m_active || m_halted )
01559 {
01560 event.Skip();
01561 return;
01562 }
01563
01564 m_x = event.GetX();
01565 m_y = event.GetY();
01566
01567
01568 double xw,yw;
01569 MouseToToolWorld( m_x, m_y, xw, yw );
01570 m_xwprev = xw;
01571 m_ywprev = yw;
01572
01573 if ( event.Dragging() )
01574 {
01575
01576 }
01577
01578 if ( event.LeftDClick() )
01579 {
01580 if ( GetBusy() )
01581 FinishBusyMode();
01582 else
01583 StopTool();
01584 }
01585 else if (event.LeftDown() && GetBusy() )
01586 {
01587
01588
01589 if ( RedirectToEditObject( event ) || m_stop || m_halted )
01590 return;
01591
01592
01593
01594 a2dCanvasObject* neweditobject = NULL;
01595 a2dIterC ic( GetCanvasView() );
01596 a2dIterCU cu( ic, m_corridor.GetInverseTransform() );
01597 a2dHitEvent hitevent = a2dHitEvent( xw, yw, false, a2dCANOBJHITOPTION_LAYERS );
01598 neweditobject = m_parentobject->ChildIsHitWorld( ic, hitevent );
01599
01600 if ( !neweditobject && !m_SingleClickToEnd || neweditobject == m_original || neweditobject == m_canvasobject)
01601
01602 return;
01603
01604 StopTool();
01605 }
01606 else if (event.LeftUp() && GetBusy() )
01607 {
01608 if ( !RedirectToEditObject( event ) )
01609 event.Skip();
01610 }
01611 else if ( GetBusy() )
01612 {
01613 if ( !RedirectToEditObject( event ) )
01614 event.Skip();
01615 }
01616 else
01617 {
01618 event.Skip();
01619 }
01620 }
01621
01622 bool a2dObjectEditTool::RedirectToEditObject( wxMouseEvent& event )
01623 {
01624 if ( !m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01625 return false;
01626
01627 bool isHit;
01628 bool processed = false;
01629
01630 int margin = a2dCanvasGlobals->GetHitMarginDevice();
01631
01632
01633
01634 double xw = GetDrawer2D()->DeviceToWorldX(m_x);
01635 double yw = GetDrawer2D()->DeviceToWorldY(m_y);
01636 processed = GetCanvasView()->ProcessCanvasObjectEvent( event, isHit, xw, yw, margin );
01637
01638 if ( m_canvasobject )
01639 {
01640 m_canvasobject->AdjustPinLocation();
01641 m_connectedwirecopies.UpdateImmediate( false, this, m_canvasobject );
01642 }
01643
01644 wxPoint pos = m_stcontroller->GetMousePosition();
01645 GetCanvasView()->UpdateCrossHair( pos.x, pos.y );
01646
01647
01648
01649
01650
01651 if ( m_original && !m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01652 {
01653 if ( m_halted )
01654 CleanupToolObjects();
01655 else
01656 FinishBusyMode();
01657 }
01658 return processed;
01659 }
01660
01661 bool a2dObjectEditTool::ReStartEdit( wxUint16 editmode )
01662 {
01663 m_canvasobject->Update( a2dCanvasObject::updatemask_force );
01664 m_original->Update( a2dCanvasObject::updatemask_force );
01665 SetEditObject( NULL );
01666
01667 if ( GetBusy() )
01668 {
01669 if ( m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01670 m_canvasobject->EndEdit();
01671
01672 m_original->AdjustPinLocation();
01673 m_connectedwirecopies.UpdateImmediate( true, this );
01674 }
01675 a2dStTool::CleanupToolObjects();
01676
01677 m_connectedwirecopies.clear();
01678 m_canvasobject = 0;
01679
01680 m_mode = editmode;
01681
01682 return CreateToolObjects();
01683 }
01684
01685 bool a2dObjectEditTool::CreateToolObjects()
01686 {
01687 AdjustRenderOptions();
01688 m_original->SetVisible( m_renderOriginal );
01689
01690 m_preserve_select = m_original->GetSelected();
01691
01692 m_canvasobject = m_original->StartEdit( this, m_mode, wxEDITSTYLE_COPY | wxEDITSTYLE_CONNECTED );
01693
01694 if ( !m_canvasobject )
01695 return false;
01696
01697 #ifdef EDITBUF
01698 m_original->SetVisible( false );
01699 GetCanvasView()->Update( a2dCANVIEW_UPDATE_PENDING | a2dCANVIEW_UPDATE_AREAS | a2dCANVIEW_UPDATE_BLIT );
01700 GetCanvasDocument()->SetUpdatesPending( false );
01701 GetCanvasView()->SetDocumentDrawStyle( RenderTOOL_OBJECTS );
01702 GetCanvasDocument()->SetIgnorePendingObjects( true );
01703 #endif
01704
01705 a2dComEvent event( this, m_original, &sm_toolStartEditObject );
01706 ProcessEvent( event );
01707
01708
01709 a2dCanvasObjectList connectedwires;
01710 m_original->CreateWireEditCopies( &connectedwires, &m_connectedwirecopies );
01711 m_canvasobject->RestoreConnectionsAfterCloning();
01712 m_connectedwirecopies.RestoreConnectionsAfterCloning();
01713
01714
01715
01716
01717 if ( m_original->GetVisible() )
01718 m_original->SetVisible( m_renderOriginal );
01719 connectedwires.SetSpecificFlags( m_renderOriginal, a2dCanvasOFlags::VISIBLE );
01720
01721
01722 for( a2dCanvasObjectList::iterator iter = m_connectedwirecopies.begin(); iter != m_connectedwirecopies.end(); ++iter )
01723 {
01724 a2dCanvasObject *obj = *iter;
01725 AddEditobject( obj );
01726 }
01727
01728
01729 GetCanvasView()->SetCursor(m_toolcursor);
01730
01731 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
01732
01733 SetEditObject( m_original );
01734
01735 if (m_disableOtherViews)
01736 GetCanvasView()->GetCanvasDocument()->EnableAllViews( false, GetCanvasView() );
01737
01738 return true;
01739 }
01740
01741 void a2dObjectEditTool::CleanupToolObjects()
01742 {
01743 SetEditObject( NULL );
01744
01745 if ( GetBusy() )
01746 {
01747 if ( m_original->GetFlag( a2dCanvasOFlags::Editing ) )
01748 m_canvasobject->EndEdit();
01749
01750 if ( GetCanvasView() )
01751 GetCanvasView()->SetCursor(*wxSTANDARD_CURSOR);
01752
01753 m_original->SetSelected( m_preserve_select );
01754
01755 m_original->AdjustPinLocation();
01756 m_connectedwirecopies.UpdateImmediate( true, this );
01757
01758 if ( !m_halted )
01759 CloseCommandGroup();
01760
01761 #ifdef EDITBUF
01762 GetCanvasView()->SetDocumentDrawStyle( RenderLAYERED | a2dCanvasGlobals->GetSelectDrawStyle() );
01763 GetCanvasDocument()->SetIgnorePendingObjects( false );
01764 #endif
01765
01766 if (m_disableOtherViews && GetCanvasView() )
01767 {
01768 GetCanvasView()->GetCanvasDocument()->EnableAllViews( true, GetCanvasView() );
01769 }
01770 }
01771 a2dStTool::CleanupToolObjects();
01772
01773 m_connectedwirecopies.clear();
01774 m_canvasobject = 0;
01775 }
01776
01777 void a2dObjectEditTool::Render()
01778 {
01779 if ( m_original && GetBusy())
01780 {
01781
01782
01783 {
01784 if ( m_useEditOpaque == a2dOpaqueMode_Tool )
01785 {
01786 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( m_editOpacityFactor );
01787 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS_STYLED, 0 );
01788 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01789 }
01790 else if ( m_useEditOpaque == a2dOpaqueMode_Tool_FixedStyle )
01791 {
01792 a2dFill fill = *a2dTRANSPARENT_FILL;
01793 a2dStroke stroke = a2dCanvasGlobals->GetHandle()->GetStroke();
01794 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( m_editOpacityFactor );
01795 GetCanvasView()->SetFixedStyleFill( fill );
01796 GetCanvasView()->SetFixedStyleStroke( stroke );
01797 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS, 0 );
01798 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01799 }
01800 else if ( m_useEditOpaque == a2dOpaqueMode_Controller && m_stcontroller->GetUseOpaqueEditcopy() )
01801 {
01802 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( m_stcontroller->GetOpacityFactorEditcopy() );
01803 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS_STYLED, 0 );
01804 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01805 }
01806 else
01807 {
01808 a2dFill fill = *a2dTRANSPARENT_FILL;
01809 a2dStroke stroke = a2dCanvasGlobals->GetHandle()->GetStroke();
01810 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01811 GetCanvasView()->SetFixedStyleFill( fill );
01812 GetCanvasView()->SetFixedStyleStroke( stroke );
01813 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS, 0 );
01814 }
01815 }
01816 }
01817 }
01818
01819 void a2dObjectEditTool::TriggerReStartEdit( wxUint16 editmode )
01820 {
01821 m_triggerRestart = true;
01822 }
01823
01824 void a2dObjectEditTool::OnIdle( wxIdleEvent &event )
01825 {
01826 if ( m_triggerRestart && GetBusy() && !m_halted )
01827 {
01828
01829 wxUint16 editmode = a2dCanvasObject::PROPID_Editmode->GetPropertyValue( m_canvasobject );
01830 ReStartEdit( editmode );
01831 m_triggerRestart = false;
01832 }
01833
01834 #ifdef EDITBUF
01835 if ( m_canvasobject )
01836 if ( m_canvasobject->GetPending() )
01837 GetCanvasView()->AddPendingObject( m_canvasobject );
01838 #endif
01839
01840 if ( m_original )
01841 {
01842 if ( m_pending )
01843 {
01844
01845
01846 }
01847 }
01848 else
01849 a2dStTool::OnIdle( event );
01850 }
01851
01852 void a2dObjectEditTool::OnKeyDown(wxKeyEvent& event)
01853 {
01854
01855 event.Skip();
01856 }
01857
01858 void a2dObjectEditTool::OnKeyUp(wxKeyEvent& event)
01859 {
01860 if (GetBusy() && m_pending )
01861 {
01862 switch(event.GetKeyCode())
01863 {
01864 case WXK_UP:
01865 case WXK_DOWN:
01866 case WXK_LEFT:
01867 case WXK_RIGHT:
01868 {
01869 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
01870 doc->GetCommandProcessor()->Submit(
01871 new a2dCommand_SetCanvasProperty( m_original, a2dCanvasObject::PROPID_TransformMatrix,
01872 m_canvasobject->GetTransformMatrix() ) );
01873
01874 }
01875 break;
01876 default:
01877 {
01878 event.Skip();
01879 }
01880 }
01881 }
01882 else
01883 event.Skip();
01884 }
01885
01886 void a2dObjectEditTool::OnChar(wxKeyEvent& event)
01887 {
01888 if (GetBusy())
01889 {
01890 switch(event.GetKeyCode())
01891 {
01892 case WXK_ESCAPE:
01893 {
01894 StopTool();
01895 }
01896 break;
01897 case WXK_TAB:
01898 {
01899 if ( event.m_shiftDown )
01900 {
01901 int mode = m_mode;
01902 SetMode( ++mode );
01903 }
01904 else if (!m_canvasobject || !m_canvasobject->ProcessEvent(event) )
01905 event.Skip();
01906 }
01907 break;
01908 default:
01909 {
01910 bool processed = false;
01911 if(m_canvasobject)
01912 processed = m_canvasobject->ProcessEvent(event);
01913
01914 if ( !processed && m_canvasobject)
01915 {
01916 if ( m_canvasobject->IsDraggable() )
01917 {
01918 double shiftx;
01919 double shifty;
01920 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
01921
01922
01923
01924 switch(event.GetKeyCode())
01925 {
01926 case WXK_UP:
01927 shiftx = 0;
01928 break;
01929
01930 case WXK_DOWN:
01931 shiftx = 0;
01932 shifty = -shifty;
01933 break;
01934
01935 case WXK_LEFT:
01936 shiftx = -shiftx;
01937 shifty = 0;
01938 break;
01939
01940 case WXK_RIGHT:
01941 shifty = 0;
01942 break;
01943 default:
01944 {
01945 shiftx = 0;
01946 shifty = 0;
01947 event.Skip();
01948 }
01949 }
01950
01951 m_canvasobject->Translate( shiftx, shifty );
01952 event.Skip( false );
01953 m_pending = true;
01954 }
01955 else
01956 event.Skip( false );
01957 }
01958 if(!m_canvasobject)
01959 event.Skip();
01960 }
01961 }
01962
01963 if(m_canvasobject)
01964 {
01965 m_canvasobject->AdjustPinLocation();
01966 m_connectedwirecopies.UpdateImmediate( false, this, m_canvasobject );
01967 }
01968 }
01969 else
01970 event.Skip();
01971 }
01972
01973 void a2dObjectEditTool::OnComEvent( a2dComEvent& event )
01974 {
01975 if ( GetBusy() )
01976 {
01977 if ( event.GetEventComId() == &a2dStTool::sm_toolBeforePush )
01978 {
01979
01980 if ( GetBusy() && !m_halted )
01981 {
01982 m_halted = true;
01983 CleanupToolObjects();
01984 }
01985 m_pending = true;
01986 }
01987 else if ( GetCanvasView() && event.GetEventComId() == &a2dCanvasView::sm_changedShowObject )
01988 {
01989 if ( event.GetEventObject() == GetCanvasView() )
01990 {
01991 StopTool();
01992 }
01993 }
01994 else
01995 event.Skip();
01996 }
01997
01998 event.Skip();
01999 }
02000
02001 void a2dObjectEditTool::SetActive(bool active)
02002 {
02003 if ( active )
02004 {
02005 if ( m_halted )
02006 {
02007 m_halted = false;
02008
02009
02010 CreateToolObjects();
02011 m_active = true;
02012 }
02013 m_pending = true;
02014 a2dBaseTool::SetActive( active );
02015 }
02016 else
02017 {
02018
02019
02020 SetEditObject( NULL );
02021
02022 m_pending = true;
02023 a2dBaseTool::SetActive( active );
02024 }
02025 }
02026
02027 void a2dObjectEditTool::OnUndoEvent( a2dCommandProcessorEvent& WXUNUSED(event) )
02028 {
02029 if (GetBusy() && !m_halted )
02030 {
02031
02032 wxUint16 editmode = a2dCanvasObject::PROPID_Editmode->GetPropertyValue( m_canvasobject );
02033 TriggerReStartEdit( editmode );
02034 }
02035 }
02036
02037 void a2dObjectEditTool::OnRedoEvent( a2dCommandProcessorEvent& event )
02038 {
02039 OnUndoEvent( event );
02040 }
02041
02042 void a2dObjectEditTool::OnDoEvent( a2dCommandProcessorEvent& event )
02043 {
02044 if (GetBusy())
02045 {
02046 }
02047 }
02048
02049
02050
02051
02052
02053