]> git.saurik.com Git - wxWidgets.git/blame - contrib/samples/ogl/ogledit/doc.cpp
Removed every usage of obsolete wxTLW flags. 2.6 compatibility markup for them.
[wxWidgets.git] / contrib / samples / ogl / ogledit / doc.cpp
CommitLineData
1fc25a89 1/////////////////////////////////////////////////////////////////////////////
f4ec6bd2 2// Name: contrib/samples/ogl/ogledit/doc.cpp
1fc25a89
JS
3// Purpose: Implements document functionality in OGLEdit
4// Author: Julian Smart
5// Modified by:
6// Created: 12/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
2ba06d5a 9// Licence: wxWindows licence
1fc25a89
JS
10/////////////////////////////////////////////////////////////////////////////
11
1fc25a89 12// For compilers that support precompilation, includes "wx.h".
92a19c2e 13#include "wx/wxprec.h"
1fc25a89
JS
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
f4ec6bd2 20#include "wx/wx.h"
1fc25a89
JS
21#endif
22
f4ec6bd2 23#include "wx/ioswrap.h"
ed0e8cce 24
1fc25a89
JS
25#if !wxUSE_DOC_VIEW_ARCHITECTURE
26#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in wx_setup.h!
27#endif
28
1fc25a89
JS
29#include "ogledit.h"
30#include "doc.h"
31#include "view.h"
32
1fc25a89
JS
33IMPLEMENT_DYNAMIC_CLASS(DiagramDocument, wxDocument)
34
35DiagramDocument::DiagramDocument(void)
36{
37}
38
39DiagramDocument::~DiagramDocument(void)
40{
41}
42
43bool DiagramDocument::OnCloseDocument(void)
44{
9f13cedb
WS
45 diagram.DeleteAllShapes();
46 return true;
1fc25a89
JS
47}
48
49#if wxUSE_STD_IOSTREAM
dd107c50 50wxSTD ostream& DiagramDocument::SaveObject(wxSTD ostream& stream)
1fc25a89 51{
9f13cedb
WS
52#if wxUSE_PROLOGIO
53
54 wxDocument::SaveObject(stream);
55c91e8a 55
9f13cedb
WS
56 char buf[400];
57 (void) wxGetTempFileName("diag", buf);
1fc25a89 58
9f13cedb
WS
59 diagram.SaveFile(buf);
60 wxTransferFileToStream(buf, stream);
1fc25a89 61
9f13cedb
WS
62 wxRemoveFile(buf);
63
64#endif
55c91e8a 65
9f13cedb 66 return stream;
1fc25a89
JS
67}
68
dd107c50 69wxSTD istream& DiagramDocument::LoadObject(wxSTD istream& stream)
1fc25a89 70{
9f13cedb
WS
71#if wxUSE_PROLOGIO
72
73 wxDocument::LoadObject(stream);
1fc25a89 74
9f13cedb
WS
75 char buf[400];
76 (void) wxGetTempFileName("diag", buf);
1fc25a89 77
9f13cedb 78 wxTransferStreamToFile(stream, buf);
1fc25a89 79
9f13cedb
WS
80 diagram.DeleteAllShapes();
81 diagram.LoadFile(buf);
82 wxRemoveFile(buf);
83
84#endif
1fc25a89 85
9f13cedb 86 return stream;
1fc25a89
JS
87}
88#else
89
90wxOutputStream& DiagramDocument::SaveObject(wxOutputStream& stream)
91{
1dde66dd
JS
92#if wxUSE_PROLOGIO
93
9f13cedb
WS
94 wxDocument::SaveObject(stream);
95 wxChar buf[400];
96 (void) wxGetTempFileName(_T("diag"), buf);
1fc25a89 97
9f13cedb 98 diagram.SaveFile(buf);
1fc25a89 99
9f13cedb 100 wxTransferFileToStream(buf, stream);
1fc25a89 101
9f13cedb 102 wxRemoveFile(buf);
1dde66dd
JS
103
104#endif
1fc25a89 105
9f13cedb 106 return stream;
1fc25a89
JS
107}
108
109wxInputStream& DiagramDocument::LoadObject(wxInputStream& stream)
110{
1dde66dd 111#if wxUSE_PROLOGIO
9f13cedb 112 wxDocument::LoadObject(stream);
1fc25a89 113
9f13cedb
WS
114 wxChar buf[400];
115 (void) wxGetTempFileName(_T("diag"), buf);
1fc25a89 116
9f13cedb 117 wxTransferStreamToFile(stream, buf);
1fc25a89 118
9f13cedb
WS
119 diagram.DeleteAllShapes();
120 diagram.LoadFile(buf);
121 wxRemoveFile(buf);
1dde66dd 122#endif
1fc25a89 123
9f13cedb 124 return stream;
1fc25a89
JS
125}
126
127#endif
128
129/*
130 * Implementation of drawing command
131 */
132
1484b5cc 133DiagramCommand::DiagramCommand(const wxString& name, int command, DiagramDocument *ddoc, wxClassInfo *info, double xx, double yy,
9f13cedb
WS
134 bool sel, wxShape *theShape, wxShape *fs, wxShape *ts)
135 :wxCommand(true, name)
1fc25a89 136{
9f13cedb
WS
137 doc = ddoc;
138 cmd = command;
139 shape = theShape;
140 fromShape = fs;
141 toShape = ts;
142 shapeInfo = info;
143 shapeBrush = NULL;
144 shapePen = NULL;
145 x = xx;
146 y = yy;
147 selected = sel;
148 deleteShape = false;
1fc25a89
JS
149}
150
9f13cedb
WS
151DiagramCommand::DiagramCommand(const wxString& name, int command, DiagramDocument *ddoc, wxBrush *backgroundColour, wxShape *theShape)
152 :wxCommand(true, name)
1fc25a89 153{
9f13cedb
WS
154 doc = ddoc;
155 cmd = command;
156 shape = theShape;
157 fromShape = NULL;
158 toShape = NULL;
159 shapeInfo = NULL;
160 x = 0.0;
161 y = 0.0;
162 selected = false;
163 deleteShape = false;
164 shapeBrush = backgroundColour;
165 shapePen = NULL;
1fc25a89
JS
166}
167
9f13cedb
WS
168DiagramCommand::DiagramCommand(const wxString& name, int command, DiagramDocument *ddoc, const wxString& lab, wxShape *theShape)
169 :wxCommand(true, name)
1fc25a89 170{
9f13cedb
WS
171 doc = ddoc;
172 cmd = command;
173 shape = theShape;
174 fromShape = NULL;
175 toShape = NULL;
176 shapeInfo = NULL;
177 x = 0.0;
178 y = 0.0;
179 selected = false;
180 deleteShape = false;
181 shapeBrush = NULL;
182 shapePen = NULL;
183 shapeLabel = lab;
1fc25a89
JS
184}
185
186DiagramCommand::~DiagramCommand(void)
187{
188 if (shape && deleteShape)
189 {
190 shape->SetCanvas(NULL);
191 delete shape;
192 }
193}
194
195bool DiagramCommand::Do(void)
196{
197 switch (cmd)
198 {
cecdcad1 199 case wxID_CUT:
1fc25a89
JS
200 {
201 if (shape)
202 {
2ba06d5a 203 deleteShape = true;
55c91e8a 204
2ba06d5a 205 shape->Select(false);
55c91e8a 206
1fc25a89
JS
207 // Generate commands to explicitly remove each connected line.
208 RemoveLines(shape);
55c91e8a 209
1fc25a89
JS
210 doc->GetDiagram()->RemoveShape(shape);
211 if (shape->IsKindOf(CLASSINFO(wxLineShape)))
212 {
213 wxLineShape *lineShape = (wxLineShape *)shape;
214 fromShape = lineShape->GetFrom();
215 toShape = lineShape->GetTo();
216 }
217 shape->Unlink();
55c91e8a 218
2ba06d5a 219 doc->Modify(true);
1fc25a89
JS
220 doc->UpdateAllViews();
221 }
222
223 break;
224 }
225 case OGLEDIT_ADD_SHAPE:
226 {
8552e6f0 227 wxShape *theShape;
1fc25a89
JS
228 if (shape)
229 theShape = shape; // Saved from undoing the shape
230 else
231 {
232 theShape = (wxShape *)shapeInfo->CreateObject();
233 theShape->AssignNewIds();
1484b5cc 234 theShape->SetEventHandler(new MyEvtHandler(theShape, theShape, wxEmptyString));
2ba06d5a 235 theShape->SetCentreResize(false);
1fc25a89
JS
236 theShape->SetPen(wxBLACK_PEN);
237 theShape->SetBrush(wxCYAN_BRUSH);
55c91e8a 238
1fc25a89
JS
239 theShape->SetSize(60, 60);
240 }
241 doc->GetDiagram()->AddShape(theShape);
2ba06d5a 242 theShape->Show(true);
1fc25a89
JS
243
244 wxClientDC dc(theShape->GetCanvas());
245 theShape->GetCanvas()->PrepareDC(dc);
246
247 theShape->Move(dc, x, y);
55c91e8a 248
1fc25a89 249 shape = theShape;
2ba06d5a 250 deleteShape = false;
1fc25a89 251
2ba06d5a 252 doc->Modify(true);
1fc25a89
JS
253 doc->UpdateAllViews();
254 break;
255 }
256 case OGLEDIT_ADD_LINE:
257 {
8552e6f0 258 wxShape *theShape;
1fc25a89
JS
259 if (shape)
260 theShape = shape; // Saved from undoing the line
261 else
262 {
263 theShape = (wxShape *)shapeInfo->CreateObject();
264 theShape->AssignNewIds();
1484b5cc 265 theShape->SetEventHandler(new MyEvtHandler(theShape, theShape, wxEmptyString));
1fc25a89
JS
266 theShape->SetPen(wxBLACK_PEN);
267 theShape->SetBrush(wxRED_BRUSH);
268
269 wxLineShape *lineShape = (wxLineShape *)theShape;
270
271 // Yes, you can have more than 2 control points, in which case
272 // it becomes a multi-segment line.
273 lineShape->MakeLineControlPoints(2);
1484b5cc 274 lineShape->AddArrow(ARROW_ARROW, ARROW_POSITION_END, 10.0, 0.0, _T("Normal arrowhead"));
1fc25a89 275 }
55c91e8a 276
1fc25a89 277 doc->GetDiagram()->AddShape(theShape);
55c91e8a 278
1fc25a89 279 fromShape->AddLine((wxLineShape *)theShape, toShape);
55c91e8a 280
2ba06d5a 281 theShape->Show(true);
1fc25a89
JS
282
283 wxClientDC dc(theShape->GetCanvas());
284 theShape->GetCanvas()->PrepareDC(dc);
285
286 // It won't get drawn properly unless you move both
287 // connected images
288 fromShape->Move(dc, fromShape->GetX(), fromShape->GetY());
289 toShape->Move(dc, toShape->GetX(), toShape->GetY());
55c91e8a 290
1fc25a89 291 shape = theShape;
2ba06d5a 292 deleteShape = false;
1fc25a89 293
2ba06d5a 294 doc->Modify(true);
1fc25a89
JS
295 doc->UpdateAllViews();
296 break;
297 }
298 case OGLEDIT_CHANGE_BACKGROUND_COLOUR:
299 {
300 if (shape)
301 {
302 wxClientDC dc(shape->GetCanvas());
303 shape->GetCanvas()->PrepareDC(dc);
304
305 wxBrush *oldBrush = shape->GetBrush();
306 shape->SetBrush(shapeBrush);
307 shapeBrush = oldBrush;
308 shape->Draw(dc);
55c91e8a 309
2ba06d5a 310 doc->Modify(true);
1fc25a89
JS
311 doc->UpdateAllViews();
312 }
313
314 break;
315 }
316 case OGLEDIT_EDIT_LABEL:
317 {
318 if (shape)
319 {
320 MyEvtHandler *myHandler = (MyEvtHandler *)shape->GetEventHandler();
321 wxString oldLabel(myHandler->label);
322 myHandler->label = shapeLabel;
323 shapeLabel = oldLabel;
324
325 wxClientDC dc(shape->GetCanvas());
326 shape->GetCanvas()->PrepareDC(dc);
327
1484b5cc 328 shape->FormatText(dc, /* (char*) (const char*) */ myHandler->label);
1fc25a89 329 shape->Draw(dc);
55c91e8a 330
2ba06d5a 331 doc->Modify(true);
1fc25a89
JS
332 doc->UpdateAllViews();
333 }
334
335 break;
336 }
337 }
2ba06d5a 338 return true;
1fc25a89
JS
339}
340
341bool DiagramCommand::Undo(void)
342{
343 switch (cmd)
344 {
cecdcad1 345 case wxID_CUT:
1fc25a89
JS
346 {
347 if (shape)
348 {
349 doc->GetDiagram()->AddShape(shape);
2ba06d5a 350 shape->Show(true);
1fc25a89
JS
351
352 if (shape->IsKindOf(CLASSINFO(wxLineShape)))
353 {
354 wxLineShape *lineShape = (wxLineShape *)shape;
355
356 fromShape->AddLine(lineShape, toShape);
357 }
358 if (selected)
2ba06d5a 359 shape->Select(true);
1fc25a89 360
2ba06d5a 361 deleteShape = false;
1fc25a89 362 }
2ba06d5a 363 doc->Modify(true);
1fc25a89
JS
364 doc->UpdateAllViews();
365 break;
366 }
367 case OGLEDIT_ADD_SHAPE:
368 case OGLEDIT_ADD_LINE:
369 {
370 if (shape)
371 {
372 wxClientDC dc(shape->GetCanvas());
373 shape->GetCanvas()->PrepareDC(dc);
374
2ba06d5a 375 shape->Select(false, &dc);
1fc25a89
JS
376 doc->GetDiagram()->RemoveShape(shape);
377 shape->Unlink();
2ba06d5a 378 deleteShape = true;
1fc25a89 379 }
2ba06d5a 380 doc->Modify(true);
1fc25a89
JS
381 doc->UpdateAllViews();
382 break;
383 }
384 case OGLEDIT_CHANGE_BACKGROUND_COLOUR:
385 {
386 if (shape)
387 {
388 wxClientDC dc(shape->GetCanvas());
389 shape->GetCanvas()->PrepareDC(dc);
390
391 wxBrush *oldBrush = shape->GetBrush();
392 shape->SetBrush(shapeBrush);
393 shapeBrush = oldBrush;
394 shape->Draw(dc);
55c91e8a 395
2ba06d5a 396 doc->Modify(true);
1fc25a89
JS
397 doc->UpdateAllViews();
398 }
399 break;
400 }
401 case OGLEDIT_EDIT_LABEL:
402 {
403 if (shape)
404 {
405 MyEvtHandler *myHandler = (MyEvtHandler *)shape->GetEventHandler();
406 wxString oldLabel(myHandler->label);
407 myHandler->label = shapeLabel;
408 shapeLabel = oldLabel;
409
410 wxClientDC dc(shape->GetCanvas());
411 shape->GetCanvas()->PrepareDC(dc);
412
1484b5cc 413 shape->FormatText(dc, /* (char*) (const char*) */ myHandler->label);
1fc25a89 414 shape->Draw(dc);
55c91e8a 415
2ba06d5a 416 doc->Modify(true);
1fc25a89
JS
417 doc->UpdateAllViews();
418 }
419
420 break;
421 }
422 }
2ba06d5a 423 return true;
1fc25a89
JS
424}
425
426// Remove each individual line connected to a shape by sending a command.
427void DiagramCommand::RemoveLines(wxShape *shape)
428{
36ca94a2 429 wxObjectList::compatibility_iterator node = shape->GetLines().GetFirst();
1fc25a89
JS
430 while (node)
431 {
8552e6f0 432 wxLineShape *line = (wxLineShape *)node->GetData();
cecdcad1 433 doc->GetCommandProcessor()->Submit(new DiagramCommand(_T("Cut"), wxID_CUT, doc, NULL, 0.0, 0.0, line->Selected(), line));
55c91e8a 434
8552e6f0 435 node = shape->GetLines().GetFirst();
1fc25a89
JS
436 }
437}
438
439/*
440 * MyEvtHandler: an event handler class for all shapes
441 */
55c91e8a 442
1484b5cc 443void MyEvtHandler::OnLeftClick(double WXUNUSED(x), double WXUNUSED(y), int keys, int WXUNUSED(attachment))
1fc25a89
JS
444{
445 wxClientDC dc(GetShape()->GetCanvas());
446 GetShape()->GetCanvas()->PrepareDC(dc);
447
448 if (keys == 0)
449 {
450 // Selection is a concept the library knows about
451 if (GetShape()->Selected())
452 {
2ba06d5a 453 GetShape()->Select(false, &dc);
1fc25a89
JS
454 GetShape()->GetCanvas()->Redraw(dc); // Redraw because bits of objects will be are missing
455 }
456 else
457 {
458 // Ensure no other shape is selected, to simplify Undo/Redo code
2ba06d5a 459 bool redraw = false;
36ca94a2 460 wxObjectList::compatibility_iterator node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
1fc25a89
JS
461 while (node)
462 {
8552e6f0 463 wxShape *eachShape = (wxShape *)node->GetData();
1fc25a89
JS
464 if (eachShape->GetParent() == NULL)
465 {
466 if (eachShape->Selected())
467 {
2ba06d5a
WS
468 eachShape->Select(false, &dc);
469 redraw = true;
1fc25a89
JS
470 }
471 }
8552e6f0 472 node = node->GetNext();
1fc25a89 473 }
2ba06d5a 474 GetShape()->Select(true, &dc);
1fc25a89
JS
475 if (redraw)
476 GetShape()->GetCanvas()->Redraw(dc);
477 }
478 }
479 else if (keys & KEY_CTRL)
480 {
481 // Do something for CONTROL
482 }
483 else
484 {
d96cdd4a 485#if wxUSE_STATUSBAR
1fc25a89 486 wxGetApp().frame->SetStatusText(label);
d96cdd4a 487#endif // wxUSE_STATUSBAR
1fc25a89
JS
488 }
489}
490
491/*
492 * Implement connection of two shapes by right-dragging between them.
493 */
494
1484b5cc 495void MyEvtHandler::OnBeginDragRight(double x, double y, int WXUNUSED(keys), int attachment)
1fc25a89
JS
496{
497 // Force attachment to be zero for now. Eventually we can deal with
498 // the actual attachment point, e.g. a rectangle side if attachment mode is on.
499 attachment = 0;
55c91e8a 500
1fc25a89
JS
501 wxClientDC dc(GetShape()->GetCanvas());
502 GetShape()->GetCanvas()->PrepareDC(dc);
503
55c91e8a 504 wxPen dottedPen(*wxBLACK, 1, wxDOT);
1fc25a89
JS
505 dc.SetLogicalFunction(OGLRBLF);
506 dc.SetPen(dottedPen);
507 double xp, yp;
508 GetShape()->GetAttachmentPosition(attachment, &xp, &yp);
509 dc.DrawLine((long) xp, (long) yp, (long) x, (long) y);
510 GetShape()->GetCanvas()->CaptureMouse();
511}
512
1484b5cc 513void MyEvtHandler::OnDragRight(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int attachment)
1fc25a89
JS
514{
515 // Force attachment to be zero for now
516 attachment = 0;
517
518 wxClientDC dc(GetShape()->GetCanvas());
519 GetShape()->GetCanvas()->PrepareDC(dc);
520
55c91e8a 521 wxPen dottedPen(*wxBLACK, 1, wxDOT);
1fc25a89
JS
522 dc.SetLogicalFunction(OGLRBLF);
523 dc.SetPen(dottedPen);
524 double xp, yp;
525 GetShape()->GetAttachmentPosition(attachment, &xp, &yp);
526 dc.DrawLine((long) xp, (long) yp, (long) x, (long) y);
527}
528
1484b5cc 529void MyEvtHandler::OnEndDragRight(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
1fc25a89
JS
530{
531 GetShape()->GetCanvas()->ReleaseMouse();
532 MyCanvas *canvas = (MyCanvas *)GetShape()->GetCanvas();
533
534 // Check if we're on an object
535 int new_attachment;
536 wxShape *otherShape = canvas->FindFirstSensitiveShape(x, y, &new_attachment, OP_DRAG_RIGHT);
55c91e8a 537
1fc25a89
JS
538 if (otherShape && !otherShape->IsKindOf(CLASSINFO(wxLineShape)))
539 {
540 canvas->view->GetDocument()->GetCommandProcessor()->Submit(
1484b5cc 541 new DiagramCommand(_T("wxLineShape"), OGLEDIT_ADD_LINE, (DiagramDocument *)canvas->view->GetDocument(), CLASSINFO(wxLineShape),
2ba06d5a 542 0.0, 0.0, false, NULL, GetShape(), otherShape));
1fc25a89
JS
543 }
544}
545
1484b5cc 546void MyEvtHandler::OnEndSize(double WXUNUSED(x), double WXUNUSED(y))
1fc25a89
JS
547{
548 wxClientDC dc(GetShape()->GetCanvas());
549 GetShape()->GetCanvas()->PrepareDC(dc);
550
1484b5cc 551 GetShape()->FormatText(dc, /* (char*) (const char*) */ label);
1fc25a89
JS
552}
553
554/*
555 * Diagram
556 */
1dde66dd
JS
557
558#if wxUSE_PROLOGIO
55c91e8a 559
1fc25a89
JS
560bool MyDiagram::OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
561{
562 wxDiagram::OnShapeSave(db, shape, expr);
563 MyEvtHandler *handler = (MyEvtHandler *)shape.GetEventHandler();
1484b5cc 564 expr.AddAttributeValueString(_T("label"), handler->label);
2ba06d5a 565 return true;
1fc25a89
JS
566}
567
568bool MyDiagram::OnShapeLoad(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
569{
570 wxDiagram::OnShapeLoad(db, shape, expr);
1484b5cc
VS
571 wxChar *label = NULL;
572 expr.AssignAttributeValue(_T("label"), &label);
1fc25a89
JS
573 MyEvtHandler *handler = new MyEvtHandler(&shape, &shape, wxString(label));
574 shape.SetEventHandler(handler);
55c91e8a 575
1fc25a89
JS
576 if (label)
577 delete[] label;
2ba06d5a 578 return true;
1fc25a89
JS
579}
580
1dde66dd
JS
581#endif
582
1fc25a89
JS
583/*
584 * New shapes
585 */
586
587IMPLEMENT_DYNAMIC_CLASS(wxRoundedRectangleShape, wxRectangleShape)
588
589wxRoundedRectangleShape::wxRoundedRectangleShape(double w, double h):
590 wxRectangleShape(w, h)
591{
592 // 0.3 of the smaller rectangle dimension
593 SetCornerRadius((double) -0.3);
594}
595
596IMPLEMENT_DYNAMIC_CLASS(wxDiamondShape, wxPolygonShape)
597
598wxDiamondShape::wxDiamondShape(double w, double h):
599 wxPolygonShape()
600{
601 // wxPolygonShape::SetSize relies on the shape having non-zero
602 // size initially.
603 if (w == 0.0)
604 w = 60.0;
605 if (h == 0.0)
606 h = 60.0;
55c91e8a 607
1fc25a89
JS
608 wxList *thePoints = new wxList;
609 wxRealPoint *point = new wxRealPoint(0.0, (-h/2.0));
610 thePoints->Append((wxObject*) point);
611
612 point = new wxRealPoint((w/2.0), 0.0);
613 thePoints->Append((wxObject*) point);
614
615 point = new wxRealPoint(0.0, (h/2.0));
616 thePoints->Append((wxObject*) point);
617
618 point = new wxRealPoint((-w/2.0), 0.0);
619 thePoints->Append((wxObject*) point);
620
621 Create(thePoints);
622}