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 int n
= wxGetApp().GetDiagramClipboard().GetCount();
314 event
.Enable( (n
> 0) );
317 void csDiagramView::OnDuplicateUpdate(wxUpdateUIEvent
& event
)
319 event
.Enable( (m_selections
.GetCount() > 0) );
322 void csDiagramView::DoCut(wxList
& shapes
)
324 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
326 if (shapes
.GetCount() > 0)
328 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Cut"), doc
);
330 wxObjectList::compatibility_iterator node
= shapes
.GetFirst();
333 wxShape
*theShape
= (wxShape
*) node
->GetData();
334 csCommandState
* state
= new csCommandState(ID_CS_CUT
, NULL
, theShape
);
336 // Insert lines at the front, so they are cut first.
337 // Otherwise we may try to remove a shape with a line still
339 if (theShape
->IsKindOf(CLASSINFO(wxLineShape
)))
340 cmd
->InsertState(state
);
342 cmd
->AddState(state
);
344 node
= node
->GetNext();
346 cmd
->RemoveLines(); // Schedule any connected lines, not already mentioned,
347 // to be removed first
349 doc
->GetCommandProcessor()->Submit(cmd
);
353 // Generalised command
354 void csDiagramView::DoCmd(wxList
& shapes
, wxList
& oldShapes
, int cmd
, const wxString
& op
)
356 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
358 if (shapes
.GetCount() > 0)
360 csDiagramCommand
* command
= new csDiagramCommand(op
, doc
);
362 wxObjectList::compatibility_iterator node
= shapes
.GetFirst();
363 wxObjectList::compatibility_iterator node1
= oldShapes
.GetFirst();
364 while (node
&& node1
)
366 wxShape
*theShape
= (wxShape
*) node
->GetData();
367 wxShape
*oldShape
= (wxShape
*) node1
->GetData();
368 csCommandState
* state
= new csCommandState(cmd
, theShape
, oldShape
);
369 command
->AddState(state
);
371 node
= node
->GetNext();
372 node1
= node1
->GetNext();
374 doc
->GetCommandProcessor()->Submit(command
);
378 void csDiagramView::OnChangeBackgroundColour(wxCommandEvent
& WXUNUSED(event
))
380 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
383 FindSelectedShapes(selections
);
385 if (selections
.GetCount() > 0)
388 data
.SetChooseFull(true);
389 if (selections
.GetCount() == 1)
391 wxShape
* firstShape
= (wxShape
*) selections
.GetFirst()->GetData();
392 data
.SetColour(firstShape
->GetBrush()->GetColour());
395 wxColourDialog
*dialog
= new wxColourDialog(frame
, &data
);
396 wxBrush
*theBrush
= NULL
;
397 if (dialog
->ShowModal() == wxID_OK
)
399 wxColourData retData
= dialog
->GetColourData();
400 wxColour col
= retData
.GetColour();
401 theBrush
= wxTheBrushList
->FindOrCreateBrush(col
, wxSOLID
);
407 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Change colour"), doc
);
409 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
412 wxShape
*theShape
= (wxShape
*) node
->GetData();
413 wxShape
* newShape
= theShape
->CreateNewCopy();
414 newShape
->SetBrush(theBrush
);
416 csCommandState
* state
= new csCommandState(ID_CS_CHANGE_BACKGROUND_COLOUR
, newShape
, theShape
);
417 cmd
->AddState(state
);
419 node
= node
->GetNext();
421 doc
->GetCommandProcessor()->Submit(cmd
);
425 void csDiagramView::OnEditProperties(wxCommandEvent
& WXUNUSED(event
))
427 wxShape
*theShape
= FindFirstSelectedShape();
429 ((csEvtHandler
*)theShape
->GetEventHandler())->EditProperties();
432 void csDiagramView::OnEditPropertiesUpdate(wxUpdateUIEvent
& event
)
435 FindSelectedShapes(selections
);
436 event
.Enable( (selections
.GetCount() > 0) );
439 void csDiagramView::OnPointSizeComboSel(wxCommandEvent
& event
)
441 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
442 wxASSERT( combo
!= NULL
);
444 int newPointSize
= (combo
->GetSelection() + 1);
446 ApplyPointSize(newPointSize
);
450 // TODO: must find out how to intercept the Return key, rather than
451 // every key stroke. But for now, do every key stroke.
452 void csDiagramView::OnPointSizeComboText(wxCommandEvent
& event
)
454 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
455 wxASSERT( combo
!= NULL
);
457 wxString
str(combo
->GetValue());
459 str
.ToLong( &newPointSize
);
461 if (newPointSize
< 2)
464 ApplyPointSize(newPointSize
);
467 void csDiagramView::ApplyPointSize(int pointSize
)
469 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
472 FindSelectedShapes(selections
);
474 if (selections
.GetCount() > 0)
476 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Point size"), doc
);
478 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
481 wxShape
*theShape
= (wxShape
*) node
->GetData();
482 wxShape
*newShape
= theShape
->CreateNewCopy();
484 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
485 theShape
->GetFont()->GetFamily(),
486 theShape
->GetFont()->GetStyle(),
487 theShape
->GetFont()->GetWeight(),
488 theShape
->GetFont()->GetUnderlined(),
489 theShape
->GetFont()->GetFaceName());
491 newShape
->SetFont(newFont
);
493 csCommandState
* state
= new csCommandState(ID_CS_FONT_CHANGE
, newShape
, theShape
);
495 cmd
->AddState(state
);
497 node
= node
->GetNext();
499 doc
->GetCommandProcessor()->Submit(cmd
);
503 void csDiagramView::OnZoomSel(wxCommandEvent
& event
)
508 int noStrings
= (maxZoom
- minZoom
)/inc
;
510 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
511 wxASSERT( combo
!= NULL
);
513 int scale
= (int) ((noStrings
- combo
->GetSelection() - 1)*inc
+ minZoom
);
515 canvas
->SetScale((double) (scale
/100.0), (double) (scale
/100.0));
519 // Select or deselect all
520 void csDiagramView::SelectAll(bool select
)
522 wxClientDC
dc(canvas
);
523 canvas
->PrepareDC(dc
);
528 FindSelectedShapes(selections
);
530 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
533 wxShape
*theShape
= (wxShape
*) node
->GetData();
534 theShape
->Select(false, &dc
);
535 SelectShape(theShape
, false);
537 node
= node
->GetNext();
542 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
543 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
546 wxShape
*eachShape
= (wxShape
*)node
->GetData();
547 if (eachShape
->GetParent() == NULL
&&
548 !eachShape
->IsKindOf(CLASSINFO(wxControlPoint
)) &&
549 !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)))
551 eachShape
->Select(true, &dc
);
552 SelectShape(eachShape
, true);
554 node
= node
->GetNext();
560 void csDiagramView::OnToggleArrowTool(wxCommandEvent
& WXUNUSED(event
))
562 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
564 bool state
= wxGetApp().GetDiagramToolBar()->GetToolState(DIAGRAM_TOOLBAR_LINE_ARROW
);
567 stateName
= _T("Arrow on");
569 stateName
= _T("Arrow off");
572 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
574 if (selections
.GetCount() > 0)
576 csDiagramCommand
* cmd
= new csDiagramCommand(stateName
, doc
);
578 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
581 wxLineShape
*theShape
= (wxLineShape
*) node
->GetData();
582 wxLineShape
*newShape
= NULL
;
587 if (theShape
->GetArrows().GetCount() == 0)
589 newShape
= (wxLineShape
*) theShape
->CreateNewCopy();
590 newShape
->AddArrow(ARROW_ARROW
, ARROW_POSITION_MIDDLE
, 10.0, 0.0, _T("Normal arrowhead"));
595 if (theShape
->GetArrows().GetCount() > 0)
597 newShape
= (wxLineShape
*) theShape
->CreateNewCopy();
598 newShape
->ClearArrowsAtPosition();
602 // If the new state is the same as the old, don't bother adding it to the command state.
605 csCommandState
* state
= new csCommandState(ID_CS_ARROW_CHANGE
, newShape
, theShape
);
606 cmd
->AddState(state
);
609 node
= node
->GetNext();
611 doc
->GetCommandProcessor()->Submit(cmd
);
615 void csDiagramView::OnToggleArrowToolUpdate(wxUpdateUIEvent
& event
)
618 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
619 event
.Enable( (selections
.GetCount() > 0) );
622 // Make the point size combobox reflect this
623 void csDiagramView::ReflectPointSize(int pointSize
)
625 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
626 comboBox
->SetSelection(pointSize
-1);
629 // Make the arrow toggle button reflect the state of the line
630 void csDiagramView::ReflectArrowState(wxLineShape
* lineShape
)
632 bool haveArrow
= false;
633 wxObjectList::compatibility_iterator node
= lineShape
->GetArrows().GetFirst();
636 wxArrowHead
*arrow
= (wxArrowHead
*)node
->GetData();
637 if (ARROW_POSITION_MIDDLE
== arrow
->GetArrowEnd())
639 node
= node
->GetNext();
642 wxGetApp().GetDiagramToolBar()->ToggleTool(DIAGRAM_TOOLBAR_LINE_ARROW
, haveArrow
);
645 void csDiagramView::OnAlign(wxCommandEvent
& event
)
647 // Make a copy of the selections, keeping only those shapes
648 // that are top-level non-line shapes.
650 wxObjectList::compatibility_iterator node
= GetSelectionList().GetFirst();
653 wxShape
* shape
= (wxShape
*) node
->GetData();
654 if ((shape
->GetParent() == NULL
) && (!shape
->IsKindOf(CLASSINFO(wxLineShape
))))
656 selections
.Append(shape
);
658 node
= node
->GetNext();
661 if (selections
.GetCount() == 0)
664 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
665 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Align"), doc
);
667 node
= selections
.GetFirst();
668 wxShape
* firstShape
= (wxShape
*) node
->GetData();
670 double x
= firstShape
->GetX();
671 double y
= firstShape
->GetY();
672 double width
, height
;
673 firstShape
->GetBoundingBoxMax(&width
, &height
);
675 node
= selections
.GetFirst();
678 wxShape
* shape
= (wxShape
*) node
->GetData();
679 if (shape
!= firstShape
)
681 /* double x1 = */ shape
->GetX();
682 /* double y1 = */ shape
->GetY();
683 double width1
, height1
;
684 shape
->GetBoundingBoxMax(& width1
, & height1
);
686 wxShape
* newShape
= shape
->CreateNewCopy();
688 switch (event
.GetId())
690 case DIAGRAM_TOOLBAR_ALIGNL
:
692 double x2
= (double)(x
- (width
/2.0) + (width1
/2.0));
696 case DIAGRAM_TOOLBAR_ALIGNR
:
698 double x2
= (double)(x
+ (width
/2.0) - (width1
/2.0));
702 case DIAGRAM_TOOLBAR_ALIGNB
:
704 double y2
= (double)(y
+ (height
/2.0) - (height1
/2.0));
708 case DIAGRAM_TOOLBAR_ALIGNT
:
710 double y2
= (double)(y
- (height
/2.0) + (height1
/2.0));
714 case DIAGRAM_TOOLBAR_ALIGN_HORIZ
:
719 case DIAGRAM_TOOLBAR_ALIGN_VERT
:
724 case DIAGRAM_TOOLBAR_COPY_SIZE
:
726 newShape
->SetSize(width
, height
);
730 csCommandState
* state
= new csCommandState(ID_CS_ALIGN
, newShape
, shape
);
731 cmd
->AddState(state
);
733 node
= node
->GetNext();
735 doc
->GetCommandProcessor()->Submit(cmd
);
738 void csDiagramView::OnAlignUpdate(wxUpdateUIEvent
& event
)
740 // This is an approximation, since there may be lines
741 // amongst the selections.
742 event
.Enable( (m_selections
.GetCount() > 1) ) ;
745 void csDiagramView::OnNewLinePoint(wxCommandEvent
& WXUNUSED(event
))
747 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
748 csDiagramCommand
* cmd
= new csDiagramCommand(_T("New line point"), doc
);
750 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
753 wxShape
* shape
= (wxShape
*) node
->GetData();
754 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
756 wxShape
* newShape
= shape
->CreateNewCopy();
757 ((wxLineShape
*)newShape
)->InsertLineControlPoint(NULL
);
758 csCommandState
* state
= new csCommandState(ID_CS_NEW_POINT
, newShape
, shape
);
759 cmd
->AddState(state
);
761 node
= node
->GetNext();
763 doc
->GetCommandProcessor()->Submit(cmd
);
766 void csDiagramView::OnCutLinePoint(wxCommandEvent
& WXUNUSED(event
))
768 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
769 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Cut line point"), doc
);
771 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
774 wxShape
* shape
= (wxShape
*) node
->GetData();
775 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
777 wxShape
* newShape
= shape
->CreateNewCopy();
778 ((wxLineShape
*)newShape
)->DeleteLineControlPoint();
779 csCommandState
* state
= new csCommandState(ID_CS_CUT_POINT
, newShape
, shape
);
780 cmd
->AddState(state
);
782 node
= node
->GetNext();
784 doc
->GetCommandProcessor()->Submit(cmd
);
787 void csDiagramView::OnStraightenLines(wxCommandEvent
& WXUNUSED(event
))
789 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
790 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Straighten lines"), doc
);
792 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
795 wxShape
* shape
= (wxShape
*) node
->GetData();
796 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
798 wxShape
* newShape
= shape
->CreateNewCopy();
799 ((wxLineShape
*)newShape
)->Straighten();
800 csCommandState
* state
= new csCommandState(ID_CS_STRAIGHTEN
, newShape
, shape
);
801 cmd
->AddState(state
);
803 node
= node
->GetNext();
805 doc
->GetCommandProcessor()->Submit(cmd
);
808 void csDiagramView::OnNewLinePointUpdate(wxUpdateUIEvent
& event
)
811 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
812 event
.Enable( (selections
.GetCount() > 0) );
815 void csDiagramView::OnCutLinePointUpdate(wxUpdateUIEvent
& event
)
818 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
819 event
.Enable( (selections
.GetCount() > 0) );
822 void csDiagramView::OnStraightenLinesUpdate(wxUpdateUIEvent
& event
)
825 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
826 event
.Enable( (selections
.GetCount() > 0) );
830 * Window implementations
833 IMPLEMENT_CLASS(csCanvas
, wxShapeCanvas
)
835 BEGIN_EVENT_TABLE(csCanvas
, wxShapeCanvas
)
836 EVT_MOUSE_EVENTS(csCanvas::OnMouseEvent
)
837 EVT_PAINT(csCanvas::OnPaint
)
840 // Define a constructor for my canvas
841 csCanvas::csCanvas(csDiagramView
*v
, wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
,
842 const wxSize
& size
, long style
):
843 wxShapeCanvas(parent
, id
, pos
, size
, style
)
848 csCanvas::~csCanvas(void)
852 void csCanvas::DrawOutline(wxDC
& dc
, double x1
, double y1
, double x2
, double y2
)
854 wxPen
dottedPen(*wxBLACK
, 1, wxDOT
);
855 dc
.SetPen(dottedPen
);
856 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
858 dc
.DrawRectangle((long) x1
, (long) y1
, (long) (x2
- x1
), (long) (y2
- y1
));
861 void csCanvas::OnLeftClick(double x
, double y
, int WXUNUSED(keys
))
863 csEditorToolPalette
*palette
= wxGetApp().GetDiagramPalette();
865 if (palette
->GetSelection() == PALETTE_ARROW
)
867 GetView()->SelectAll(false);
876 if (palette
->GetSelection() == PALETTE_TEXT_TOOL
)
880 #if wxUSE_WX_RESOURCES
881 // Ask for a label and create a new free-floating text region
882 csLabelEditingDialog
* dialog
= new csLabelEditingDialog(GetParent());
884 dialog
->SetShapeLabel( wxEmptyString
);
885 dialog
->SetTitle(_T("New text box"));
886 if (dialog
->ShowModal() == wxID_CANCEL
)
892 newLabel
= dialog
->GetShapeLabel();
894 #endif // wxUSE_WX_RESOURCES
896 wxShape
* shape
= new csTextBoxShape
;
897 shape
->AssignNewIds();
898 shape
->SetEventHandler(new csEvtHandler(shape
, shape
, newLabel
));
900 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
901 wxString
str(comboBox
->GetValue());
903 str
.ToLong( &pointSize
);
905 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
906 shape
->GetFont()->GetFamily(),
907 shape
->GetFont()->GetStyle(),
908 shape
->GetFont()->GetWeight(),
909 shape
->GetFont()->GetUnderlined(),
910 shape
->GetFont()->GetFaceName());
912 shape
->SetFont(newFont
);
917 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Text box"),
918 (csDiagramDocument
*)GetView()->GetDocument(),
919 new csCommandState(ID_CS_ADD_SHAPE
, shape
, NULL
));
920 GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd
);
922 palette
->SetSelection(PALETTE_ARROW
);
927 csSymbol
* symbol
= wxGetApp().GetSymbolDatabase()->FindSymbol(palette
->GetSelection());
930 wxShape
* theShape
= symbol
->GetShape()->CreateNewCopy();
932 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
933 wxString
str(comboBox
->GetValue());
935 str
.ToLong( &pointSize
);
937 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
938 symbol
->GetShape()->GetFont()->GetFamily(),
939 symbol
->GetShape()->GetFont()->GetStyle(),
940 symbol
->GetShape()->GetFont()->GetWeight(),
941 symbol
->GetShape()->GetFont()->GetUnderlined(),
942 symbol
->GetShape()->GetFont()->GetFaceName());
944 theShape
->SetFont(newFont
);
946 theShape
->AssignNewIds();
950 csDiagramCommand
* cmd
= new csDiagramCommand(symbol
->GetName(),
951 (csDiagramDocument
*)GetView()->GetDocument(),
952 new csCommandState(ID_CS_ADD_SHAPE
, theShape
, NULL
));
953 GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd
);
955 palette
->SetSelection(PALETTE_ARROW
);
959 void csCanvas::OnRightClick(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
964 static double sg_initialX
, sg_initialY
;
966 void csCanvas::OnDragLeft(bool WXUNUSED(draw
), double x
, double y
, int WXUNUSED(keys
))
971 dc
.SetLogicalFunction(OGLRBLF
);
972 DrawOutline(dc
, sg_initialX
, sg_initialY
, x
, y
);
975 void csCanvas::OnBeginDragLeft(double x
, double y
, int WXUNUSED(keys
))
983 dc
.SetLogicalFunction(OGLRBLF
);
984 DrawOutline(dc
, sg_initialX
, sg_initialY
, x
, y
);
988 void csCanvas::OnEndDragLeft(double x
, double y
, int WXUNUSED(keys
))
995 // Select all images within the rectangle
996 float min_x
, max_x
, min_y
, max_y
;
997 min_x
= wxMin(x
, sg_initialX
);
998 max_x
= wxMax(x
, sg_initialX
);
999 min_y
= wxMin(y
, sg_initialY
);
1000 max_y
= wxMax(y
, sg_initialY
);
1002 wxObjectList::compatibility_iterator node
= GetDiagram()->GetShapeList()->GetFirst();
1005 wxShape
*shape
= (wxShape
*)node
->GetData();
1006 if (shape
->GetParent() == NULL
&& !shape
->IsKindOf(CLASSINFO(wxControlPoint
)))
1008 float image_x
= shape
->GetX();
1009 float image_y
= shape
->GetY();
1010 if (image_x
>= min_x
&& image_x
<= max_x
&&
1011 image_y
>= min_y
&& image_y
<= max_y
)
1013 shape
->Select(true, &dc
);
1014 GetView()->SelectShape(shape
, true);
1017 node
= node
->GetNext();
1021 void csCanvas::OnDragRight(bool WXUNUSED(draw
), double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1025 void csCanvas::OnBeginDragRight(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1029 void csCanvas::OnEndDragRight(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1033 void csCanvas::OnMouseEvent(wxMouseEvent
& event
)
1035 wxShapeCanvas::OnMouseEvent(event
);
1038 void csCanvas::OnPaint(wxPaintEvent
& event
)
1040 // if (GetDiagram())
1041 wxShapeCanvas::OnPaint(event
);