]> git.saurik.com Git - wxWidgets.git/blame - contrib/samples/ogl/studio/shapes.cpp
reversed change
[wxWidgets.git] / contrib / samples / ogl / studio / shapes.cpp
CommitLineData
1fc25a89
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: shapes.cpp
3// Purpose: Implements Studio shapes
4// Author: Julian Smart
5// Modified by:
6// Created: 12/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13// #pragma implementation
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
92a19c2e 17#include "wx/wxprec.h"
1fc25a89
JS
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <wx/wx.h>
25#endif
26
27#if !wxUSE_DOC_VIEW_ARCHITECTURE
28#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in wx_setup.h!
29#endif
30
7c9955d1
JS
31#include <wx/deprecated/setup.h>
32#include <wx/deprecated/wxexpr.h>
1fc25a89
JS
33
34#include "studio.h"
35#include "doc.h"
36#include "shapes.h"
37#include "view.h"
38#include <wx/ogl/basicp.h>
39#include <wx/ogl/linesp.h>
40#include "cspalette.h"
41#include "dialogs.h"
42
43#define csSTANDARD_SHAPE_WIDTH 100
44
45IMPLEMENT_CLASS(csDiagram, wxDiagram)
46
47csDiagram::~csDiagram()
48{
49 DeleteAllShapes();
50}
51
52void csDiagram::Redraw(wxDC& dc)
53{
54 wxDiagram::Redraw(dc);
55
56 // Draw line crossings
57 wxLineCrossings lineCrossings;
58 lineCrossings.FindCrossings(*this);
59 lineCrossings.DrawCrossings(*this, dc);
60}
61
62/*
63 * csEvtHandler: an event handler class for all shapes
64 */
65
66IMPLEMENT_DYNAMIC_CLASS(csEvtHandler, wxShapeEvtHandler)
67
68csEvtHandler::csEvtHandler(wxShapeEvtHandler *prev, wxShape *shape, const wxString& lab):
69 wxShapeEvtHandler(prev, shape)
70{
71 m_label = lab;
72}
73
74csEvtHandler::~csEvtHandler()
75{
76}
77
78// Copy any event handler data
79void csEvtHandler::CopyData(wxShapeEvtHandler& copy)
80{
81 wxShapeEvtHandler::CopyData(copy);
82
83 csEvtHandler& csCopy = (csEvtHandler&) copy;
84 csCopy.m_label = m_label;
85}
86
1484b5cc 87void csEvtHandler::OnLeftClick(double WXUNUSED(x), double WXUNUSED(y), int keys, int WXUNUSED(attachment))
1fc25a89
JS
88{
89 wxClientDC dc(GetShape()->GetCanvas());
90 GetShape()->GetCanvas()->PrepareDC(dc);
91
92 csDiagramView* view = ((csCanvas*)GetShape()->GetCanvas())->GetView();
93 view->ReflectPointSize(GetShape()->GetFont()->GetPointSize());
94
95 if (GetShape()->IsKindOf(CLASSINFO(wxLineShape)))
96 view->ReflectArrowState((wxLineShape*) GetShape());
97
98 csEditorToolPalette *palette = wxGetApp().GetDiagramPalette();
99 if (palette->GetSelection() == PALETTE_TEXT_TOOL)
100 {
101 view->ReflectPointSize(GetShape()->GetFont()->GetPointSize());
102
103 EditProperties();
104#if 0
105 csLabelEditingDialog* dialog = new csLabelEditingDialog(GetShape()->GetCanvas()->GetParent());
106 dialog->SetShapeLabel(m_label);
107 if (dialog->ShowModal() == wxID_CANCEL)
108 {
109 dialog->Destroy();
110 return;
111 }
112
113 wxString newLabel = dialog->GetShapeLabel();
114 dialog->Destroy();
115
116 wxShape* newShape = GetShape()->CreateNewCopy();
117
118 csEvtHandler* handler = (csEvtHandler *)newShape->GetEventHandler();
119 handler->m_label = newLabel;
120
121 view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand("Edit label", (csDiagramDocument*) view->GetDocument(),
122 new csCommandState(ID_CS_EDIT_PROPERTIES, newShape, GetShape())));
123#endif
124 return;
125 }
126
127 if (keys == 0)
128 {
129 // If no shift key, then everything is deselected.
130 // If the shape was selected, deselect it and vice versa.
131 bool selected = GetShape()->Selected();
132
133 view->SelectAll(FALSE);
134
135 selected = !selected;
136
137 GetShape()->Select(selected, &dc);
138 GetShape()->GetCanvas()->Redraw(dc); // Redraw because bits of objects will be missing
139
140 view->SelectShape(GetShape(), selected);
141 }
142 else if (keys & KEY_SHIFT)
143 {
144 if (GetShape()->Selected())
145 {
146 GetShape()->Select(FALSE, &dc);
147 view->SelectShape(GetShape(), FALSE);
148 }
149 else
150 {
151 GetShape()->Select(TRUE, &dc);
152 view->SelectShape(GetShape(), TRUE);
153 }
154 GetShape()->GetCanvas()->Redraw(dc); // Redraw because bits of objects will be missing
155 }
156 else if (keys & KEY_CTRL)
157 {
158 // Do something for CONTROL
159 }
160 else
161 {
162 ((wxFrame*)wxGetApp().GetTopWindow())->SetStatusText(m_label);
163 }
164}
165
1484b5cc 166void csEvtHandler::OnRightClick(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
1fc25a89
JS
167{
168 // Have to convert back to physical coordinates from logical coordinates.
169
170 int viewStartX, viewStartY;
171 int unitX, unitY;
a059a1f2 172 GetShape()->GetCanvas()->GetViewStart(& viewStartX, & viewStartY);
1fc25a89
JS
173 GetShape()->GetCanvas()->GetScrollPixelsPerUnit(& unitX, & unitY);
174
175 int x1 = (int)(x * GetShape()->GetCanvas()->GetScaleX());
176 int y1 = (int)(y * GetShape()->GetCanvas()->GetScaleY());
177
178 int menuX = (int) (x1 - (viewStartX * unitX)) ;
179 int menuY = (int) (y1 - (viewStartY * unitY));
180
181 wxGetApp().GetShapeEditMenu()->SetClientData((char*) GetShape());
182 wxGetApp().GetShapeEditMenu()->Enable(ID_CS_ROTATE_CLOCKWISE, !GetShape()->IsKindOf(CLASSINFO(wxLineShape)));
183 wxGetApp().GetShapeEditMenu()->Enable(ID_CS_ROTATE_ANTICLOCKWISE, !GetShape()->IsKindOf(CLASSINFO(wxLineShape)));
184
185 GetShape()->GetCanvas()->PopupMenu(wxGetApp().GetShapeEditMenu(), menuX, menuY);
186}
187
188/*
189 * Implement connection of two shapes by right-dragging between them.
190 */
191
1484b5cc 192void csEvtHandler::OnBeginDragRight(double x, double y, int WXUNUSED(keys), int attachment)
1fc25a89
JS
193{
194 wxClientDC dc(GetShape()->GetCanvas());
195 GetShape()->GetCanvas()->PrepareDC(dc);
196
197 wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
198 dc.SetLogicalFunction(OGLRBLF);
199 dc.SetPen(dottedPen);
200 double xp, yp;
201 GetShape()->GetAttachmentPositionEdge(attachment, &xp, &yp);
8552e6f0 202 dc.DrawLine((wxCoord)xp, (wxCoord)yp, (wxCoord)x, (wxCoord)y);
1fc25a89
JS
203 GetShape()->GetCanvas()->CaptureMouse();
204}
205
1484b5cc 206void csEvtHandler::OnDragRight(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int attachment)
1fc25a89
JS
207{
208 wxClientDC dc(GetShape()->GetCanvas());
209 GetShape()->GetCanvas()->PrepareDC(dc);
210
211 wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
212 dc.SetLogicalFunction(OGLRBLF);
213 dc.SetPen(dottedPen);
214 double xp, yp;
215 GetShape()->GetAttachmentPositionEdge(attachment, &xp, &yp);
8552e6f0 216 dc.DrawLine((wxCoord)xp, (wxCoord)yp, (wxCoord)x, (wxCoord)y);
1fc25a89
JS
217}
218
1484b5cc 219void csEvtHandler::OnEndDragRight(double x, double y, int WXUNUSED(keys), int attachment)
1fc25a89
JS
220{
221 GetShape()->GetCanvas()->ReleaseMouse();
222 csCanvas *canvas = (csCanvas *)GetShape()->GetCanvas();
223
224 // Check if we're on an object
225 int new_attachment;
226 wxShape *otherShape = canvas->FindFirstSensitiveShape(x, y, &new_attachment, OP_DRAG_RIGHT);
227
228 if (otherShape && !otherShape->IsKindOf(CLASSINFO(wxLineShape)))
229 {
230 wxLineShape* theShape = new csLineShape;
231
232 theShape->AssignNewIds();
1484b5cc 233 theShape->SetEventHandler(new csEvtHandler(theShape, theShape, wxEmptyString));
1fc25a89
JS
234 theShape->SetPen(wxBLACK_PEN);
235 theShape->SetBrush(wxRED_BRUSH);
236
237 wxToolBar* toolbar = wxGetApp().GetDiagramToolBar();
238 bool haveArrow = toolbar->GetToolState(DIAGRAM_TOOLBAR_LINE_ARROW);
239
240 wxLineShape *lineShape = (wxLineShape *)theShape;
241
242 // Yes, you can have more than 2 control points, in which case
243 // it becomes a multi-segment line.
244 lineShape->MakeLineControlPoints(2);
245
246 if (haveArrow)
1484b5cc 247 lineShape->AddArrow(ARROW_ARROW, ARROW_POSITION_MIDDLE, 10.0, 0.0, _T("Normal arrowhead"));
1fc25a89
JS
248
249 lineShape->SetFrom(GetShape());
250 lineShape->SetTo(otherShape);
251 lineShape->SetAttachments(attachment, new_attachment);
252
253 canvas->GetView()->GetDocument()->GetCommandProcessor()->Submit(
1484b5cc 254 new csDiagramCommand(_T("Line"), (csDiagramDocument *)canvas->GetView()->GetDocument(),
1fc25a89
JS
255 new csCommandState(ID_CS_ADD_LINE, lineShape, NULL)));
256 }
257}
258
259static double g_DragOffsetX = 0.0;
260static double g_DragOffsetY = 0.0;
261static double g_DragStartX = 0.0;
262static double g_DragStartY = 0.0;
263
264void csEvtHandler::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
265{
266 if ((GetShape()->GetSensitivityFilter() & OP_DRAG_LEFT) != OP_DRAG_LEFT)
267 {
268 attachment = 0;
269 double dist;
270 if (GetShape()->GetParent())
271 {
272 GetShape()->GetParent()->HitTest(x, y, &attachment, &dist);
273 GetShape()->GetParent()->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment);
274 }
275 return;
276 }
277
278 wxClientDC dc(GetShape()->GetCanvas());
279 GetShape()->GetCanvas()->PrepareDC(dc);
280
281 dc.SetLogicalFunction(OGLRBLF);
282
283 wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
284 dc.SetPen(dottedPen);
285 dc.SetBrush(* wxTRANSPARENT_BRUSH);
286
287 double xx, yy;
288 xx = x + g_DragOffsetX;
289 yy = y + g_DragOffsetY;
290
291 GetShape()->GetCanvas()->Snap(&xx, &yy);
292
293 double offsetX = xx - g_DragStartX;
294 double offsetY = yy - g_DragStartY;
295
296// m_xpos = xx; m_ypos = yy;
297 double w, h;
298 GetShape()->GetBoundingBoxMax(&w, &h);
299 GetShape()->GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h);
300
301 // Draw bounding box for other selected shapes
8552e6f0 302 wxNode* node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
1fc25a89
JS
303 while (node)
304 {
8552e6f0 305 wxShape* shape = (wxShape*) node->GetData();
1fc25a89
JS
306 if (shape->Selected() && !shape->IsKindOf(CLASSINFO(wxLineShape)) && (shape != GetShape()))
307 {
308 shape->GetBoundingBoxMax(&w, &h);
309 shape->OnDrawOutline(dc, shape->GetX() + offsetX, shape->GetY() + offsetY, w, h);
310 }
8552e6f0 311 node = node->GetNext();
1fc25a89
JS
312 }
313}
314
315void csEvtHandler::OnBeginDragLeft(double x, double y, int keys, int attachment)
316{
317 if ((GetShape()->GetSensitivityFilter() & OP_DRAG_LEFT) != OP_DRAG_LEFT)
318 {
319 attachment = 0;
320 double dist;
321 if (GetShape()->GetParent())
322 {
323 GetShape()->GetParent()->HitTest(x, y, &attachment, &dist);
324 GetShape()->GetParent()->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment);
325 }
326 return;
327 }
328
329 wxClientDC dc(GetShape()->GetCanvas());
330 GetShape()->GetCanvas()->PrepareDC(dc);
331
332 // New policy: don't erase shape until end of drag.
333// Erase(dc);
334
335 g_DragOffsetX = GetShape()->GetX() - x;
336 g_DragOffsetY = GetShape()->GetY() - y;
337
338 double xx, yy;
339 xx = x + g_DragOffsetX;
340 yy = y + g_DragOffsetY;
341
342 GetShape()->GetCanvas()->Snap(&xx, &yy);
343
344 g_DragStartX = GetShape()->GetX();
345 g_DragStartY = GetShape()->GetY();
346
347 double offsetX = xx - g_DragStartX;
348 double offsetY = yy - g_DragStartY;
349
350 dc.SetLogicalFunction(OGLRBLF);
351
352 wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
353 dc.SetPen(dottedPen);
354 dc.SetBrush((* wxTRANSPARENT_BRUSH));
355
356 double w, h;
357 GetShape()->GetBoundingBoxMax(&w, &h);
358 GetShape()->GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h);
359
360 // Draw bounding box for other selected shapes
8552e6f0 361 wxNode* node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
1fc25a89
JS
362 while (node)
363 {
8552e6f0 364 wxShape* shape = (wxShape*) node->GetData();
1fc25a89
JS
365 if (shape->Selected() && !shape->IsKindOf(CLASSINFO(wxLineShape)) && (shape != GetShape()))
366 {
367 shape->GetBoundingBoxMax(&w, &h);
368 shape->OnDrawOutline(dc, shape->GetX() + offsetX, shape->GetY() + offsetY, w, h);
369 }
8552e6f0 370 node = node->GetNext();
1fc25a89
JS
371 }
372
373 GetShape()->GetCanvas()->CaptureMouse();
374}
375
376
377void csEvtHandler::OnEndDragLeft(double x, double y, int keys, int attachment)
378{
379 csCanvas *canvas = (csCanvas *)GetShape()->GetCanvas();
380
381 canvas->ReleaseMouse();
382 if ((GetShape()->GetSensitivityFilter() & OP_DRAG_LEFT) != OP_DRAG_LEFT)
383 {
384 attachment = 0;
385 double dist;
386 if (GetShape()->GetParent())
387 {
388 GetShape()->GetParent()->HitTest(x, y, &attachment, &dist);
389 GetShape()->GetParent()->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment);
390 }
391 return;
392 }
393
394 wxClientDC dc(canvas);
395 canvas->PrepareDC(dc);
396
397 dc.SetLogicalFunction(wxCOPY);
398
399 double xx = x + g_DragOffsetX;
400 double yy = y + g_DragOffsetY;
401
402 canvas->Snap(&xx, &yy);
403
404 double offsetX = xx - g_DragStartX;
405 double offsetY = yy - g_DragStartY;
406
407 wxShape* newShape = GetShape()->CreateNewCopy();
408
409 newShape->SetX(xx);
410 newShape->SetY(yy);
411
1484b5cc 412 csDiagramCommand* cmd = new csDiagramCommand(_T("Move"), (csDiagramDocument*)canvas->GetView()->GetDocument(),
1fc25a89
JS
413 new csCommandState(ID_CS_MOVE, newShape, GetShape()));
414
415 // Move line points
8552e6f0 416 wxNode* node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
1fc25a89
JS
417 while (node)
418 {
8552e6f0 419 wxShape* shape = (wxShape*) node->GetData();
1fc25a89
JS
420 // Only move the line point(s) if both ends move too
421 if (shape->IsKindOf(CLASSINFO(wxLineShape)) &&
422 ((wxLineShape*)shape)->GetTo()->Selected() && ((wxLineShape*)shape)->GetFrom()->Selected())
423 {
424 wxLineShape* lineShape = (wxLineShape*) shape;
425
8552e6f0 426 if (lineShape->GetLineControlPoints()->GetCount() > 2)
1fc25a89
JS
427 {
428 wxLineShape* newLineShape = (wxLineShape*) lineShape->CreateNewCopy();
429
8552e6f0 430 wxNode *node1 = newLineShape->GetLineControlPoints()->GetFirst();
1fc25a89
JS
431 while (node1)
432 {
8552e6f0 433 wxRealPoint *point = (wxRealPoint *)node1->GetData();
1fc25a89
JS
434 point->x += offsetX;
435 point->y += offsetY;
8552e6f0 436 node1 = node1->GetNext();
1fc25a89
JS
437 }
438 cmd->AddState(new csCommandState(ID_CS_MOVE_LINE_POINT, newLineShape, lineShape));
439 lineShape->Erase(dc);
440 }
441 }
8552e6f0 442 node = node->GetNext();
1fc25a89
JS
443 }
444
445 // Add other selected node shapes, if any
8552e6f0 446 node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
1fc25a89
JS
447 while (node)
448 {
8552e6f0 449 wxShape* shape = (wxShape*) node->GetData();
1fc25a89
JS
450 if (shape->Selected() && !shape->IsKindOf(CLASSINFO(wxLineShape)) && (shape != GetShape()))
451 {
452 wxShape* newShape2 = shape->CreateNewCopy();
453 newShape2->SetX(shape->GetX() + offsetX);
454 newShape2->SetY(shape->GetY() + offsetY);
455 cmd->AddState(new csCommandState(ID_CS_MOVE, newShape2, shape));
456 }
8552e6f0 457 node = node->GetNext();
1fc25a89
JS
458 }
459
460 canvas->GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd);
461}
462
463void csEvtHandler::OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
464{
465 wxShape* shape = GetShape();
466 csCanvas *canvas = (csCanvas *)GetShape()->GetCanvas();
467
468 if (shape->IsKindOf(CLASSINFO(wxLineShape)))
469 {
470 // TODO: Do/Undo support for line operations
471 ((wxLineShape*)shape)->wxLineShape::OnSizingEndDragLeft(pt, x, y, keys, attachment);
472#if 0
473 wxLineShape* lineShape = (wxLineShape*) shape;
474
475 wxLineControlPoint* lpt = (wxLineControlPoint*) pt;
476
477 wxClientDC dc(canvas);
478 canvas->PrepareDC(dc);
479
480 shape->SetDisableLabel(FALSE);
481
482 if (lpt->m_type == CONTROL_POINT_LINE)
483 {
484 canvas->Snap(&x, &y);
485
486 dc.SetLogicalFunction(wxCOPY);
487 lpt->SetX(x); lpt->SetY(y);
488 lpt->m_point->x = x; lpt->m_point->y = y;
489
490 this->OnMoveLink(dc);
491 }
492 if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM)
493 {
494 if (lpt->m_oldCursor)
495 canvas->SetCursor(lpt->m_oldCursor);
496 lineShape->Erase(dc);
497
498 lpt->SetX(x); lpt->SetY(y);
499
500 if (lineShape->GetFrom())
501 {
502 lineShape->GetFrom()->MoveLineToNewAttachment(dc, lineShape, x, y);
503 }
504 }
505 if (lpt->m_type == CONTROL_POINT_ENDPOINT_TO)
506 {
507 if (lpt->m_oldCursor)
508 canvas->SetCursor(lpt->m_oldCursor);
509
510 lpt->SetX(x); lpt->SetY(y);
511
512 if (lineShape->GetTo())
513 {
514 lineShape->GetTo()->MoveLineToNewAttachment(dc, lineShape, x, y);
515 }
516 }
517#endif
518 return;
519 }
520
521 wxClientDC dc(canvas);
522 canvas->PrepareDC(dc);
523
524 canvas->ReleaseMouse();
525 dc.SetLogicalFunction(wxCOPY);
526
527// shape->Erase(dc);
528/*
529 shape->Recompute();
530 shape->ResetControlPoints();
531 if (!pt->m_eraseObject)
532 shape->Show(FALSE);
533*/
534
535 wxShape* newShape = shape->CreateNewCopy();
536
537 if (newShape->IsKindOf(CLASSINFO(wxPolygonShape)))
538 {
539 wxPolygonControlPoint* ppt = (wxPolygonControlPoint*) pt;
540 newShape->SetSize(ppt->GetNewSize().x, ppt->GetNewSize().y);
541
542 ((wxPolygonShape *)newShape)->CalculateBoundingBox();
543 ((wxPolygonShape *)newShape)->CalculatePolygonCentre();
544 newShape->ResetControlPoints();
545 }
546 else
547 {
548 newShape->SetSize(pt->sm_controlPointDragEndWidth, pt->sm_controlPointDragEndHeight);
549 if (shape->GetCentreResize())
550 {
551 // Old position is fine
552 }
553 else
554 {
555 newShape->SetX(pt->sm_controlPointDragPosX);
556 newShape->SetY(pt->sm_controlPointDragPosY);
557 }
558 }
559
1484b5cc 560 csDiagramCommand* cmd = new csDiagramCommand(_T("Size"), (csDiagramDocument*)canvas->GetView()->GetDocument(),
1fc25a89
JS
561 new csCommandState(ID_CS_SIZE, newShape, shape));
562
563 canvas->GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd);
564
565}
566
1484b5cc 567void csEvtHandler::OnEndSize(double WXUNUSED(x), double WXUNUSED(y))
1fc25a89
JS
568{
569 wxClientDC dc(GetShape()->GetCanvas());
570 GetShape()->GetCanvas()->PrepareDC(dc);
571
572 GetShape()->FormatText(dc, m_label);
573}
574
575void csEvtHandler::OnChangeAttachment(int attachment, wxLineShape* line, wxList& ordering)
576{
577 csCanvas *canvas = (csCanvas *)GetShape()->GetCanvas();
578
579 // We actually submit two different states: one to change the ordering, and another
580 // to change the attachment for the line.
581 // Problem. If we refresh after the attachment change, we'll get a flicker.
582 // We really want to do both in a oner.
583
1484b5cc 584 csDiagramCommand* cmd = new csDiagramCommand(_T("Change attachment"), (csDiagramDocument*)canvas->GetView()->GetDocument());
1fc25a89
JS
585
586 wxLineShape* newLine = (wxLineShape*) line->CreateNewCopy();
587 if (line->GetTo() == GetShape())
588 newLine->SetAttachmentTo(attachment);
589 else
590 newLine->SetAttachmentFrom(attachment);
591
592 cmd->AddState(new csCommandState(ID_CS_CHANGE_LINE_ATTACHMENT, newLine, line));
593
594 // Change ordering
595 wxShape* newShape = GetShape()->CreateNewCopy();
596 newShape->ApplyAttachmentOrdering(ordering);
597
598 cmd->AddState(new csCommandState(ID_CS_CHANGE_LINE_ORDERING, newShape, GetShape()));
599
600 canvas->GetView()->GetDocument()->GetCommandProcessor()->Submit(cmd);
601}
602
1484b5cc 603void csEvtHandler::OnLeftDoubleClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment))
1fc25a89
JS
604{
605 EditProperties();
606}
607
608// Popup up a property dialog
609bool csEvtHandler::EditProperties()
610{
611 wxShape* shape = GetShape();
612
613 // For now, no line property editing
614 if (shape->IsKindOf(CLASSINFO(wxLineShape)))
615 return FALSE;
616
617 csDiagramView* view = ((csCanvas*)shape->GetCanvas())->GetView();
618
619 wxPanel* attributeDialog;
620 wxString attributeDialogName;
621 wxString title;
622
623 if (shape->IsKindOf(CLASSINFO(csThinRectangleShape)))
624 {
625 attributeDialog = new csThinRectangleDialog;
1484b5cc
VS
626 attributeDialogName = _T("thin_rectangle");
627 title = _T("Thin Rectangle Properties");
1fc25a89
JS
628 }
629 else if (shape->IsKindOf(CLASSINFO(csWideRectangleShape)))
630 {
631 attributeDialog = new csWideRectangleDialog;
1484b5cc
VS
632 attributeDialogName = _T("wide_rectangle");
633 title = _T("Wide Rectangle Properties");
1fc25a89
JS
634 }
635 else if (shape->IsKindOf(CLASSINFO(csTriangleShape)))
636 {
637 attributeDialog = new csTriangleDialog;
1484b5cc
VS
638 attributeDialogName = _T("triangle");
639 title = _T("Triangle Properties");
1fc25a89
JS
640 }
641 else if (shape->IsKindOf(CLASSINFO(csSemiCircleShape)))
642 {
643 attributeDialog = new csSemiCircleDialog;
1484b5cc
VS
644 attributeDialogName = _T("semi_circle");
645 title = _T("Semicircle Properties");
1fc25a89
JS
646 }
647 else if (shape->IsKindOf(CLASSINFO(csCircleShape)))
648 {
649 attributeDialog = new csCircleDialog;
1484b5cc
VS
650 attributeDialogName = _T("circle");
651 title = _T("Circle Properties");
1fc25a89
JS
652 }
653 else if (shape->IsKindOf(CLASSINFO(csCircleShadowShape)))
654 {
655 attributeDialog = new csCircleShadowDialog;
1484b5cc
VS
656 attributeDialogName = _T("circle_shadow");
657 title = _T("Circle Shadow Properties");
1fc25a89
JS
658 }
659 else if (shape->IsKindOf(CLASSINFO(csTextBoxShape)))
660 {
661 attributeDialog = new csTextBoxDialog;
1484b5cc
VS
662 attributeDialogName = _T("text_box");
663 title = _T("Text Box Properties");
1fc25a89
JS
664 }
665 else if (shape->IsKindOf(CLASSINFO(csGroupShape)))
666 {
667 attributeDialog = new csGroupDialog;
1484b5cc
VS
668 attributeDialogName = _T("group");
669 title = _T("Group Properties");
1fc25a89
JS
670 }
671 else if (shape->IsKindOf(CLASSINFO(csOctagonShape)))
672 {
673 attributeDialog = new csOctagonDialog;
1484b5cc
VS
674 attributeDialogName = _T("octagon");
675 title = _T("Octagon Properties");
1fc25a89
JS
676 }
677 else
678 {
1484b5cc 679 wxMessageBox(_T("Unrecognised shape."), _T("Studio"), wxICON_EXCLAMATION);
1fc25a89
JS
680 return FALSE;
681 }
682
683 csShapePropertiesDialog* dialog = new csShapePropertiesDialog(shape->GetCanvas()->GetParent(), title, attributeDialog, attributeDialogName);
684 dialog->GetGeneralPropertiesDialog()->SetShapeLabel(m_label);
685 if (dialog->ShowModal() == wxID_CANCEL)
686 {
687 dialog->Destroy();
688 return FALSE;
689 }
690
691 wxString newLabel = dialog->GetGeneralPropertiesDialog()->GetShapeLabel();
692 dialog->Destroy();
693
694 wxShape* newShape = shape->CreateNewCopy();
695
696 csEvtHandler* handler2 = (csEvtHandler *)newShape->GetEventHandler();
697 handler2->m_label = newLabel;
698
1484b5cc 699 view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand(_T("Edit properties"), (csDiagramDocument*) view->GetDocument(),
1fc25a89
JS
700 new csCommandState(ID_CS_EDIT_PROPERTIES, newShape, shape)));
701
702 return TRUE;
703}
704
705/*
706 * Diagram
707 */
708
709bool csDiagram::OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
710{
711 wxDiagram::OnShapeSave(db, shape, expr);
712 csEvtHandler *handler = (csEvtHandler *)shape.GetEventHandler();
1484b5cc 713 expr.AddAttributeValueString(_T("label"), handler->m_label);
1fc25a89
JS
714 return TRUE;
715}
716
717bool csDiagram::OnShapeLoad(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
718{
719 wxDiagram::OnShapeLoad(db, shape, expr);
1484b5cc
VS
720 wxString label = wxEmptyString;
721 expr.GetAttributeValue(_T("label"), label);
1fc25a89
JS
722 csEvtHandler *handler = new csEvtHandler(&shape, &shape, label);
723 shape.SetEventHandler(handler);
724
725 return TRUE;
726}
727
728IMPLEMENT_DYNAMIC_CLASS(csThinRectangleShape, wxDrawnShape)
729
730csThinRectangleShape::csThinRectangleShape()
731{
732 SetDrawnPen(wxBLACK_PEN);
733 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
734 SetDrawnBrush(brush);
735
736 double w = csSTANDARD_SHAPE_WIDTH/2;
737 double h = csSTANDARD_SHAPE_WIDTH;
738
8552e6f0 739 DrawRectangle(wxRect((int)(- w/2), (int)(- h/2), (int)(w), (int)(h)));
1fc25a89
JS
740 CalculateSize();
741
742 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
743 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
744 SetCentreResize(FALSE);
745}
746
747IMPLEMENT_DYNAMIC_CLASS(csWideRectangleShape, wxDrawnShape)
748
749csWideRectangleShape::csWideRectangleShape()
750{
751 SetDrawnPen(wxBLACK_PEN);
752 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
753 SetDrawnBrush(brush);
754
755 double w = csSTANDARD_SHAPE_WIDTH;
756 double h = w/2.0;
757
8552e6f0 758 DrawRoundedRectangle(wxRect((int)(- w/2), (int)(- h/2), (int)(w), (int)(h)), -0.3);
1fc25a89
JS
759 CalculateSize();
760
761 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
762 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
763 SetCentreResize(FALSE);
764}
765
766IMPLEMENT_DYNAMIC_CLASS(csTriangleShape, wxDrawnShape)
767
768csTriangleShape::csTriangleShape()
769{
770 SetDrawnPen(wxBLACK_PEN);
771 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
772 SetDrawnBrush(brush);
773
774 double w = csSTANDARD_SHAPE_WIDTH;
775 double h = (csSTANDARD_SHAPE_WIDTH*2.0)/3.0;
776
777 // Triangle, from top vertex
778 wxPoint* points = new wxPoint[3];
779
780
8552e6f0
MB
781 points[0] = wxPoint( 0 , (int)(- h / 2) );
782 points[1] = wxPoint( (int)(w / 2) , (int)(h / 2) );
783 points[2] = wxPoint( (int)(-w / 2), (int)(h / 2) );
1fc25a89
JS
784
785 DrawPolygon(3, points, oglMETAFLAGS_OUTLINE);
786
787 delete[] points;
788
789 // Add another triangle at the top for the black bit
790 SetDrawnBrush(wxBLACK_BRUSH);
791
792 points = new wxPoint[3];
793
794 // Calculate where the new points will be, using the proportions
795 // of the triangle.
796 double h1 = 8; // Height of little triangle.
797
798 /*
799 Formula: ((w/2) / h) = w1 / h1
800 w1 = ((w/2) / h) * h1;
801 */
802 double ratio = ((w/2.0) / h) ;
803 double w1 = ratio * h1;
804
805 points[0] = wxPoint(0 , (int) (- h / 2 ));
806 points[1] = wxPoint( (int) w1, (int) (- h / 2 + h1));
807 points[2] = wxPoint( (int) -w1, (int) (- h / 2 + h1));
808
809 DrawPolygon(3, points);
810
811 delete[] points;
812
813 CalculateSize();
814
815 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
816 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
817 SetCentreResize(FALSE);
818}
819
820IMPLEMENT_DYNAMIC_CLASS(csSemiCircleShape, wxDrawnShape)
821
822csSemiCircleShape::csSemiCircleShape()
823{
824 // Zero degrees
825 DrawAtAngle(oglDRAWN_ANGLE_0);
826
827 double w = csSTANDARD_SHAPE_WIDTH;
828 double h = w/2.0;
829
830 SetDrawnPen(wxTRANSPARENT_PEN);
831 SetDrawnBrush(wxTRANSPARENT_BRUSH);
832
833 // Draw a dummy rectangle that will be used for calculating the
834 // bounding box, since we can't calculate the bounding box for
835 // an arbitrary arc (not implemented)
836
8552e6f0 837 DrawRectangle(wxRect((int)(-w/2.0), (int)(-h/2.0), (int)(w), (int)(h)));
1fc25a89
JS
838
839 SetDrawnPen(wxBLACK_PEN);
840 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
841 SetDrawnBrush(brush);
842
8552e6f0
MB
843 DrawEllipticArc(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(2*h)), 0.0, 180.0);
844 DrawLine(wxPoint((int)(-w/2), (int)(h/2)), wxPoint((int)(w/2), (int)(h/2)));
1fc25a89
JS
845
846 CalculateSize();
847
848 /// 90 degrees
849
850 w = csSTANDARD_SHAPE_WIDTH/2;
851 h = csSTANDARD_SHAPE_WIDTH;
852
853 DrawAtAngle(oglDRAWN_ANGLE_90);
854
855 SetDrawnPen(wxTRANSPARENT_PEN);
856 SetDrawnBrush(wxTRANSPARENT_BRUSH);
857
8552e6f0 858 DrawRectangle(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(h)));
1fc25a89
JS
859
860 SetDrawnPen(wxBLACK_PEN);
861 SetDrawnBrush(brush);
862
8552e6f0
MB
863 DrawEllipticArc(wxRect((int)(-w/2 - w), (int)(-h/2), (int)(2*w), (int)(h)), 270.0, 90.0);
864 DrawLine(wxPoint((int)(-w/2), (int)(-h/2)), wxPoint((int)(-w/2), (int)(h/2)));
1fc25a89
JS
865
866 CalculateSize();
867
868 /// 180 degrees
869
870 DrawAtAngle(oglDRAWN_ANGLE_180);
871
872 w = csSTANDARD_SHAPE_WIDTH;
873 h = csSTANDARD_SHAPE_WIDTH/2;
874
875 SetDrawnPen(wxTRANSPARENT_PEN);
876 SetDrawnBrush(wxTRANSPARENT_BRUSH);
877
8552e6f0 878 DrawRectangle(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(h)));
1fc25a89
JS
879
880 SetDrawnPen(wxBLACK_PEN);
881 SetDrawnBrush(brush);
882
8552e6f0
MB
883 DrawEllipticArc(wxRect((int)(-w/2), (int)(-h/2 - h), (int)(w), (int)(2*h)), 180.0, 0.0);
884 DrawLine(wxPoint((int)(-w/2), (int)(-h/2)), wxPoint((int)(w/2), (int)(-h/2)));
1fc25a89
JS
885
886 CalculateSize();
887
888 /// 270 degrees
889
890 DrawAtAngle(oglDRAWN_ANGLE_270);
891
892 w = csSTANDARD_SHAPE_WIDTH/2;
893 h = csSTANDARD_SHAPE_WIDTH;
894
895 SetDrawnPen(wxTRANSPARENT_PEN);
896 SetDrawnBrush(wxTRANSPARENT_BRUSH);
897
8552e6f0 898 DrawRectangle(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(h)));
1fc25a89
JS
899
900 SetDrawnPen(wxBLACK_PEN);
901 SetDrawnBrush(brush);
902
8552e6f0
MB
903 DrawEllipticArc(wxRect((int)(-w/2), (int)(-h/2), (int)(2*w), (int)(h)), 90.0, 270.0);
904 DrawLine(wxPoint((int)(w/2),(int)(-h/2)), wxPoint((int)(w/2), (int)(h/2)));
1fc25a89
JS
905
906 CalculateSize();
907
908 // Reset to zero
909 DrawAtAngle(oglDRAWN_ANGLE_0);
910 CalculateSize();
911
912 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
913 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
914 SetCentreResize(FALSE);
915}
916
917IMPLEMENT_DYNAMIC_CLASS(csCircleShape, wxCircleShape)
918
919csCircleShape::csCircleShape()
920{
921 SetPen(wxBLACK_PEN);
922 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
923 SetBrush(brush);
924
925 SetSize(csSTANDARD_SHAPE_WIDTH*0.6, csSTANDARD_SHAPE_WIDTH*0.6);
926
927 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
928 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
929 SetCentreResize(FALSE);
930}
931
932IMPLEMENT_DYNAMIC_CLASS(csCircleShadowShape, wxCircleShape)
933
934csCircleShadowShape::csCircleShadowShape()
935{
936 SetPen(wxBLACK_PEN);
937 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
938 SetBrush(brush);
939
940 SetSize(csSTANDARD_SHAPE_WIDTH*0.6, csSTANDARD_SHAPE_WIDTH*0.6);
941
942 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
943 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
944 SetCentreResize(FALSE);
945 SetShadowMode(SHADOW_RIGHT);
946}
947
948IMPLEMENT_DYNAMIC_CLASS(csOctagonShape, wxPolygonShape)
949
950csOctagonShape::csOctagonShape()
951{
952 SetPen(wxBLACK_PEN);
953 SetBrush(wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID));
954
955 double w = csSTANDARD_SHAPE_WIDTH*0.5;
956 double h = csSTANDARD_SHAPE_WIDTH*0.5;
957
958 double prop = h/3.0;
959
960 wxList* points = new wxList;
961 points->Append((wxObject*) new wxRealPoint(-w/2.0 + prop, -h/2.0));
962 points->Append((wxObject*) new wxRealPoint(w/2.0 - prop, -h/2.0));
963 points->Append((wxObject*) new wxRealPoint(w/2.0, -h/2.0 + prop));
964 points->Append((wxObject*) new wxRealPoint(w/2.0, h/2.0 - prop));
965 points->Append((wxObject*) new wxRealPoint(w/2.0 - prop, h/2.0));
966 points->Append((wxObject*) new wxRealPoint(-w/2.0 + prop, h/2.0));
967 points->Append((wxObject*) new wxRealPoint(-w/2.0, h/2.0 - prop));
968 points->Append((wxObject*) new wxRealPoint(-w/2.0, -h/2.0 + prop));
969
970 Create(points);
971
972 SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
973 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
974 SetCentreResize(FALSE);
975}
976
977// This is a transparent shape for drawing around other shapes.
978IMPLEMENT_DYNAMIC_CLASS(csGroupShape, wxRectangleShape)
979
980csGroupShape::csGroupShape()
981{
1484b5cc 982 SetPen(wxThePenList->FindOrCreatePen(_T("BLACK"), 1, wxDOT));
1fc25a89
JS
983 SetBrush(wxTRANSPARENT_BRUSH);
984
985 SetSize(csSTANDARD_SHAPE_WIDTH, csSTANDARD_SHAPE_WIDTH);
986 SetCentreResize(FALSE);
987}
988
989void csGroupShape::OnDraw(wxDC& dc)
990{
991 wxRectangleShape::OnDraw(dc);
992}
993
994// Must modify the hit-test so it doesn't obscure shapes that are inside.
995bool csGroupShape::HitTest(double x, double y, int* attachment, double* distance)
996{
997 *attachment = 0;
998 *distance = 0.0;
999
1000 double width = 0.0, height = 0.0;
1001 GetBoundingBoxMin(&width, &height);
1002
1003 double x1 = GetX() - (width/2.0);
1004 double y1 = GetY() - (height/2.0);
1005 double x2 = GetX() + (width/2.0);
1006 double y2 = GetY() + (height/2.0);
1007
1008 double edgeTolerance = 4.0;
1009
1010 // Test each edge in turn
1011
1012 // Top/bottom edges
1013 if (x >= x1 && x <= x2)
1014 {
1015 if ((y >= y1 - edgeTolerance) && (y <= y1 + edgeTolerance))
1016 return TRUE;
1017 if ((y <= y2 + edgeTolerance) && (y >= y2 - edgeTolerance))
1018 return TRUE;
1019 }
1020 // Left/right edges
1021 if (y >= y1 && y <= y2)
1022 {
1023 if ((x >= x1 - edgeTolerance) && (x <= x1 + edgeTolerance))
1024 return TRUE;
1025 if ((x <= x2 + edgeTolerance) && (x >= x2 - edgeTolerance))
1026 return TRUE;
1027 }
1028
1029 return FALSE;
1030}
1031
1032IMPLEMENT_DYNAMIC_CLASS(csTextBoxShape, wxRectangleShape)
1033
1034csTextBoxShape::csTextBoxShape()
1035{
1036 SetPen(wxTRANSPARENT_PEN);
1037 SetBrush(wxTRANSPARENT_BRUSH);
1038
1039 SetSize(csSTANDARD_SHAPE_WIDTH, csSTANDARD_SHAPE_WIDTH/2.0);
1040
1041 SetAttachmentMode(ATTACHMENT_MODE_NONE);
1042 SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
1043 SetCentreResize(FALSE);
1044}
1045
1046IMPLEMENT_DYNAMIC_CLASS(csLineShape, wxLineShape)
1047
1048csLineShape::csLineShape()
1049{
1050}
1051
1484b5cc 1052bool csLineShape::OnMoveMiddleControlPoint(wxDC& WXUNUSED(dc), wxLineControlPoint* lpt, const wxRealPoint& pt)
1fc25a89
JS
1053{
1054 csDiagramView* view = ((csCanvas*)GetCanvas())->GetView();
1055
1056 // Temporarily set the new shape properties so we can copy it
1057 lpt->SetX(pt.x); lpt->SetY(pt.y);
1058 lpt->m_point->x = pt.x; lpt->m_point->y = pt.y;
1059
1060 wxLineShape* newShape = (wxLineShape*) this->CreateNewCopy();
1061
1062 // Now set them back again
1063 lpt->SetX(lpt->m_originalPos.x); lpt->SetY(lpt->m_originalPos.y);
1064 lpt->m_point->x = lpt->m_originalPos.x; lpt->m_point->y = lpt->m_originalPos.y;
1065
1484b5cc 1066 view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand(_T("Move line point"), (csDiagramDocument*) view->GetDocument(),
1fc25a89
JS
1067 new csCommandState(ID_CS_MOVE_LINE_POINT, newShape, this)));
1068
1069 return TRUE;
1070}
1071
1072wxLabelShape* csLineShape::OnCreateLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h)
1073{
1074 return new csLabelShape(parent, region, w, h);
1075}
1076
1077#if 0
1078bool csLineShape::OnLabelMovePre(wxDC& dc, wxLabelShape* labelShape, double x, double y, double old_x, double old_y, bool display)
1079{
1080 csDiagramView* view = ((csCanvas*)GetCanvas())->GetView();
1081
1082 wxLineShape* newShape = (wxLineShape*) this->CreateNewCopy();
1083
1084 wxLineShape::OnLabelMovePre(dc, labelShape, x, y, old_x, old_y, display);
1085
1086 view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand("Move label", (csDiagramDocument*) view->GetDocument(),
1087 new csCommandState(ID_CS_MOVE_LABEL, newShape, this)));
1088 return TRUE;
1089}
1090#endif
1091
1092IMPLEMENT_DYNAMIC_CLASS(csLabelShape, wxLabelShape)
1093
1094csLabelShape::csLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h):
1095 wxLabelShape(parent, region, w, h)
1096{
1097}
1098
1099// TODO: not sure how intercept normal behaviour (OnMovePre) to make
1100// label movement undo-able.
1101void csLabelShape::OnEndDragLeft(double x, double y, int keys, int attachment)
1102{
1103 wxLabelShape::OnEndDragLeft(x, y, keys, attachment);
1104}
1105
1106
1107// Menu for editing shapes
1108void studioShapeEditProc(wxMenu& menu, wxCommandEvent& event)
1109{
1110 wxShape* shape = (wxShape*) menu.GetClientData();
1111 csDiagramView* view = ((csCanvas*)shape->GetCanvas())->GetView();
1112
1113 switch (event.GetId())
1114 {
1115 case ID_CS_EDIT_PROPERTIES:
1116 {
1117 csEvtHandler* handler1 = (csEvtHandler *)shape->GetEventHandler();
1118 handler1->EditProperties();
1119#if 0
1120 csEvtHandler* handler1 = (csEvtHandler *)shape->GetEventHandler();
1121 csLabelEditingDialog* dialog = new csLabelEditingDialog(shape->GetCanvas()->GetParent());
1122 dialog->SetShapeLabel(handler1->m_label);
1123 if (dialog->ShowModal() == wxID_CANCEL)
1124 {
1125 dialog->Destroy();
1126 return;
1127 }
1128
1129 wxString newLabel = dialog->GetShapeLabel();
1130 dialog->Destroy();
1131
1132 wxShape* newShape = shape->CreateNewCopy();
1133
1134 csEvtHandler* handler2 = (csEvtHandler *)newShape->GetEventHandler();
1135 handler2->m_label = newLabel;
1136
1137 view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand("Edit label", (csDiagramDocument*) view->GetDocument(),
1138 new csCommandState(ID_CS_EDIT_LABEL, newShape, shape)));
1139#endif
1140 break;
1141 }
1142 case wxID_CUT:
1143 {
1144 wxList list;
1145 list.Append(shape);
1146 view->DoCut(list);
1147 break;
1148 }
1149 case ID_CS_ROTATE_CLOCKWISE:
1150 case ID_CS_ROTATE_ANTICLOCKWISE:
1151 {
1152 if (shape->IsKindOf(CLASSINFO(wxLineShape)))
1153 break;
1154
1155 double theta = shape->GetRotation();
1156 const double myPi = 3.1415926535897932384626433832795 ;
1157 double ninetyDegrees = myPi/2.0;
1158
1159 wxString opStr;
1160 if (event.GetId() == ID_CS_ROTATE_CLOCKWISE)
1161 {
1162 theta += ninetyDegrees;
1484b5cc 1163 opStr = _T("Rotate clockwise");
1fc25a89
JS
1164 }
1165 else
1166 {
1167 theta -= ninetyDegrees;
1484b5cc 1168 opStr = _T("Rotate anticlockwise");
1fc25a89
JS
1169 }
1170
1171 if (theta >= 2.0*myPi || theta < 0.0)
1172 theta = 0.0;
1173 wxShape* newShape = shape->CreateNewCopy();
1174 newShape->Rotate(0.0, 0.0, theta);
1175 wxList newShapes;
1176 wxList oldShapes;
1177 newShapes.Append(newShape);
1178 oldShapes.Append(shape);
1179 view->DoCmd(newShapes, oldShapes, event.GetId(), opStr);
1180 break;
1181 }
1182 default:
1183 break;
1184 }
1185}
1186
1187BEGIN_EVENT_TABLE(ShapeEditMenu, wxMenu)
1188 EVT_COMMAND_RANGE(1, 65000, wxEVT_COMMAND_MENU_SELECTED, ShapeEditMenu::OnCommand)
1189END_EVENT_TABLE()
1190
1191void ShapeEditMenu::OnCommand(wxCommandEvent& event)
1192{
1193 studioShapeEditProc(*this, event);
1194}
1195