1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Implements view functionality
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
23 #include <wx/colordlg.h>
25 #if !wxUSE_DOC_VIEW_ARCHITECTURE
26 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in wx_setup.h!
32 #include "cspalette.h"
35 #include <wx/ogl/basicp.h>
36 #include <wx/ogl/linesp.h>
38 IMPLEMENT_DYNAMIC_CLASS(csDiagramView
, wxView
)
40 BEGIN_EVENT_TABLE(csDiagramView
, wxView
)
41 EVT_MENU(wxID_CUT
, csDiagramView::OnCut
)
42 EVT_MENU(wxID_COPY
, csDiagramView::OnCopy
)
43 EVT_MENU(wxID_CLEAR
, csDiagramView::OnClear
)
44 EVT_MENU(wxID_PASTE
, csDiagramView::OnPaste
)
45 EVT_MENU(wxID_DUPLICATE
, csDiagramView::OnDuplicate
)
46 EVT_MENU(ID_CS_CHANGE_BACKGROUND_COLOUR
, csDiagramView::OnChangeBackgroundColour
)
47 EVT_MENU(ID_CS_EDIT_PROPERTIES
, csDiagramView::OnEditProperties
)
48 EVT_MENU(ID_CS_SELECT_ALL
, csDiagramView::OnSelectAll
)
49 EVT_TOOL(DIAGRAM_TOOLBAR_LINE_ARROW
, csDiagramView::OnToggleArrowTool
)
50 EVT_COMBOBOX(ID_WINDOW_POINT_SIZE_COMBOBOX
, csDiagramView::OnPointSizeComboSel
)
51 EVT_COMBOBOX(ID_WINDOW_ZOOM_COMBOBOX
, csDiagramView::OnZoomSel
)
52 EVT_TEXT(ID_WINDOW_POINT_SIZE_COMBOBOX
, csDiagramView::OnPointSizeComboText
)
53 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNL
, csDiagramView::OnAlign
)
54 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNR
, csDiagramView::OnAlign
)
55 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNB
, csDiagramView::OnAlign
)
56 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGNT
, csDiagramView::OnAlign
)
57 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGN_HORIZ
, csDiagramView::OnAlign
)
58 EVT_TOOL(DIAGRAM_TOOLBAR_ALIGN_VERT
, csDiagramView::OnAlign
)
59 EVT_TOOL(DIAGRAM_TOOLBAR_COPY_SIZE
, csDiagramView::OnAlign
)
60 EVT_TOOL(DIAGRAM_TOOLBAR_NEW_POINT
, csDiagramView::OnNewLinePoint
)
61 EVT_TOOL(DIAGRAM_TOOLBAR_CUT_POINT
, csDiagramView::OnCutLinePoint
)
62 EVT_TOOL(DIAGRAM_TOOLBAR_STRAIGHTEN
, csDiagramView::OnStraightenLines
)
63 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNL
, csDiagramView::OnAlignUpdate
)
64 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNR
, csDiagramView::OnAlignUpdate
)
65 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNB
, csDiagramView::OnAlignUpdate
)
66 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGNT
, csDiagramView::OnAlignUpdate
)
67 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGN_HORIZ
, csDiagramView::OnAlignUpdate
)
68 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_ALIGN_VERT
, csDiagramView::OnAlignUpdate
)
69 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_COPY_SIZE
, csDiagramView::OnAlignUpdate
)
70 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_NEW_POINT
, csDiagramView::OnNewLinePointUpdate
)
71 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_CUT_POINT
, csDiagramView::OnCutLinePointUpdate
)
72 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_STRAIGHTEN
, csDiagramView::OnStraightenLinesUpdate
)
73 EVT_UPDATE_UI(DIAGRAM_TOOLBAR_LINE_ARROW
, csDiagramView::OnToggleArrowToolUpdate
)
74 EVT_UPDATE_UI(wxID_CUT
, csDiagramView::OnCutUpdate
)
75 EVT_UPDATE_UI(wxID_COPY
, csDiagramView::OnCopyUpdate
)
76 EVT_UPDATE_UI(wxID_CLEAR
, csDiagramView::OnClearUpdate
)
77 EVT_UPDATE_UI(wxID_PASTE
, csDiagramView::OnPasteUpdate
)
78 EVT_UPDATE_UI(wxID_DUPLICATE
, csDiagramView::OnDuplicateUpdate
)
79 EVT_UPDATE_UI(ID_CS_EDIT_PROPERTIES
, csDiagramView::OnEditPropertiesUpdate
)
80 EVT_UPDATE_UI(wxID_UNDO
, csDiagramView::OnUndoUpdate
)
81 EVT_UPDATE_UI(wxID_REDO
, csDiagramView::OnRedoUpdate
)
84 // What to do when a view is created. Creates actual
85 // windows for displaying the view.
86 bool csDiagramView::OnCreate(wxDocument
*doc
, long WXUNUSED(flags
))
89 frame
= wxGetApp().CreateChildFrame(doc
, this, &editMenu
);
90 canvas
= wxGetApp().CreateCanvas(this, frame
);
91 canvas
->SetView(this);
96 // Initialize the edit menu Undo and Redo items
97 doc
->GetCommandProcessor()->SetEditMenu(editMenu
);
98 doc
->GetCommandProcessor()->Initialize();
100 wxShapeCanvas
*shapeCanvas
= (wxShapeCanvas
*)canvas
;
101 csDiagramDocument
*diagramDoc
= (csDiagramDocument
*)doc
;
102 shapeCanvas
->SetDiagram(diagramDoc
->GetDiagram());
103 diagramDoc
->GetDiagram()->SetCanvas(shapeCanvas
);
105 diagramDoc
->GetDiagram()->SetGridSpacing((double) wxGetApp().GetGridSpacing());
107 switch (wxGetApp().GetGridStyle())
109 case csGRID_STYLE_NONE
:
111 diagramDoc
->GetDiagram()->SetSnapToGrid(false);
114 case csGRID_STYLE_INVISIBLE
:
116 diagramDoc
->GetDiagram()->SetSnapToGrid(true);
119 case csGRID_STYLE_DOTTED
:
121 // TODO (not implemented in OGL)
130 csDiagramView::~csDiagramView(void)
134 ((wxDocMDIChildFrame
*)frame
)->SetView(NULL
);
138 // Sneakily gets used for default print/preview
139 // as well as drawing on the screen.
140 void csDiagramView::OnDraw(wxDC
*WXUNUSED(dc
))
144 void csDiagramView::OnUpdate(wxView
*WXUNUSED(sender
), wxObject
*WXUNUSED(hint
))
150 // Clean up windows used for displaying the view.
151 bool csDiagramView::OnClose(bool deleteWindow
)
153 if (!GetDocument()->Close())
156 csDiagramDocument
*diagramDoc
= (csDiagramDocument
*)GetDocument();
157 diagramDoc
->GetDiagram()->SetCanvas(NULL
);
159 canvas
->ClearBackground();
160 canvas
->SetDiagram(NULL
);
161 canvas
->SetView(NULL
);
164 wxMenu
* fileMenu
= frame
->GetMenuBar()->GetMenu(0);
166 // Remove file menu from those managed by the command history
167 wxGetApp().GetDocManager()->FileHistoryRemoveMenu(fileMenu
);
180 // Adds or removes shape from m_selections
181 void csDiagramView::SelectShape(wxShape
* shape
, bool select
)
183 if (select
&& !m_selections
.Member(shape
))
184 m_selections
.Append(shape
);
186 m_selections
.DeleteObject(shape
);
189 void csDiagramView::OnSelectAll(wxCommandEvent
& WXUNUSED(event
))
194 wxShape
*csDiagramView::FindFirstSelectedShape(void)
196 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
197 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
200 wxShape
*eachShape
= (wxShape
*)node
->GetData();
201 if ((eachShape
->GetParent() == NULL
) && !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)) && eachShape
->Selected())
205 else node
= node
->GetNext();
210 void csDiagramView::FindSelectedShapes(wxList
& selections
, wxClassInfo
* toFind
)
212 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
213 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
216 wxShape
*eachShape
= (wxShape
*)node
->GetData();
217 if ((eachShape
->GetParent() == NULL
) && !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)) && eachShape
->Selected() && ((toFind
== NULL
) || (eachShape
->IsKindOf(toFind
))))
219 selections
.Append(eachShape
);
221 node
= node
->GetNext();
225 void csDiagramView::OnUndoUpdate(wxUpdateUIEvent
& event
)
227 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
228 event
.Enable(doc
->GetCommandProcessor()->CanUndo());
231 void csDiagramView::OnRedoUpdate(wxUpdateUIEvent
& event
)
233 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
234 event
.Enable(doc
->GetCommandProcessor()->CanRedo());
237 void csDiagramView::OnCut(wxCommandEvent
& WXUNUSED(event
))
239 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
241 // Copy the shapes to the clipboard
242 wxGetApp().GetDiagramClipboard().Copy(doc
->GetDiagram());
245 FindSelectedShapes(selections
);
250 void csDiagramView::OnClear(wxCommandEvent
& WXUNUSED(event
))
253 FindSelectedShapes(selections
);
258 void csDiagramView::OnCopy(wxCommandEvent
& WXUNUSED(event
))
260 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
262 // Copy the shapes to the clipboard
263 if (wxGetApp().GetDiagramClipboard().Copy(doc
->GetDiagram()))
266 // Copy to the Windows clipboard
267 wxGetApp().GetDiagramClipboard().CopyToClipboard(1.0);
272 void csDiagramView::OnPaste(wxCommandEvent
& WXUNUSED(event
))
274 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
276 wxGetApp().GetDiagramClipboard().Paste(doc
->GetDiagram());
279 void csDiagramView::OnDuplicate(wxCommandEvent
& WXUNUSED(event
))
281 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
283 // Do a copy, then a paste
284 wxGetApp().GetDiagramClipboard().Copy(doc
->GetDiagram());
286 // Apply an offset. Really, this offset should keep being incremented,
287 // but where do we reset it again?
288 wxGetApp().GetDiagramClipboard().Paste(doc
->GetDiagram(), NULL
, 20, 20);
291 void csDiagramView::OnCutUpdate(wxUpdateUIEvent
& event
)
293 event
.Enable( (m_selections
.GetCount() > 0) );
296 void csDiagramView::OnClearUpdate(wxUpdateUIEvent
& event
)
298 event
.Enable( (m_selections
.GetCount() > 0) );
301 void csDiagramView::OnCopyUpdate(wxUpdateUIEvent
& event
)
303 event
.Enable( (m_selections
.GetCount() > 0) );
306 void csDiagramView::OnPasteUpdate(wxUpdateUIEvent
& event
)
308 int n
= wxGetApp().GetDiagramClipboard().GetCount();
310 event
.Enable( (n
> 0) );
313 void csDiagramView::OnDuplicateUpdate(wxUpdateUIEvent
& event
)
315 event
.Enable( (m_selections
.GetCount() > 0) );
318 void csDiagramView::DoCut(wxList
& shapes
)
320 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
322 if (shapes
.GetCount() > 0)
324 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Cut"), doc
);
326 wxObjectList::compatibility_iterator node
= shapes
.GetFirst();
329 wxShape
*theShape
= (wxShape
*) node
->GetData();
330 csCommandState
* state
= new csCommandState(ID_CS_CUT
, NULL
, theShape
);
332 // Insert lines at the front, so they are cut first.
333 // Otherwise we may try to remove a shape with a line still
335 if (theShape
->IsKindOf(CLASSINFO(wxLineShape
)))
336 cmd
->InsertState(state
);
338 cmd
->AddState(state
);
340 node
= node
->GetNext();
342 cmd
->RemoveLines(); // Schedule any connected lines, not already mentioned,
343 // to be removed first
345 doc
->GetCommandProcessor()->Submit(cmd
);
349 // Generalised command
350 void csDiagramView::DoCmd(wxList
& shapes
, wxList
& oldShapes
, int cmd
, const wxString
& op
)
352 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
354 if (shapes
.GetCount() > 0)
356 csDiagramCommand
* command
= new csDiagramCommand(op
, doc
);
358 wxObjectList::compatibility_iterator node
= shapes
.GetFirst();
359 wxObjectList::compatibility_iterator node1
= oldShapes
.GetFirst();
360 while (node
&& node1
)
362 wxShape
*theShape
= (wxShape
*) node
->GetData();
363 wxShape
*oldShape
= (wxShape
*) node1
->GetData();
364 csCommandState
* state
= new csCommandState(cmd
, theShape
, oldShape
);
365 command
->AddState(state
);
367 node
= node
->GetNext();
368 node1
= node1
->GetNext();
370 doc
->GetCommandProcessor()->Submit(command
);
374 void csDiagramView::OnChangeBackgroundColour(wxCommandEvent
& WXUNUSED(event
))
376 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
379 FindSelectedShapes(selections
);
381 if (selections
.GetCount() > 0)
384 data
.SetChooseFull(true);
385 if (selections
.GetCount() == 1)
387 wxShape
* firstShape
= (wxShape
*) selections
.GetFirst()->GetData();
388 data
.SetColour(firstShape
->GetBrush()->GetColour());
391 wxColourDialog
*dialog
= new wxColourDialog(frame
, &data
);
392 wxBrush
*theBrush
= NULL
;
393 if (dialog
->ShowModal() == wxID_OK
)
395 wxColourData retData
= dialog
->GetColourData();
396 wxColour col
= retData
.GetColour();
397 theBrush
= wxTheBrushList
->FindOrCreateBrush(col
, wxSOLID
);
403 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Change colour"), doc
);
405 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
408 wxShape
*theShape
= (wxShape
*) node
->GetData();
409 wxShape
* newShape
= theShape
->CreateNewCopy();
410 newShape
->SetBrush(theBrush
);
412 csCommandState
* state
= new csCommandState(ID_CS_CHANGE_BACKGROUND_COLOUR
, newShape
, theShape
);
413 cmd
->AddState(state
);
415 node
= node
->GetNext();
417 doc
->GetCommandProcessor()->Submit(cmd
);
421 void csDiagramView::OnEditProperties(wxCommandEvent
& WXUNUSED(event
))
423 wxShape
*theShape
= FindFirstSelectedShape();
425 ((csEvtHandler
*)theShape
->GetEventHandler())->EditProperties();
428 void csDiagramView::OnEditPropertiesUpdate(wxUpdateUIEvent
& event
)
431 FindSelectedShapes(selections
);
432 event
.Enable( (selections
.GetCount() > 0) );
435 void csDiagramView::OnPointSizeComboSel(wxCommandEvent
& event
)
437 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
438 wxASSERT( combo
!= NULL
);
440 int newPointSize
= (combo
->GetSelection() + 1);
442 ApplyPointSize(newPointSize
);
446 // TODO: must find out how to intercept the Return key, rather than
447 // every key stroke. But for now, do every key stroke.
448 void csDiagramView::OnPointSizeComboText(wxCommandEvent
& event
)
450 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
451 wxASSERT( combo
!= NULL
);
453 wxString
str(combo
->GetValue());
455 str
.ToLong( &newPointSize
);
457 if (newPointSize
< 2)
460 ApplyPointSize(newPointSize
);
463 void csDiagramView::ApplyPointSize(int pointSize
)
465 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
468 FindSelectedShapes(selections
);
470 if (selections
.GetCount() > 0)
472 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Point size"), doc
);
474 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
477 wxShape
*theShape
= (wxShape
*) node
->GetData();
478 wxShape
*newShape
= theShape
->CreateNewCopy();
480 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
481 theShape
->GetFont()->GetFamily(),
482 theShape
->GetFont()->GetStyle(),
483 theShape
->GetFont()->GetWeight(),
484 theShape
->GetFont()->GetUnderlined(),
485 theShape
->GetFont()->GetFaceName());
487 newShape
->SetFont(newFont
);
489 csCommandState
* state
= new csCommandState(ID_CS_FONT_CHANGE
, newShape
, theShape
);
491 cmd
->AddState(state
);
493 node
= node
->GetNext();
495 doc
->GetCommandProcessor()->Submit(cmd
);
499 void csDiagramView::OnZoomSel(wxCommandEvent
& event
)
504 int noStrings
= (maxZoom
- minZoom
)/inc
;
506 wxComboBox
* combo
= (wxComboBox
*) event
.GetEventObject();
507 wxASSERT( combo
!= NULL
);
509 int scale
= (int) ((noStrings
- combo
->GetSelection() - 1)*inc
+ minZoom
);
511 canvas
->SetScale((double) (scale
/100.0), (double) (scale
/100.0));
515 // Select or deselect all
516 void csDiagramView::SelectAll(bool select
)
518 wxClientDC
dc(canvas
);
519 canvas
->PrepareDC(dc
);
524 FindSelectedShapes(selections
);
526 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
529 wxShape
*theShape
= (wxShape
*) node
->GetData();
530 theShape
->Select(false, &dc
);
531 SelectShape(theShape
, false);
533 node
= node
->GetNext();
538 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
539 wxObjectList::compatibility_iterator node
= doc
->GetDiagram()->GetShapeList()->GetFirst();
542 wxShape
*eachShape
= (wxShape
*)node
->GetData();
543 if (eachShape
->GetParent() == NULL
&&
544 !eachShape
->IsKindOf(CLASSINFO(wxControlPoint
)) &&
545 !eachShape
->IsKindOf(CLASSINFO(wxLabelShape
)))
547 eachShape
->Select(true, &dc
);
548 SelectShape(eachShape
, true);
550 node
= node
->GetNext();
556 void csDiagramView::OnToggleArrowTool(wxCommandEvent
& WXUNUSED(event
))
558 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
560 bool state
= wxGetApp().GetDiagramToolBar()->GetToolState(DIAGRAM_TOOLBAR_LINE_ARROW
);
563 stateName
= _T("Arrow on");
565 stateName
= _T("Arrow off");
568 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
570 if (selections
.GetCount() > 0)
572 csDiagramCommand
* cmd
= new csDiagramCommand(stateName
, doc
);
574 wxObjectList::compatibility_iterator node
= selections
.GetFirst();
577 wxLineShape
*theShape
= (wxLineShape
*) node
->GetData();
578 wxLineShape
*newShape
= NULL
;
583 if (theShape
->GetArrows().GetCount() == 0)
585 newShape
= (wxLineShape
*) theShape
->CreateNewCopy();
586 newShape
->AddArrow(ARROW_ARROW
, ARROW_POSITION_MIDDLE
, 10.0, 0.0, _T("Normal arrowhead"));
591 if (theShape
->GetArrows().GetCount() > 0)
593 newShape
= (wxLineShape
*) theShape
->CreateNewCopy();
594 newShape
->ClearArrowsAtPosition();
598 // If the new state is the same as the old, don't bother adding it to the command state.
601 csCommandState
* state
= new csCommandState(ID_CS_ARROW_CHANGE
, newShape
, theShape
);
602 cmd
->AddState(state
);
605 node
= node
->GetNext();
607 doc
->GetCommandProcessor()->Submit(cmd
);
611 void csDiagramView::OnToggleArrowToolUpdate(wxUpdateUIEvent
& event
)
614 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
615 event
.Enable( (selections
.GetCount() > 0) );
618 // Make the point size combobox reflect this
619 void csDiagramView::ReflectPointSize(int pointSize
)
621 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
622 comboBox
->SetSelection(pointSize
-1);
625 // Make the arrow toggle button reflect the state of the line
626 void csDiagramView::ReflectArrowState(wxLineShape
* lineShape
)
628 bool haveArrow
= false;
629 wxObjectList::compatibility_iterator node
= lineShape
->GetArrows().GetFirst();
632 wxArrowHead
*arrow
= (wxArrowHead
*)node
->GetData();
633 if (ARROW_POSITION_MIDDLE
== arrow
->GetArrowEnd())
635 node
= node
->GetNext();
638 wxGetApp().GetDiagramToolBar()->ToggleTool(DIAGRAM_TOOLBAR_LINE_ARROW
, haveArrow
);
641 void csDiagramView::OnAlign(wxCommandEvent
& event
)
643 // Make a copy of the selections, keeping only those shapes
644 // that are top-level non-line shapes.
646 wxObjectList::compatibility_iterator node
= GetSelectionList().GetFirst();
649 wxShape
* shape
= (wxShape
*) node
->GetData();
650 if ((shape
->GetParent() == NULL
) && (!shape
->IsKindOf(CLASSINFO(wxLineShape
))))
652 selections
.Append(shape
);
654 node
= node
->GetNext();
657 if (selections
.GetCount() == 0)
660 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
661 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Align"), doc
);
663 node
= selections
.GetFirst();
664 wxShape
* firstShape
= (wxShape
*) node
->GetData();
666 double x
= firstShape
->GetX();
667 double y
= firstShape
->GetY();
668 double width
, height
;
669 firstShape
->GetBoundingBoxMax(&width
, &height
);
671 node
= selections
.GetFirst();
674 wxShape
* shape
= (wxShape
*) node
->GetData();
675 if (shape
!= firstShape
)
677 /* double x1 = */ shape
->GetX();
678 /* double y1 = */ shape
->GetY();
679 double width1
, height1
;
680 shape
->GetBoundingBoxMax(& width1
, & height1
);
682 wxShape
* newShape
= shape
->CreateNewCopy();
684 switch (event
.GetId())
686 case DIAGRAM_TOOLBAR_ALIGNL
:
688 double x2
= (double)(x
- (width
/2.0) + (width1
/2.0));
692 case DIAGRAM_TOOLBAR_ALIGNR
:
694 double x2
= (double)(x
+ (width
/2.0) - (width1
/2.0));
698 case DIAGRAM_TOOLBAR_ALIGNB
:
700 double y2
= (double)(y
+ (height
/2.0) - (height1
/2.0));
704 case DIAGRAM_TOOLBAR_ALIGNT
:
706 double y2
= (double)(y
- (height
/2.0) + (height1
/2.0));
710 case DIAGRAM_TOOLBAR_ALIGN_HORIZ
:
715 case DIAGRAM_TOOLBAR_ALIGN_VERT
:
720 case DIAGRAM_TOOLBAR_COPY_SIZE
:
722 newShape
->SetSize(width
, height
);
726 csCommandState
* state
= new csCommandState(ID_CS_ALIGN
, newShape
, shape
);
727 cmd
->AddState(state
);
729 node
= node
->GetNext();
731 doc
->GetCommandProcessor()->Submit(cmd
);
734 void csDiagramView::OnAlignUpdate(wxUpdateUIEvent
& event
)
736 // This is an approximation, since there may be lines
737 // amongst the selections.
738 event
.Enable( (m_selections
.GetCount() > 1) ) ;
741 void csDiagramView::OnNewLinePoint(wxCommandEvent
& WXUNUSED(event
))
743 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
744 csDiagramCommand
* cmd
= new csDiagramCommand(_T("New line point"), doc
);
746 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
749 wxShape
* shape
= (wxShape
*) node
->GetData();
750 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
752 wxShape
* newShape
= shape
->CreateNewCopy();
753 ((wxLineShape
*)newShape
)->InsertLineControlPoint(NULL
);
754 csCommandState
* state
= new csCommandState(ID_CS_NEW_POINT
, newShape
, shape
);
755 cmd
->AddState(state
);
757 node
= node
->GetNext();
759 doc
->GetCommandProcessor()->Submit(cmd
);
762 void csDiagramView::OnCutLinePoint(wxCommandEvent
& WXUNUSED(event
))
764 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
765 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Cut line point"), doc
);
767 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
770 wxShape
* shape
= (wxShape
*) node
->GetData();
771 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
773 wxShape
* newShape
= shape
->CreateNewCopy();
774 ((wxLineShape
*)newShape
)->DeleteLineControlPoint();
775 csCommandState
* state
= new csCommandState(ID_CS_CUT_POINT
, newShape
, shape
);
776 cmd
->AddState(state
);
778 node
= node
->GetNext();
780 doc
->GetCommandProcessor()->Submit(cmd
);
783 void csDiagramView::OnStraightenLines(wxCommandEvent
& WXUNUSED(event
))
785 csDiagramDocument
*doc
= (csDiagramDocument
*)GetDocument();
786 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Straighten lines"), doc
);
788 wxObjectList::compatibility_iterator node
= m_selections
.GetFirst();
791 wxShape
* shape
= (wxShape
*) node
->GetData();
792 if (shape
->IsKindOf(CLASSINFO(wxLineShape
)))
794 wxShape
* newShape
= shape
->CreateNewCopy();
795 ((wxLineShape
*)newShape
)->Straighten();
796 csCommandState
* state
= new csCommandState(ID_CS_STRAIGHTEN
, newShape
, shape
);
797 cmd
->AddState(state
);
799 node
= node
->GetNext();
801 doc
->GetCommandProcessor()->Submit(cmd
);
804 void csDiagramView::OnNewLinePointUpdate(wxUpdateUIEvent
& event
)
807 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
808 event
.Enable( (selections
.GetCount() > 0) );
811 void csDiagramView::OnCutLinePointUpdate(wxUpdateUIEvent
& event
)
814 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
815 event
.Enable( (selections
.GetCount() > 0) );
818 void csDiagramView::OnStraightenLinesUpdate(wxUpdateUIEvent
& event
)
821 FindSelectedShapes(selections
, CLASSINFO(wxLineShape
));
822 event
.Enable( (selections
.GetCount() > 0) );
826 * Window implementations
829 IMPLEMENT_CLASS(csCanvas
, wxShapeCanvas
)
831 BEGIN_EVENT_TABLE(csCanvas
, wxShapeCanvas
)
832 EVT_MOUSE_EVENTS(csCanvas::OnMouseEvent
)
833 EVT_PAINT(csCanvas::OnPaint
)
836 // Define a constructor for my canvas
837 csCanvas::csCanvas(csDiagramView
*v
, wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
,
838 const wxSize
& size
, long style
):
839 wxShapeCanvas(parent
, id
, pos
, size
, style
)
844 csCanvas::~csCanvas(void)
848 void csCanvas::DrawOutline(wxDC
& dc
, double x1
, double y1
, double x2
, double y2
)
850 wxPen
dottedPen(*wxBLACK
, 1, wxDOT
);
851 dc
.SetPen(dottedPen
);
852 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
854 dc
.DrawRectangle((long) x1
, (long) y1
, (long) (x2
- x1
), (long) (y2
- y1
));
857 void csCanvas::OnLeftClick(double x
, double y
, int WXUNUSED(keys
))
859 csEditorToolPalette
*palette
= wxGetApp().GetDiagramPalette();
861 if (palette
->GetSelection() == PALETTE_ARROW
)
863 GetView()->SelectAll(false);
872 if (palette
->GetSelection() == PALETTE_TEXT_TOOL
)
876 #if wxUSE_WX_RESOURCES
877 // Ask for a label and create a new free-floating text region
878 csLabelEditingDialog
* dialog
= new csLabelEditingDialog(GetParent());
880 dialog
->SetShapeLabel( wxEmptyString
);
881 dialog
->SetTitle(_T("New text box"));
882 if (dialog
->ShowModal() == wxID_CANCEL
)
888 newLabel
= dialog
->GetShapeLabel();
890 #endif // wxUSE_WX_RESOURCES
892 wxShape
* shape
= new csTextBoxShape
;
893 shape
->AssignNewIds();
894 shape
->SetEventHandler(new csEvtHandler(shape
, shape
, newLabel
));
896 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
897 wxString
str(comboBox
->GetValue());
899 str
.ToLong( &pointSize
);
901 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
902 shape
->GetFont()->GetFamily(),
903 shape
->GetFont()->GetStyle(),
904 shape
->GetFont()->GetWeight(),
905 shape
->GetFont()->GetUnderlined(),
906 shape
->GetFont()->GetFaceName());
908 shape
->SetFont(newFont
);
913 csDiagramCommand
* cmd
= new csDiagramCommand(_T("Text box"),
914 (csDiagramDocument
*)GetView()->GetDocument(),
915 new csCommandState(ID_CS_ADD_SHAPE
, shape
, NULL
));
916 GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd
);
918 palette
->SetSelection(PALETTE_ARROW
);
923 csSymbol
* symbol
= wxGetApp().GetSymbolDatabase()->FindSymbol(palette
->GetSelection());
926 wxShape
* theShape
= symbol
->GetShape()->CreateNewCopy();
928 wxComboBox
* comboBox
= wxGetApp().GetPointSizeComboBox();
929 wxString
str(comboBox
->GetValue());
931 str
.ToLong( &pointSize
);
933 wxFont
* newFont
= wxTheFontList
->FindOrCreateFont(pointSize
,
934 symbol
->GetShape()->GetFont()->GetFamily(),
935 symbol
->GetShape()->GetFont()->GetStyle(),
936 symbol
->GetShape()->GetFont()->GetWeight(),
937 symbol
->GetShape()->GetFont()->GetUnderlined(),
938 symbol
->GetShape()->GetFont()->GetFaceName());
940 theShape
->SetFont(newFont
);
942 theShape
->AssignNewIds();
946 csDiagramCommand
* cmd
= new csDiagramCommand(symbol
->GetName(),
947 (csDiagramDocument
*)GetView()->GetDocument(),
948 new csCommandState(ID_CS_ADD_SHAPE
, theShape
, NULL
));
949 GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd
);
951 palette
->SetSelection(PALETTE_ARROW
);
955 void csCanvas::OnRightClick(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
960 static double sg_initialX
, sg_initialY
;
962 void csCanvas::OnDragLeft(bool WXUNUSED(draw
), double x
, double y
, int WXUNUSED(keys
))
967 dc
.SetLogicalFunction(OGLRBLF
);
968 DrawOutline(dc
, sg_initialX
, sg_initialY
, x
, y
);
971 void csCanvas::OnBeginDragLeft(double x
, double y
, int WXUNUSED(keys
))
979 dc
.SetLogicalFunction(OGLRBLF
);
980 DrawOutline(dc
, sg_initialX
, sg_initialY
, x
, y
);
984 void csCanvas::OnEndDragLeft(double x
, double y
, int WXUNUSED(keys
))
991 // Select all images within the rectangle
992 float min_x
, max_x
, min_y
, max_y
;
993 min_x
= wxMin(x
, sg_initialX
);
994 max_x
= wxMax(x
, sg_initialX
);
995 min_y
= wxMin(y
, sg_initialY
);
996 max_y
= wxMax(y
, sg_initialY
);
998 wxObjectList::compatibility_iterator node
= GetDiagram()->GetShapeList()->GetFirst();
1001 wxShape
*shape
= (wxShape
*)node
->GetData();
1002 if (shape
->GetParent() == NULL
&& !shape
->IsKindOf(CLASSINFO(wxControlPoint
)))
1004 float image_x
= shape
->GetX();
1005 float image_y
= shape
->GetY();
1006 if (image_x
>= min_x
&& image_x
<= max_x
&&
1007 image_y
>= min_y
&& image_y
<= max_y
)
1009 shape
->Select(true, &dc
);
1010 GetView()->SelectShape(shape
, true);
1013 node
= node
->GetNext();
1017 void csCanvas::OnDragRight(bool WXUNUSED(draw
), double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1021 void csCanvas::OnBeginDragRight(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1025 void csCanvas::OnEndDragRight(double WXUNUSED(x
), double WXUNUSED(y
), int WXUNUSED(keys
))
1029 void csCanvas::OnMouseEvent(wxMouseEvent
& event
)
1031 wxShapeCanvas::OnMouseEvent(event
);
1034 void csCanvas::OnPaint(wxPaintEvent
& event
)
1036 // if (GetDiagram())
1037 wxShapeCanvas::OnPaint(event
);