1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Implements view functionality
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
10 /////////////////////////////////////////////////////////////////////////////
13 // #pragma implementation
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include <wx/colordlg.h>
29 #if !wxUSE_DOC_VIEW_ARCHITECTURE
30 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in wx_setup.h!
36 #include "cspalette.h"
39 #include <wx/ogl/basicp.h>
40 #include <wx/ogl/linesp.h>
42 IMPLEMENT_DYNAMIC_CLASS(csDiagramView
, wxView
)
44 BEGIN_EVENT_TABLE(csDiagramView
, wxView
)
45 EVT_MENU(wxID_CUT
, csDiagramView::OnCut
)
46 EVT_MENU(wxID_COPY
, csDiagramView::OnCopy
)
47 EVT_MENU(wxID_CLEAR
, csDiagramView::OnClear
)
48 EVT_MENU(wxID_PASTE
, csDiagramView::OnPaste
)
49 EVT_MENU(wxID_DUPLICATE
, csDiagramView::OnDuplicate
)
50 EVT_MENU(ID_CS_CHANGE_BACKGROUND_COLOUR
, csDiagramView::OnChangeBackgroundColour
)
51 EVT_MENU(ID_CS_EDIT_PROPERTIES
, csDiagramView::OnEditProperties
)
52 EVT_MENU(ID_CS_SELECT_ALL
, csDiagramView::OnSelectAll
)
53 EVT_TOOL(DIAGRAM_TOOLBAR_LINE_ARROW
, csDiagramView::OnToggleArrowTool
)
54 EVT_COMBOBOX(ID_WINDOW_POINT_SIZE_COMBOBOX
, csDiagramView::OnPointSizeComboSel
)
55 EVT_COMBOBOX(ID_WINDOW_ZOOM_COMBOBOX
, csDiagramView::OnZoomSel
)
56 EVT_TEXT(ID_WINDOW_POINT_SIZE_COMBOBOX
, csDiagramView::OnPointSizeComboText
)
57 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNL
, csDiagramView::OnAlign
)
58 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNR
, csDiagramView::OnAlign
)
59 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNB
, csDiagramView::OnAlign
)
60 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNT
, csDiagramView::OnAlign
)
61 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGN_HORIZ
, csDiagramView::OnAlign
)
62 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGN_VERT
, csDiagramView::OnAlign
)
63 EVT_TOOL(DIAGRAM_TOOLBAR_COPY_SIZE
, csDiagramView::OnAlign
)
64 EVT_TOOL(DIAGRAM_TOOLBAR_NEW_POINT
, csDiagramView::OnNewLinePoint
)
65 EVT_TOOL(DIAGRAM_TOOLBAR_CUT_POINT
, csDiagramView::OnCutLinePoint
)
66 EVT_TOOL(DIAGRAM_TOOLBAR_STRAIGHTEN
, csDiagramView::OnStraightenLines
)
67 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNL
, csDiagramView::OnAlignUpdate
)
68 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNR
, csDiagramView::OnAlignUpdate
)
69 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNB
, csDiagramView::OnAlignUpdate
)
70 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNT
, csDiagramView::OnAlignUpdate
)
71 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGN_HORIZ
, csDiagramView::OnAlignUpdate
)
72 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGN_VERT
, csDiagramView::OnAlignUpdate
)
73 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_COPY_SIZE
, csDiagramView::OnAlignUpdate
)
74 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_NEW_POINT
, csDiagramView::OnNewLinePointUpdate
)
75 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_CUT_POINT
, csDiagramView::OnCutLinePointUpdate
)
76 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_STRAIGHTEN
, csDiagramView::OnStraightenLinesUpdate
)
77 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_LINE_ARROW
, csDiagramView::OnToggleArrowToolUpdate
)
78 EVT_UPDATE_UI(wxID_CUT
, csDiagramView::OnCutUpdate
)
79 EVT_UPDATE_UI(wxID_COPY
, csDiagramView::OnCopyUpdate
)
80 EVT_UPDATE_UI(wxID_CLEAR
, csDiagramView::OnClearUpdate
)
81 EVT_UPDATE_UI(wxID_PASTE
, csDiagramView::OnPasteUpdate
)
82 EVT_UPDATE_UI(wxID_DUPLICATE
, csDiagramView::OnDuplicateUpdate
)
83 EVT_UPDATE_UI(ID_CS_EDIT_PROPERTIES
, csDiagramView::OnEditPropertiesUpdate
)
84 EVT_UPDATE_UI(wxID_UNDO
, csDiagramView::OnUndoUpdate
)
85 EVT_UPDATE_UI(wxID_REDO
, csDiagramView::OnRedoUpdate
)
88 // What to do when a view is created. Creates actual
89 // windows for displaying the view.
90 bool csDiagramView::OnCreate(wxDocument
*doc
, long WXUNUSED(flags
))
93 frame
= wxGetApp().CreateChildFrame(doc
, this, &editMenu
);
94 canvas
= wxGetApp().CreateCanvas(this, frame
);
95 canvas
->SetView(this);
100 // Initialize the edit menu Undo and Redo items
101 doc
->GetCommandProcessor()->SetEditMenu(editMenu
);
102 doc
->GetCommandProcessor()->Initialize();
104 wxShapeCanvas
*shapeCanvas
= (wxShapeCanvas
*)canvas
;
105 csDiagramDocument
*diagramDoc
= (csDiagramDocument
*)doc
;
106 shapeCanvas
->SetDiagram(diagramDoc
->GetDiagram());
107 diagramDoc
->GetDiagram()->SetCanvas(shapeCanvas
);
109 diagramDoc
->GetDiagram()->SetGridSpacing((double) wxGetApp().GetGridSpacing());
111 switch (wxGetApp().GetGridStyle())
113 case csGRID_STYLE_NONE
:
115 diagramDoc
->GetDiagram()->SetSnapToGrid(false);
118 case csGRID_STYLE_INVISIBLE
:
120 diagramDoc
->GetDiagram()->SetSnapToGrid(true);
123 case csGRID_STYLE_DOTTED
:
125 // TODO (not implemented in OGL)
134 csDiagramView::~csDiagramView(void)
138 ((wxDocMDIChildFrame
*)frame
)->SetView(NULL
);
142 // Sneakily gets used for default print/preview
143 // as well as drawing on the screen.
144 void csDiagramView::OnDraw(wxDC
*WXUNUSED(dc
))
148 void csDiagramView::OnUpdate(wxView
*WXUNUSED(sender
), wxObject
*WXUNUSED(hint
))
154 // Clean up windows used for displaying the view.
155 bool csDiagramView::OnClose(bool deleteWindow
)
157 if (!GetDocument()->Close())
160 csDiagramDocument
*diagramDoc
= (csDiagramDocument
*)GetDocument();
161 diagramDoc
->GetDiagram()->SetCanvas(NULL
);
163 canvas
->ClearBackground();
164 canvas
->SetDiagram(NULL
);
165 canvas
->SetView(NULL
);
168 wxMenu
* fileMenu
= frame
->GetMenuBar()->GetMenu(0);
170 // Remove file menu from those managed by the command history
171 wxGetApp().GetDocManager()->FileHistoryRemoveMenu(fileMenu
);
184 // Adds or removes shape from m_selections
185 void csDiagramView::SelectShape(wxShape
* shape
, bool select
)
187 if (select
&& !m_selections
.Member(shape
))
188 m_selections
.Append(shape
);
190 m_selections
.DeleteObject(shape
);
193 void csDiagramView::OnSelectAll(wxCommandEvent
& WXUNUSED(event
))
198 wxShape
*csDiagramView::FindFirstSelectedShape(void)
200 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
201 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
204 wxShape
*eachShape
= (wxShape
*)node
->GetData();
205 if ((eachShape
->GetParent() == NULL
) && !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)) && eachShape
->Selected())
209 else node
= node
->GetNext();
214 void csDiagramView::FindSelectedShapes(wxList
& selections
, wxClassInfo
* toFind
)
216 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
217 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
220 wxShape
*eachShape
= (wxShape
*)node
->GetData();
221 if ((eachShape
->GetParent() == NULL
) && !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)) && eachShape
->Selected() && ((toFind
== NULL
) || (eachShape
->IsKindOf(toFind
))))
223 selections
.Append(eachShape
);
225 node
= node
->GetNext();
229 void csDiagramView::OnUndoUpdate(wxUpdateUIEvent
& event
)
231 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
232 event
.Enable(doc
->GetCommandProcessor()->CanUndo());
235 void csDiagramView::OnRedoUpdate(wxUpdateUIEvent
& event
)
237 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
238 event
.Enable(doc
->GetCommandProcessor()->CanRedo());
241 void csDiagramView::OnCut(wxCommandEvent
& WXUNUSED(event
))
243 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
245 // Copy the shapes to the clipboard
246 wxGetApp().GetDiagramClipboard().Copy(doc
->GetDiagram());
249 FindSelectedShapes(selections
);
254 void csDiagramView::OnClear(wxCommandEvent
& WXUNUSED(event
))
257 FindSelectedShapes(selections
);
262 void csDiagramView::OnCopy(wxCommandEvent
& WXUNUSED(event
))
264 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
266 // Copy the shapes to the clipboard
267 if (wxGetApp().GetDiagramClipboard().Copy(doc
->GetDiagram()))
270 // Copy to the Windows clipboard
271 wxGetApp().GetDiagramClipboard().CopyToClipboard(1.0);
276 void csDiagramView::OnPaste(wxCommandEvent
& WXUNUSED(event
))
278 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
280 wxGetApp().GetDiagramClipboard().Paste(doc
->GetDiagram());
283 void csDiagramView::OnDuplicate(wxCommandEvent
& WXUNUSED(event
))
285 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
287 // Do a copy, then a paste
288 wxGetApp().GetDiagramClipboard().Copy(doc
->GetDiagram());
290 // Apply an offset. Really, this offset should keep being incremented,
291 // but where do we reset it again?
292 wxGetApp().GetDiagramClipboard().Paste(doc
->GetDiagram(), NULL
, 20, 20);
295 void csDiagramView::OnCutUpdate(wxUpdateUIEvent
& event
)
297 event
.Enable( (m_selections
.GetCount() > 0) );
300 void csDiagramView::OnClearUpdate(wxUpdateUIEvent
& event
)
302 event
.Enable( (m_selections
.GetCount() > 0) );
305 void csDiagramView::OnCopyUpdate(wxUpdateUIEvent
& event
)
307 event
.Enable( (m_selections
.GetCount() > 0) );
310 void csDiagramView::OnPasteUpdate(wxUpdateUIEvent
& event
)
312 /* csDiagramDocument *doc = */ (csDiagramDocument
*)GetDocument();
314 int n
= wxGetApp().GetDiagramClipboard().GetCount();
316 event
.Enable( (n
> 0) );
319 void csDiagramView::OnDuplicateUpdate(wxUpdateUIEvent
& event
)
321 event
.Enable( (m_selections
.GetCount() > 0) );
324 void csDiagramView::DoCut(wxList
& shapes
)
326 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
328 if (shapes
.GetCount() > 0)
330 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Cut"), doc
);
332 wxObjectList::compatibility_iterator node
= shapes
.GetFirst();
335 wxShape
*theShape
= (wxShape
*) node
->GetData();
336 csCommandState
* state
= new csCommandState(ID_CS_CUT
, NULL
, theShape
);
338 // Insert lines at the front, so they are cut first.
339 // Otherwise we may try to remove a shape with a line still
341 if (theShape
->IsKindOf(CLASSINFO(wxLineShape
)))
342 cmd
->InsertState(state
);
344 cmd
->AddState(state
);
346 node
= node
->GetNext();
348 cmd
->RemoveLines(); // Schedule any connected lines, not already mentioned,
349 // to be removed first
351 doc
->GetCommandProcessor()->Submit(cmd
);
355 // Generalised command
356 void csDiagramView::DoCmd(wxList
& shapes
, wxList
& oldShapes
, int cmd
, const wxString
& op
)
358 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
360 if (shapes
.GetCount() > 0)
362 csDiagramCommand
* command
= new csDiagramCommand(op
, doc
);
364 wxObjectList::compatibility_iterator node
= shapes
.GetFirst();
365 wxObjectList::compatibility_iterator node1
= oldShapes
.GetFirst();
366 while (node
&& node1
)
368 wxShape
*theShape
= (wxShape
*) node
->GetData();
369 wxShape
*oldShape
= (wxShape
*) node1
->GetData();
370 csCommandState
* state
= new csCommandState(cmd
, theShape
, oldShape
);
371 command
->AddState(state
);
373 node
= node
->GetNext();
374 node1
= node1
->GetNext();
376 doc
->GetCommandProcessor()->Submit(command
);
380 void csDiagramView::OnChangeBackgroundColour(wxCommandEvent
& WXUNUSED(event
))
382 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
385 FindSelectedShapes(selections
);
387 if (selections
.GetCount() > 0)
390 data
.SetChooseFull(true);
391 if (selections
.GetCount() == 1)
393 wxShape
* firstShape
= (wxShape
*) selections
.GetFirst()->GetData();
394 data
.SetColour(firstShape
->GetBrush()->GetColour());
397 wxColourDialog
*dialog
= new wxColourDialog(frame
, &data
);
398 wxBrush
*theBrush
= NULL
;
399 if (dialog
->ShowModal() == wxID_OK
)
401 wxColourData retData
= dialog
->GetColourData();
402 wxColour col
= retData
.GetColour();
403 theBrush
= wxTheBrushList
->FindOrCreateBrush(col
, wxSOLID
);
409 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Change colour"), doc
);
411 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
414 wxShape
*theShape
= (wxShape
*) node
->GetData();
415 wxShape
* newShape
= theShape
->CreateNewCopy();
416 newShape
->SetBrush(theBrush
);
418 csCommandState
* state
= new csCommandState(ID_CS_CHANGE_BACKGROUND_COLOUR
, newShape
, theShape
);
419 cmd
->AddState(state
);
421 node
= node
->GetNext();
423 doc
->GetCommandProcessor()->Submit(cmd
);
427 void csDiagramView::OnEditProperties(wxCommandEvent
& WXUNUSED(event
))
429 wxShape
*theShape
= FindFirstSelectedShape();
431 ((csEvtHandler
*)theShape
->GetEventHandler())->EditProperties();
434 void csDiagramView::OnEditPropertiesUpdate(wxUpdateUIEvent
& event
)
437 FindSelectedShapes(selections
);
438 event
.Enable( (selections
.GetCount() > 0) );
441 void csDiagramView::OnPointSizeComboSel(wxCommandEvent
& event
)
443 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
444 wxASSERT( combo
!= NULL
);
446 int newPointSize
= (combo
->GetSelection() + 1);
448 ApplyPointSize(newPointSize
);
452 // TODO: must find out how to intercept the Return key, rather than
453 // every key stroke. But for now, do every key stroke.
454 void csDiagramView::OnPointSizeComboText(wxCommandEvent
& event
)
456 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
457 wxASSERT( combo
!= NULL
);
459 wxString
str(combo
->GetValue());
461 str
.ToLong( &newPointSize
);
463 if (newPointSize
< 2)
466 ApplyPointSize(newPointSize
);
469 void csDiagramView::ApplyPointSize(int pointSize
)
471 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
474 FindSelectedShapes(selections
);
476 if (selections
.GetCount() > 0)
478 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Point size"), doc
);
480 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
483 wxShape
*theShape
= (wxShape
*) node
->GetData();
484 wxShape
*newShape
= theShape
->CreateNewCopy();
486 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
487 theShape
->GetFont()->GetFamily(),
488 theShape
->GetFont()->GetStyle(),
489 theShape
->GetFont()->GetWeight(),
490 theShape
->GetFont()->GetUnderlined(),
491 theShape
->GetFont()->GetFaceName());
493 newShape
->SetFont(newFont
);
495 csCommandState
* state
= new csCommandState(ID_CS_FONT_CHANGE
, newShape
, theShape
);
497 cmd
->AddState(state
);
499 node
= node
->GetNext();
501 doc
->GetCommandProcessor()->Submit(cmd
);
505 void csDiagramView::OnZoomSel(wxCommandEvent
& event
)
510 int noStrings
= (maxZoom
- minZoom
)/inc
;
512 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
513 wxASSERT( combo
!= NULL
);
515 int scale
= (int) ((noStrings
- combo
->GetSelection() - 1)*inc
+ minZoom
);
517 canvas
->SetScale((double) (scale
/100.0), (double) (scale
/100.0));
521 // Select or deselect all
522 void csDiagramView::SelectAll(bool select
)
524 wxClientDC
dc(canvas
);
525 canvas
->PrepareDC(dc
);
530 FindSelectedShapes(selections
);
532 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
535 wxShape
*theShape
= (wxShape
*) node
->GetData();
536 theShape
->Select(false, &dc
);
537 SelectShape(theShape
, false);
539 node
= node
->GetNext();
544 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
545 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
548 wxShape
*eachShape
= (wxShape
*)node
->GetData();
549 if (eachShape
->GetParent() == NULL
&&
550 !eachShape
->IsKindOf(CLASSINFO(wxControlPoint
)) &&
551 !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)))
553 eachShape
->Select(true, &dc
);
554 SelectShape(eachShape
, true);
556 node
= node
->GetNext();
562 void csDiagramView::OnToggleArrowTool(wxCommandEvent
& WXUNUSED(event
))
564 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
566 bool state
= wxGetApp().GetDiagramToolBar()->GetToolState(DIAGRAM_TOOLBAR_LINE_ARROW
);
569 stateName
= _T("Arrow on");
571 stateName
= _T("Arrow off");
574 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
576 if (selections
.GetCount() > 0)
578 csDiagramCommand
* cmd
= new csDiagramCommand(stateName
, doc
);
580 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
583 wxLineShape
*theShape
= (wxLineShape
*) node
->GetData();
584 wxLineShape
*newShape
= NULL
;
589 if (theShape
->GetArrows().GetCount() == 0)
591 newShape
= (wxLineShape
*) theShape
->CreateNewCopy();
592 newShape
->AddArrow(ARROW_ARROW
, ARROW_POSITION_MIDDLE
, 10.0, 0.0, _T("Normal arrowhead"));
597 if (theShape
->GetArrows().GetCount() > 0)
599 newShape
= (wxLineShape
*) theShape
->CreateNewCopy();
600 newShape
->ClearArrowsAtPosition();
604 // If the new state is the same as the old, don't bother adding it to the command state.
607 csCommandState
* state
= new csCommandState(ID_CS_ARROW_CHANGE
, newShape
, theShape
);
608 cmd
->AddState(state
);
611 node
= node
->GetNext();
613 doc
->GetCommandProcessor()->Submit(cmd
);
617 void csDiagramView::OnToggleArrowToolUpdate(wxUpdateUIEvent
& event
)
620 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
621 event
.Enable( (selections
.GetCount() > 0) );
624 // Make the point size combobox reflect this
625 void csDiagramView::ReflectPointSize(int pointSize
)
627 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
628 comboBox
->SetSelection(pointSize
-1);
631 // Make the arrow toggle button reflect the state of the line
632 void csDiagramView::ReflectArrowState(wxLineShape
* lineShape
)
634 bool haveArrow
= false;
635 wxObjectList::compatibility_iterator node
= lineShape
->GetArrows().GetFirst();
638 wxArrowHead
*arrow
= (wxArrowHead
*)node
->GetData();
639 if (ARROW_POSITION_MIDDLE
== arrow
->GetArrowEnd())
641 node
= node
->GetNext();
644 wxGetApp().GetDiagramToolBar()->ToggleTool(DIAGRAM_TOOLBAR_LINE_ARROW
, haveArrow
);
647 void csDiagramView::OnAlign(wxCommandEvent
& event
)
649 // Make a copy of the selections, keeping only those shapes
650 // that are top-level non-line shapes.
652 wxObjectList::compatibility_iterator node
= GetSelectionList().GetFirst();
655 wxShape
* shape
= (wxShape
*) node
->GetData();
656 if ((shape
->GetParent() == NULL
) && (!shape
->IsKindOf(CLASSINFO(wxLineShape
))))
658 selections
.Append(shape
);
660 node
= node
->GetNext();
663 if (selections
.GetCount() == 0)
666 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
667 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Align"), doc
);
669 node
= selections
.GetFirst();
670 wxShape
* firstShape
= (wxShape
*) node
->GetData();
672 double x
= firstShape
->GetX();
673 double y
= firstShape
->GetY();
674 double width
, height
;
675 firstShape
->GetBoundingBoxMax(&width
, &height
);
677 node
= selections
.GetFirst();
680 wxShape
* shape
= (wxShape
*) node
->GetData();
681 if (shape
!= firstShape
)
683 /* double x1 = */ shape
->GetX();
684 /* double y1 = */ shape
->GetY();
685 double width1
, height1
;
686 shape
->GetBoundingBoxMax(& width1
, & height1
);
688 wxShape
* newShape
= shape
->CreateNewCopy();
690 switch (event
.GetId())
692 case DIAGRAM_TOOLBAR_ALIGNL
:
694 double x2
= (double)(x
- (width
/2.0) + (width1
/2.0));
698 case DIAGRAM_TOOLBAR_ALIGNR
:
700 double x2
= (double)(x
+ (width
/2.0) - (width1
/2.0));
704 case DIAGRAM_TOOLBAR_ALIGNB
:
706 double y2
= (double)(y
+ (height
/2.0) - (height1
/2.0));
710 case DIAGRAM_TOOLBAR_ALIGNT
:
712 double y2
= (double)(y
- (height
/2.0) + (height1
/2.0));
716 case DIAGRAM_TOOLBAR_ALIGN_HORIZ
:
721 case DIAGRAM_TOOLBAR_ALIGN_VERT
:
726 case DIAGRAM_TOOLBAR_COPY_SIZE
:
728 newShape
->SetSize(width
, height
);
732 csCommandState
* state
= new csCommandState(ID_CS_ALIGN
, newShape
, shape
);
733 cmd
->AddState(state
);
735 node
= node
->GetNext();
737 doc
->GetCommandProcessor()->Submit(cmd
);
740 void csDiagramView::OnAlignUpdate(wxUpdateUIEvent
& event
)
742 // This is an approximation, since there may be lines
743 // amongst the selections.
744 event
.Enable( (m_selections
.GetCount() > 1) ) ;
747 void csDiagramView::OnNewLinePoint(wxCommandEvent
& WXUNUSED(event
))
749 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
750 csDiagramCommand
* cmd
= new csDiagramCommand(_T("New line point"), doc
);
752 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
755 wxShape
* shape
= (wxShape
*) node
->GetData();
756 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
758 wxShape
* newShape
= shape
->CreateNewCopy();
759 ((wxLineShape
*)newShape
)->InsertLineControlPoint(NULL
);
760 csCommandState
* state
= new csCommandState(ID_CS_NEW_POINT
, newShape
, shape
);
761 cmd
->AddState(state
);
763 node
= node
->GetNext();
765 doc
->GetCommandProcessor()->Submit(cmd
);
768 void csDiagramView::OnCutLinePoint(wxCommandEvent
& WXUNUSED(event
))
770 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
771 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Cut line point"), doc
);
773 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
776 wxShape
* shape
= (wxShape
*) node
->GetData();
777 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
779 wxShape
* newShape
= shape
->CreateNewCopy();
780 ((wxLineShape
*)newShape
)->DeleteLineControlPoint();
781 csCommandState
* state
= new csCommandState(ID_CS_CUT_POINT
, newShape
, shape
);
782 cmd
->AddState(state
);
784 node
= node
->GetNext();
786 doc
->GetCommandProcessor()->Submit(cmd
);
789 void csDiagramView::OnStraightenLines(wxCommandEvent
& WXUNUSED(event
))
791 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
792 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Straighten lines"), doc
);
794 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
797 wxShape
* shape
= (wxShape
*) node
->GetData();
798 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
800 wxShape
* newShape
= shape
->CreateNewCopy();
801 ((wxLineShape
*)newShape
)->Straighten();
802 csCommandState
* state
= new csCommandState(ID_CS_STRAIGHTEN
, newShape
, shape
);
803 cmd
->AddState(state
);
805 node
= node
->GetNext();
807 doc
->GetCommandProcessor()->Submit(cmd
);
810 void csDiagramView::OnNewLinePointUpdate(wxUpdateUIEvent
& event
)
813 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
814 event
.Enable( (selections
.GetCount() > 0) );
817 void csDiagramView::OnCutLinePointUpdate(wxUpdateUIEvent
& event
)
820 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
821 event
.Enable( (selections
.GetCount() > 0) );
824 void csDiagramView::OnStraightenLinesUpdate(wxUpdateUIEvent
& event
)
827 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
828 event
.Enable( (selections
.GetCount() > 0) );
832 * Window implementations
835 IMPLEMENT_CLASS(csCanvas
, wxShapeCanvas
)
837 BEGIN_EVENT_TABLE(csCanvas
, wxShapeCanvas
)
838 EVT_MOUSE_EVENTS(csCanvas::OnMouseEvent
)
839 EVT_PAINT(csCanvas::OnPaint
)
842 // Define a constructor for my canvas
843 csCanvas::csCanvas(csDiagramView
*v
, wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
,
844 const wxSize
& size
, long style
):
845 wxShapeCanvas(parent
, id
, pos
, size
, style
)
850 csCanvas::~csCanvas(void)
854 void csCanvas::DrawOutline(wxDC
& dc
, double x1
, double y1
, double x2
, double y2
)
856 wxPen
dottedPen(*wxBLACK
, 1, wxDOT
);
857 dc
.SetPen(dottedPen
);
858 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
860 dc
.DrawRectangle((long) x1
, (long) y1
, (long) (x2
- x1
), (long) (y2
- y1
));
863 void csCanvas::OnLeftClick(double x
, double y
, int WXUNUSED(keys
))
865 csEditorToolPalette
*palette
= wxGetApp().GetDiagramPalette();
867 if (palette
->GetSelection() == PALETTE_ARROW
)
869 GetView()->SelectAll(false);
878 if (palette
->GetSelection() == PALETTE_TEXT_TOOL
)
880 // Ask for a label and create a new free-floating text region
881 csLabelEditingDialog
* dialog
= new csLabelEditingDialog(GetParent());
883 dialog
->SetShapeLabel( wxEmptyString
);
884 dialog
->SetTitle(_T("New text box"));
885 if (dialog
->ShowModal() == wxID_CANCEL
)
891 wxString newLabel
= dialog
->GetShapeLabel();
894 wxShape
* shape
= new csTextBoxShape
;
895 shape
->AssignNewIds();
896 shape
->SetEventHandler(new csEvtHandler(shape
, shape
, newLabel
));
898 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
899 wxString
str(comboBox
->GetValue());
901 str
.ToLong( &pointSize
);
903 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
904 shape
->GetFont()->GetFamily(),
905 shape
->GetFont()->GetStyle(),
906 shape
->GetFont()->GetWeight(),
907 shape
->GetFont()->GetUnderlined(),
908 shape
->GetFont()->GetFaceName());
910 shape
->SetFont(newFont
);
915 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Text box"),
916 (csDiagramDocument
*)GetView()->GetDocument(),
917 new csCommandState(ID_CS_ADD_SHAPE
, shape
, NULL
));
918 GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd
);
920 palette
->SetSelection(PALETTE_ARROW
);
925 csSymbol
* symbol
= wxGetApp().GetSymbolDatabase()->FindSymbol(palette
->GetSelection());
928 wxShape
* theShape
= symbol
->GetShape()->CreateNewCopy();
930 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
931 wxString
str(comboBox
->GetValue());
933 str
.ToLong( &pointSize
);
935 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
936 symbol
->GetShape()->GetFont()->GetFamily(),
937 symbol
->GetShape()->GetFont()->GetStyle(),
938 symbol
->GetShape()->GetFont()->GetWeight(),
939 symbol
->GetShape()->GetFont()->GetUnderlined(),
940 symbol
->GetShape()->GetFont()->GetFaceName());
942 theShape
->SetFont(newFont
);
944 theShape
->AssignNewIds();
948 csDiagramCommand
* cmd
= new csDiagramCommand(symbol
->GetName(),
949 (csDiagramDocument
*)GetView()->GetDocument(),
950 new csCommandState(ID_CS_ADD_SHAPE
, theShape
, NULL
));
951 GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd
);
953 palette
->SetSelection(PALETTE_ARROW
);
957 void csCanvas::OnRightClick(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
962 static double sg_initialX
, sg_initialY
;
964 void csCanvas::OnDragLeft(bool WXUNUSED(draw
), double x
, double y
, int WXUNUSED(keys
))
969 dc
.SetLogicalFunction(OGLRBLF
);
970 DrawOutline(dc
, sg_initialX
, sg_initialY
, x
, y
);
973 void csCanvas::OnBeginDragLeft(double x
, double y
, int WXUNUSED(keys
))
981 dc
.SetLogicalFunction(OGLRBLF
);
982 DrawOutline(dc
, sg_initialX
, sg_initialY
, x
, y
);
986 void csCanvas::OnEndDragLeft(double x
, double y
, int WXUNUSED(keys
))
993 // Select all images within the rectangle
994 float min_x
, max_x
, min_y
, max_y
;
995 min_x
= wxMin(x
, sg_initialX
);
996 max_x
= wxMax(x
, sg_initialX
);
997 min_y
= wxMin(y
, sg_initialY
);
998 max_y
= wxMax(y
, sg_initialY
);
1000 wxObjectList::compatibility_iterator node
= GetDiagram()->GetShapeList()->GetFirst();
1003 wxShape
*shape
= (wxShape
*)node
->GetData();
1004 if (shape
->GetParent() == NULL
&& !shape
->IsKindOf(CLASSINFO(wxControlPoint
)))
1006 float image_x
= shape
->GetX();
1007 float image_y
= shape
->GetY();
1008 if (image_x
>= min_x
&& image_x
<= max_x
&&
1009 image_y
>= min_y
&& image_y
<= max_y
)
1011 shape
->Select(true, &dc
);
1012 GetView()->SelectShape(shape
, true);
1015 node
= node
->GetNext();
1019 void csCanvas::OnDragRight(bool WXUNUSED(draw
), double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1023 void csCanvas::OnBeginDragRight(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1027 void csCanvas::OnEndDragRight(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1031 void csCanvas::OnMouseEvent(wxMouseEvent
& event
)
1033 wxShapeCanvas::OnMouseEvent(event
);
1036 void csCanvas::OnPaint(wxPaintEvent
& event
)
1038 // if (GetDiagram())
1039 wxShapeCanvas::OnPaint(event
);