~ubuntu-branches/ubuntu/utopic/pgadmin3/utopic-proposed

« back to all changes in this revision

Viewing changes to pgadmin/ogl/composit.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2011-06-07 23:03:54 UTC
  • mfrom: (1.3.1 upstream) (13 sid)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20110607230354-3td4j9y71u4ahcvj
Tags: 1.14.0~beta1-1
* New upstream development release, adding Build-Depends on
  postgresql-server-dev-all >= 117~.
* Add Build-Depends on quilt, (un)patch to debian/rules and patch for fixing
  the include for kwlist.h in pgadmin/db/keywords.c.
* Add pg_config --includedir-server output to CPPFLAGS.
* Remove unrecognized configure options: --with-wx-config,
  --with-pgsql-include, --enable-gtk2, --enable-unicode.
* Clean up manually the files that are left behind after the broken
  distclean.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// pgAdmin III - PostgreSQL Tools
 
4
//
 
5
// Portions Copyright (C) 1998 - 2011, Julian Smart
 
6
// Portions Copyright (C) 2011, The pgAdmin Development Team
 
7
// This software is released under the PostgreSQL Licence
 
8
//
 
9
// composit.cpp - Composite OGL class
 
10
//
 
11
//////////////////////////////////////////////////////////////////////////
 
12
 
 
13
#include "pgAdmin3.h"
 
14
 
 
15
#include "ogl/ogl.h"
 
16
 
 
17
#if wxUSE_PROLOGIO
 
18
// Sometimes, objects need to access the whole database to
 
19
// construct themselves.
 
20
wxExprDatabase *GlobalwxExprDatabase = NULL;
 
21
#endif
 
22
 
 
23
/*
 
24
 * Division control point
 
25
 */
 
26
 
 
27
class wxDivisionControlPoint: public wxControlPoint
 
28
{
 
29
        DECLARE_DYNAMIC_CLASS(wxDivisionControlPoint)
 
30
public:
 
31
        wxDivisionControlPoint() {}
 
32
        wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type);
 
33
        ~wxDivisionControlPoint();
 
34
 
 
35
        void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0);
 
36
        void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0);
 
37
        void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0);
 
38
};
 
39
 
 
40
IMPLEMENT_DYNAMIC_CLASS(wxDivisionControlPoint, wxControlPoint)
 
41
 
 
42
/*
 
43
 * Composite object
 
44
 *
 
45
 */
 
46
 
 
47
IMPLEMENT_DYNAMIC_CLASS(wxCompositeShape, wxRectangleShape)
 
48
 
 
49
wxCompositeShape::wxCompositeShape(): wxRectangleShape(10.0, 10.0)
 
50
{
 
51
//  selectable = FALSE;
 
52
        m_oldX = m_xpos;
 
53
        m_oldY = m_ypos;
 
54
}
 
55
 
 
56
wxCompositeShape::~wxCompositeShape()
 
57
{
 
58
        wxNode *node = m_constraints.GetFirst();
 
59
        while (node)
 
60
        {
 
61
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
62
                delete constraint;
 
63
                node = node->GetNext();
 
64
        }
 
65
        node = m_children.GetFirst();
 
66
        while (node)
 
67
        {
 
68
                wxShape *object = (wxShape *)node->GetData();
 
69
                wxNode *next = node->GetNext();
 
70
                object->Unlink();
 
71
                delete object;
 
72
                node = next;
 
73
        }
 
74
}
 
75
 
 
76
void wxCompositeShape::OnDraw(wxDC &dc)
 
77
{
 
78
        double x1 = (double)(m_xpos - m_width / 2.0);
 
79
        double y1 = (double)(m_ypos - m_height / 2.0);
 
80
 
 
81
        if (m_shadowMode != SHADOW_NONE)
 
82
        {
 
83
                if (m_shadowBrush)
 
84
                        dc.SetBrush(* m_shadowBrush);
 
85
                dc.SetPen(* g_oglTransparentPen);
 
86
 
 
87
                if (m_cornerRadius != 0.0)
 
88
                        dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY),
 
89
                                                WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
 
90
                else
 
91
                        dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height));
 
92
        }
 
93
}
 
94
 
 
95
void wxCompositeShape::OnDrawContents(wxDC &dc)
 
96
{
 
97
        wxNode *node = m_children.GetFirst();
 
98
        while (node)
 
99
        {
 
100
                wxShape *object = (wxShape *)node->GetData();
 
101
                object->Draw(dc);
 
102
                object->DrawLinks(dc);
 
103
                node = node->GetNext();
 
104
        }
 
105
        wxShape::OnDrawContents(dc);
 
106
}
 
107
 
 
108
bool wxCompositeShape::OnMovePre(double x, double y, double oldx, double oldy, bool display)
 
109
{
 
110
        double diffX = x - oldx;
 
111
        double diffY = y - oldy;
 
112
        wxNode *node = m_children.GetFirst();
 
113
        while (node)
 
114
        {
 
115
                wxShape *object = (wxShape *)node->GetData();
 
116
 
 
117
                object->Move(object->GetX() + diffX, object->GetY() + diffY, display);
 
118
 
 
119
                node = node->GetNext();
 
120
        }
 
121
        return TRUE;
 
122
}
 
123
 
 
124
static double objectStartX = 0.0;
 
125
static double objectStartY = 0.0;
 
126
 
 
127
void wxCompositeShape::OnDragLeft(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
 
128
{
 
129
        double xx = x;
 
130
        double yy = y;
 
131
        m_canvas->Snap(&xx, &yy);
 
132
        double offsetX = xx - objectStartX;
 
133
        double offsetY = yy - objectStartY;
 
134
 
 
135
        wxClientDC dc(GetCanvas());
 
136
        GetCanvas()->PrepareDC(dc);
 
137
 
 
138
        dc.SetLogicalFunction(OGLRBLF);
 
139
        wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
 
140
        dc.SetPen(dottedPen);
 
141
        dc.SetBrush((* wxTRANSPARENT_BRUSH));
 
142
 
 
143
        GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight());
 
144
//  wxShape::OnDragLeft(draw, x, y, keys, attachment);
 
145
}
 
146
 
 
147
void wxCompositeShape::OnBeginDragLeft(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
 
148
{
 
149
        objectStartX = x;
 
150
        objectStartY = y;
 
151
 
 
152
        wxClientDC dc(GetCanvas());
 
153
        GetCanvas()->PrepareDC(dc);
 
154
 
 
155
        Erase();
 
156
 
 
157
        dc.SetLogicalFunction(OGLRBLF);
 
158
 
 
159
        wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
 
160
        dc.SetPen(dottedPen);
 
161
        dc.SetBrush((* wxTRANSPARENT_BRUSH));
 
162
        m_canvas->CaptureMouse();
 
163
 
 
164
        double xx = x;
 
165
        double yy = y;
 
166
        m_canvas->Snap(&xx, &yy);
 
167
        double offsetX = xx - objectStartX;
 
168
        double offsetY = yy - objectStartY;
 
169
 
 
170
        GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight());
 
171
 
 
172
//  wxShape::OnBeginDragLeft(x, y, keys, attachment);
 
173
}
 
174
 
 
175
void wxCompositeShape::OnEndDragLeft(double x, double y, int keys, int WXUNUSED(attachment))
 
176
{
 
177
//  wxShape::OnEndDragLeft(x, y, keys, attachment);
 
178
 
 
179
        wxClientDC dc(GetCanvas());
 
180
        GetCanvas()->PrepareDC(dc);
 
181
 
 
182
        m_canvas->ReleaseMouse();
 
183
 
 
184
        if (!m_draggable)
 
185
        {
 
186
                if (m_parent) m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, 0);
 
187
                return;
 
188
        }
 
189
 
 
190
        dc.SetLogicalFunction(wxCOPY);
 
191
        double xx = x;
 
192
        double yy = y;
 
193
        m_canvas->Snap(&xx, &yy);
 
194
        double offsetX = xx - objectStartX;
 
195
        double offsetY = yy - objectStartY;
 
196
 
 
197
        Move(GetX() + offsetX, GetY() + offsetY);
 
198
 
 
199
        if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
 
200
}
 
201
 
 
202
void wxCompositeShape::OnRightClick(double x, double y, int keys, int WXUNUSED(attachment))
 
203
{
 
204
        // If we get a ctrl-right click, this means send the message to
 
205
        // the division, so we can invoke a user interface for dealing with regions.
 
206
        if (keys & KEY_CTRL)
 
207
        {
 
208
                wxNode *node = m_divisions.GetFirst();
 
209
                while (node)
 
210
                {
 
211
                        wxDivisionShape *division = (wxDivisionShape *)node->GetData();
 
212
                        wxNode *next = node->GetNext();
 
213
                        int attach = 0;
 
214
                        double dist = 0.0;
 
215
                        if (division->HitTest(x, y, &attach, &dist))
 
216
                        {
 
217
                                division->GetEventHandler()->OnRightClick(x, y, keys, attach);
 
218
                                node = NULL;
 
219
                        }
 
220
                        if (node)
 
221
                                node = next;
 
222
                }
 
223
        }
 
224
}
 
225
 
 
226
void wxCompositeShape::SetSize(double w, double h, bool recursive)
 
227
{
 
228
        SetAttachmentSize(w, h);
 
229
 
 
230
        double xScale = (double)(w / (wxMax(1.0, GetWidth())));
 
231
        double yScale = (double)(h / (wxMax(1.0, GetHeight())));
 
232
 
 
233
        m_width = w;
 
234
        m_height = h;
 
235
 
 
236
        if (!recursive) return;
 
237
 
 
238
        wxNode *node = m_children.GetFirst();
 
239
 
 
240
        wxClientDC dc(GetCanvas());
 
241
        GetCanvas()->PrepareDC(dc);
 
242
 
 
243
        double xBound, yBound;
 
244
        while (node)
 
245
        {
 
246
                wxShape *object = (wxShape *)node->GetData();
 
247
 
 
248
                // Scale the position first
 
249
                double newX = (double)(((object->GetX() - GetX()) * xScale) + GetX());
 
250
                double newY = (double)(((object->GetY() - GetY()) * yScale) + GetY());
 
251
                object->Show(FALSE);
 
252
                object->Move(newX, newY);
 
253
                object->Show(TRUE);
 
254
 
 
255
                // Now set the scaled size
 
256
                object->GetBoundingBoxMin(&xBound, &yBound);
 
257
                object->SetSize(object->GetFixedWidth() ? xBound : xScale * xBound,
 
258
                                object->GetFixedHeight() ? yBound : yScale * yBound);
 
259
 
 
260
                node = node->GetNext();
 
261
        }
 
262
        SetDefaultRegionSize();
 
263
}
 
264
 
 
265
void wxCompositeShape::AddChild(wxShape *child, wxShape *addAfter)
 
266
{
 
267
        m_children.Append(child);
 
268
        child->SetParent(this);
 
269
        if (m_canvas)
 
270
        {
 
271
                // Ensure we add at the right position
 
272
                if (addAfter)
 
273
                        child->RemoveFromCanvas(m_canvas);
 
274
                child->AddToCanvas(m_canvas, addAfter);
 
275
        }
 
276
}
 
277
 
 
278
void wxCompositeShape::RemoveChild(wxShape *child)
 
279
{
 
280
        m_children.DeleteObject(child);
 
281
        m_divisions.DeleteObject(child);
 
282
        RemoveChildFromConstraints(child);
 
283
        child->SetParent(NULL);
 
284
}
 
285
 
 
286
void wxCompositeShape::DeleteConstraintsInvolvingChild(wxShape *child)
 
287
{
 
288
        wxNode *node = m_constraints.GetFirst();
 
289
        while (node)
 
290
        {
 
291
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
292
                wxNode *nextNode = node->GetNext();
 
293
 
 
294
                if ((constraint->m_constrainingObject == child) ||
 
295
                        constraint->m_constrainedObjects.Member(child))
 
296
                {
 
297
                        delete constraint;
 
298
                        delete node;
 
299
                }
 
300
                node = nextNode;
 
301
        }
 
302
}
 
303
 
 
304
void wxCompositeShape::RemoveChildFromConstraints(wxShape *child)
 
305
{
 
306
        wxNode *node = m_constraints.GetFirst();
 
307
        while (node)
 
308
        {
 
309
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
310
                wxNode *nextNode = node->GetNext();
 
311
 
 
312
                if (constraint->m_constrainedObjects.Member(child))
 
313
                        constraint->m_constrainedObjects.DeleteObject(child);
 
314
                if (constraint->m_constrainingObject == child)
 
315
                        constraint->m_constrainingObject = NULL;
 
316
 
 
317
                // Delete the constraint if no participants left
 
318
                if (!constraint->m_constrainingObject)
 
319
                {
 
320
                        delete constraint;
 
321
                        delete node;
 
322
                }
 
323
 
 
324
                node = nextNode;
 
325
        }
 
326
}
 
327
 
 
328
void wxCompositeShape::Copy(wxShape &copy)
 
329
{
 
330
        wxRectangleShape::Copy(copy);
 
331
 
 
332
        wxASSERT( copy.IsKindOf(CLASSINFO(wxCompositeShape)) ) ;
 
333
 
 
334
        wxCompositeShape &compositeCopy = (wxCompositeShape &) copy;
 
335
 
 
336
        // Associate old and new copies for compositeCopying constraints and division geometry
 
337
        oglObjectCopyMapping.Append((long)this, &compositeCopy);
 
338
 
 
339
        // Copy the children
 
340
        wxNode *node = m_children.GetFirst();
 
341
        while (node)
 
342
        {
 
343
                wxShape *object = (wxShape *)node->GetData();
 
344
                wxShape *newObject = object->CreateNewCopy(FALSE, FALSE);
 
345
                if (newObject->GetId() == 0)
 
346
                        newObject->SetId(wxNewId());
 
347
 
 
348
                newObject->SetParent(&compositeCopy);
 
349
                compositeCopy.m_children.Append(newObject);
 
350
 
 
351
                // Some m_children may be divisions
 
352
                if (m_divisions.Member(object))
 
353
                        compositeCopy.m_divisions.Append(newObject);
 
354
 
 
355
                oglObjectCopyMapping.Append((long)object, newObject);
 
356
 
 
357
                node = node->GetNext();
 
358
        }
 
359
 
 
360
        // Copy the constraints
 
361
        node = m_constraints.GetFirst();
 
362
        while (node)
 
363
        {
 
364
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
365
 
 
366
                wxShape *newConstraining = (wxShape *)(oglObjectCopyMapping.Find((long)constraint->m_constrainingObject)->GetData());
 
367
 
 
368
                wxList newConstrainedList;
 
369
                wxNode *node2 = constraint->m_constrainedObjects.GetFirst();
 
370
                while (node2)
 
371
                {
 
372
                        wxShape *constrainedObject = (wxShape *)node2->GetData();
 
373
                        wxShape *newConstrained = (wxShape *)(oglObjectCopyMapping.Find((long)constrainedObject)->GetData());
 
374
                        newConstrainedList.Append(newConstrained);
 
375
                        node2 = node2->GetNext();
 
376
                }
 
377
 
 
378
                wxOGLConstraint *newConstraint = new wxOGLConstraint(constraint->m_constraintType, newConstraining,
 
379
                        newConstrainedList);
 
380
                newConstraint->m_constraintId = constraint->m_constraintId;
 
381
                if (!constraint->m_constraintName.IsEmpty())
 
382
                {
 
383
                        newConstraint->m_constraintName = constraint->m_constraintName;
 
384
                }
 
385
                newConstraint->SetSpacing(constraint->m_xSpacing, constraint->m_ySpacing);
 
386
                compositeCopy.m_constraints.Append(newConstraint);
 
387
 
 
388
                node = node->GetNext();
 
389
        }
 
390
 
 
391
        // Now compositeCopy the division geometry
 
392
        node = m_divisions.GetFirst();
 
393
        while (node)
 
394
        {
 
395
                wxDivisionShape *division = (wxDivisionShape *)node->GetData();
 
396
                wxNode *node1 = oglObjectCopyMapping.Find((long)division);
 
397
                wxNode *leftNode = NULL;
 
398
                wxNode *topNode = NULL;
 
399
                wxNode *rightNode = NULL;
 
400
                wxNode *bottomNode = NULL;
 
401
                if (division->GetLeftSide())
 
402
                        leftNode = oglObjectCopyMapping.Find((long)division->GetLeftSide());
 
403
                if (division->GetTopSide())
 
404
                        topNode = oglObjectCopyMapping.Find((long)division->GetTopSide());
 
405
                if (division->GetRightSide())
 
406
                        rightNode = oglObjectCopyMapping.Find((long)division->GetRightSide());
 
407
                if (division->GetBottomSide())
 
408
                        bottomNode = oglObjectCopyMapping.Find((long)division->GetBottomSide());
 
409
                if (node1)
 
410
                {
 
411
                        wxDivisionShape *newDivision = (wxDivisionShape *)node1->GetData();
 
412
                        if (leftNode)
 
413
                                newDivision->SetLeftSide((wxDivisionShape *)leftNode->GetData());
 
414
                        if (topNode)
 
415
                                newDivision->SetTopSide((wxDivisionShape *)topNode->GetData());
 
416
                        if (rightNode)
 
417
                                newDivision->SetRightSide((wxDivisionShape *)rightNode->GetData());
 
418
                        if (bottomNode)
 
419
                                newDivision->SetBottomSide((wxDivisionShape *)bottomNode->GetData());
 
420
                }
 
421
                node = node->GetNext();
 
422
        }
 
423
}
 
424
 
 
425
wxOGLConstraint *wxCompositeShape::AddConstraint(wxOGLConstraint *constraint)
 
426
{
 
427
        m_constraints.Append(constraint);
 
428
        if (constraint->m_constraintId == 0)
 
429
                constraint->m_constraintId = wxNewId();
 
430
        return constraint;
 
431
}
 
432
 
 
433
wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxList &constrained)
 
434
{
 
435
        wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, constrained);
 
436
        if (constraint->m_constraintId == 0)
 
437
                constraint->m_constraintId = wxNewId();
 
438
        m_constraints.Append(constraint);
 
439
        return constraint;
 
440
}
 
441
 
 
442
wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxShape *constrained)
 
443
{
 
444
        wxList l;
 
445
        l.Append(constrained);
 
446
        wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, l);
 
447
        if (constraint->m_constraintId == 0)
 
448
                constraint->m_constraintId = wxNewId();
 
449
        m_constraints.Append(constraint);
 
450
        return constraint;
 
451
}
 
452
 
 
453
wxOGLConstraint *wxCompositeShape::FindConstraint(long cId, wxCompositeShape **actualComposite)
 
454
{
 
455
        wxNode *node = m_constraints.GetFirst();
 
456
        while (node)
 
457
        {
 
458
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
459
                if (constraint->m_constraintId == cId)
 
460
                {
 
461
                        if (actualComposite)
 
462
                                *actualComposite = this;
 
463
                        return constraint;
 
464
                }
 
465
                node = node->GetNext();
 
466
        }
 
467
        // If not found, try children.
 
468
        node = m_children.GetFirst();
 
469
        while (node)
 
470
        {
 
471
                wxShape *child = (wxShape *)node->GetData();
 
472
                if (child->IsKindOf(CLASSINFO(wxCompositeShape)))
 
473
                {
 
474
                        wxOGLConstraint *constraint = ((wxCompositeShape *)child)->FindConstraint(cId, actualComposite);
 
475
                        if (constraint)
 
476
                        {
 
477
                                if (actualComposite)
 
478
                                        *actualComposite = (wxCompositeShape *)child;
 
479
                                return constraint;
 
480
                        }
 
481
                }
 
482
                node = node->GetNext();
 
483
        }
 
484
        return NULL;
 
485
}
 
486
 
 
487
void wxCompositeShape::DeleteConstraint(wxOGLConstraint *constraint)
 
488
{
 
489
        m_constraints.DeleteObject(constraint);
 
490
        delete constraint;
 
491
}
 
492
 
 
493
void wxCompositeShape::CalculateSize()
 
494
{
 
495
        double maxX = (double) - 999999.9;
 
496
        double maxY = (double) - 999999.9;
 
497
        double minX = (double)  999999.9;
 
498
        double minY = (double)  999999.9;
 
499
 
 
500
        double w, h;
 
501
        wxNode *node = m_children.GetFirst();
 
502
        while (node)
 
503
        {
 
504
                wxShape *object = (wxShape *)node->GetData();
 
505
 
 
506
                // Recalculate size of composite objects because may not conform
 
507
                // to size it was set to - depends on the children.
 
508
                object->CalculateSize();
 
509
 
 
510
                object->GetBoundingBoxMax(&w, &h);
 
511
                if ((object->GetX() + (w / 2.0)) > maxX)
 
512
                        maxX = (double)(object->GetX() + (w / 2.0));
 
513
                if ((object->GetX() - (w / 2.0)) < minX)
 
514
                        minX = (double)(object->GetX() - (w / 2.0));
 
515
                if ((object->GetY() + (h / 2.0)) > maxY)
 
516
                        maxY = (double)(object->GetY() + (h / 2.0));
 
517
                if ((object->GetY() - (h / 2.0)) < minY)
 
518
                        minY = (double)(object->GetY() - (h / 2.0));
 
519
 
 
520
                node = node->GetNext();
 
521
        }
 
522
        m_width = maxX - minX;
 
523
        m_height = maxY - minY;
 
524
        m_xpos = (double)(m_width / 2.0 + minX);
 
525
        m_ypos = (double)(m_height / 2.0 + minY);
 
526
}
 
527
 
 
528
bool wxCompositeShape::Recompute()
 
529
{
 
530
        int noIterations = 0;
 
531
        bool changed = TRUE;
 
532
        while (changed && (noIterations < 500))
 
533
        {
 
534
                changed = Constrain();
 
535
                noIterations ++;
 
536
        }
 
537
        /*
 
538
        #ifdef wx_x
 
539
          if (changed)
 
540
            cerr << "Warning: constraint algorithm failed after 500 iterations.\n";
 
541
        #endif
 
542
        */
 
543
        return (!changed);
 
544
}
 
545
 
 
546
bool wxCompositeShape::Constrain()
 
547
{
 
548
        CalculateSize();
 
549
 
 
550
        bool changed = FALSE;
 
551
        wxNode *node = m_children.GetFirst();
 
552
        while (node)
 
553
        {
 
554
                wxShape *object = (wxShape *)node->GetData();
 
555
                if (object->Constrain())
 
556
                        changed = TRUE;
 
557
                node = node->GetNext();
 
558
        }
 
559
 
 
560
        node = m_constraints.GetFirst();
 
561
        while (node)
 
562
        {
 
563
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
564
                if (constraint->Evaluate()) changed = TRUE;
 
565
                node = node->GetNext();
 
566
        }
 
567
        return changed;
 
568
}
 
569
 
 
570
#if wxUSE_PROLOGIO
 
571
void wxCompositeShape::WriteAttributes(wxExpr *clause)
 
572
{
 
573
        wxRectangleShape::WriteAttributes(clause);
 
574
 
 
575
//  clause->AddAttributeValue("selectable", (long)selectable);
 
576
 
 
577
        // Output constraints as constraint1 = (...), constraint2 = (...), etc.
 
578
        int constraintNo = 1;
 
579
        wxChar m_constraintNameBuf[20];
 
580
        wxNode *node = m_constraints.GetFirst();
 
581
        while (node)
 
582
        {
 
583
                wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData();
 
584
                wxSprintf(m_constraintNameBuf, _T("constraint%d"), constraintNo);
 
585
 
 
586
                // Each constraint is stored in the form
 
587
                // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList)
 
588
                wxExpr *constraintExpr = new wxExpr(wxExprList);
 
589
                constraintExpr->Append(new wxExpr((long)constraint->m_constraintType));
 
590
                constraintExpr->Append(new wxExpr(wxExprString, constraint->m_constraintName));
 
591
                constraintExpr->Append(new wxExpr(constraint->m_constraintId));
 
592
                constraintExpr->Append(new wxExpr(constraint->m_xSpacing));
 
593
                constraintExpr->Append(new wxExpr(constraint->m_ySpacing));
 
594
                constraintExpr->Append(new wxExpr(constraint->m_constrainingObject->GetId()));
 
595
 
 
596
                wxExpr *objectList = new wxExpr(wxExprList);
 
597
                wxNode *node1 = constraint->m_constrainedObjects.GetFirst();
 
598
                while (node1)
 
599
                {
 
600
                        wxShape *obj = (wxShape *)node1->GetData();
 
601
                        objectList->Append(new wxExpr(obj->GetId()));
 
602
                        node1 = node1->GetNext();
 
603
                }
 
604
                constraintExpr->Append(objectList);
 
605
 
 
606
                clause->AddAttributeValue(m_constraintNameBuf, constraintExpr);
 
607
 
 
608
                node = node->GetNext();
 
609
                constraintNo ++;
 
610
        }
 
611
 
 
612
        // Write the ids of all the child images
 
613
        wxExpr *childrenExpr = new wxExpr(wxExprList);
 
614
        node = m_children.GetFirst();
 
615
        while (node)
 
616
        {
 
617
                wxShape *child = (wxShape *)node->GetData();
 
618
                childrenExpr->Append(new wxExpr(child->GetId()));
 
619
                node = node->GetNext();
 
620
        }
 
621
        clause->AddAttributeValue(_T("children"), childrenExpr);
 
622
 
 
623
        // Write the ids of all the division images
 
624
        if (m_divisions.GetCount() > 0)
 
625
        {
 
626
                wxExpr *divisionsExpr = new wxExpr(wxExprList);
 
627
                node = m_divisions.GetFirst();
 
628
                while (node)
 
629
                {
 
630
                        wxShape *child = (wxShape *)node->GetData();
 
631
                        divisionsExpr->Append(new wxExpr(child->GetId()));
 
632
                        node = node->GetNext();
 
633
                }
 
634
                clause->AddAttributeValue(_T("divisions"), divisionsExpr);
 
635
        }
 
636
}
 
637
 
 
638
// Problem. Child images are always written AFTER the parent
 
639
// so as to be able to link up to parent. So we may not be able
 
640
// to find the constraint participants until we've read everything
 
641
// in. Need to have another pass for composites.
 
642
void wxCompositeShape::ReadAttributes(wxExpr *clause)
 
643
{
 
644
        wxRectangleShape::ReadAttributes(clause);
 
645
 
 
646
//  clause->GetAttributeValue("selectable", selectable);
 
647
}
 
648
 
 
649
void wxCompositeShape::ReadConstraints(wxExpr *clause, wxExprDatabase *database)
 
650
{
 
651
        // Constraints are output as constraint1 = (...), constraint2 = (...), etc.
 
652
        int constraintNo = 1;
 
653
        wxChar m_constraintNameBuf[20];
 
654
        bool haveConstraints = TRUE;
 
655
 
 
656
        while (haveConstraints)
 
657
        {
 
658
                wxSprintf(m_constraintNameBuf, _T("constraint%d"), constraintNo);
 
659
                wxExpr *constraintExpr = NULL;
 
660
                clause->GetAttributeValue(m_constraintNameBuf, &constraintExpr);
 
661
                if (!constraintExpr)
 
662
                {
 
663
                        haveConstraints = FALSE;
 
664
                        break;
 
665
                }
 
666
                wxString cName = wxEmptyString;
 
667
                wxShape *m_constrainingObject = NULL;
 
668
                wxList m_constrainedObjects;
 
669
 
 
670
                // Each constraint is stored in the form
 
671
                // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList)
 
672
 
 
673
                wxExpr *typeExpr = constraintExpr->Nth(0);
 
674
                wxExpr *nameExpr = constraintExpr->Nth(1);
 
675
                wxExpr *idExpr = constraintExpr->Nth(2);
 
676
                wxExpr *xExpr = constraintExpr->Nth(3);
 
677
                wxExpr *yExpr = constraintExpr->Nth(4);
 
678
                wxExpr *constrainingExpr = constraintExpr->Nth(5);
 
679
                wxExpr *constrainedExpr = constraintExpr->Nth(6);
 
680
 
 
681
                int cType = (int)typeExpr->IntegerValue();
 
682
                double cXSpacing = xExpr->RealValue();
 
683
                double cYSpacing = yExpr->RealValue();
 
684
                cName = nameExpr->StringValue();
 
685
                long cId = idExpr->IntegerValue();
 
686
 
 
687
                wxExpr *objExpr1 = database->HashFind(_T("node_image"), constrainingExpr->IntegerValue());
 
688
                if (objExpr1 && objExpr1->GetClientData())
 
689
                        m_constrainingObject = (wxShape *)objExpr1->GetClientData();
 
690
                else
 
691
                        wxLogFatalError(wxT("Object graphics error: Couldn't find constraining image of composite."));
 
692
 
 
693
                int i = 0;
 
694
                wxExpr *currentIdExpr = constrainedExpr->Nth(i);
 
695
                while (currentIdExpr)
 
696
                {
 
697
                        long currentId = currentIdExpr->IntegerValue();
 
698
                        wxExpr *objExpr2 = database->HashFind(_T("node_image"), currentId);
 
699
                        if (objExpr2 && objExpr2->GetClientData())
 
700
                        {
 
701
                                m_constrainedObjects.Append((wxShape *)objExpr2->GetClientData());
 
702
                        }
 
703
                        else
 
704
                        {
 
705
                                wxLogFatalError(wxT("Object graphics error: Couldn't find constrained image of composite."));
 
706
                        }
 
707
 
 
708
                        i ++;
 
709
                        currentIdExpr = constrainedExpr->Nth(i);
 
710
                }
 
711
                wxOGLConstraint *newConstraint = AddConstraint(cType, m_constrainingObject, m_constrainedObjects);
 
712
                newConstraint->SetSpacing(cXSpacing, cYSpacing);
 
713
                newConstraint->m_constraintId = cId;
 
714
                newConstraint->m_constraintName = cName;
 
715
                constraintNo ++;
 
716
        }
 
717
}
 
718
#endif
 
719
 
 
720
// Make this composite into a container by creating one wxDivisionShape
 
721
void wxCompositeShape::MakeContainer()
 
722
{
 
723
        wxDivisionShape *division = OnCreateDivision();
 
724
        m_divisions.Append(division);
 
725
        AddChild(division);
 
726
 
 
727
        division->SetSize(m_width, m_height);
 
728
 
 
729
        wxClientDC dc(GetCanvas());
 
730
        GetCanvas()->PrepareDC(dc);
 
731
 
 
732
        division->Move(GetX(), GetY());
 
733
        Recompute();
 
734
        division->Show(TRUE);
 
735
}
 
736
 
 
737
wxDivisionShape *wxCompositeShape::OnCreateDivision()
 
738
{
 
739
        return new wxDivisionShape;
 
740
}
 
741
 
 
742
wxShape *wxCompositeShape::FindContainerImage()
 
743
{
 
744
        wxNode *node = m_children.GetFirst();
 
745
        while (node)
 
746
        {
 
747
                wxShape *child = (wxShape *)node->GetData();
 
748
                if (!m_divisions.Member(child))
 
749
                        return child;
 
750
                node = node->GetNext();
 
751
        }
 
752
        return NULL;
 
753
}
 
754
 
 
755
// Returns TRUE if division is a descendant of this container
 
756
bool wxCompositeShape::ContainsDivision(wxDivisionShape *division)
 
757
{
 
758
        if (m_divisions.Member(division))
 
759
                return TRUE;
 
760
        wxNode *node = m_children.GetFirst();
 
761
        while (node)
 
762
        {
 
763
                wxShape *child = (wxShape *)node->GetData();
 
764
                if (child->IsKindOf(CLASSINFO(wxCompositeShape)))
 
765
                {
 
766
                        bool ans = ((wxCompositeShape *)child)->ContainsDivision(division);
 
767
                        if (ans)
 
768
                                return TRUE;
 
769
                }
 
770
                node = node->GetNext();
 
771
        }
 
772
        return FALSE;
 
773
}
 
774
 
 
775
/*
 
776
 * Division object
 
777
 *
 
778
 */
 
779
 
 
780
IMPLEMENT_DYNAMIC_CLASS(wxDivisionShape, wxCompositeShape)
 
781
 
 
782
wxDivisionShape::wxDivisionShape()
 
783
{
 
784
        SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT);
 
785
        SetCentreResize(FALSE);
 
786
        SetAttachmentMode(TRUE);
 
787
        m_leftSide = NULL;
 
788
        m_rightSide = NULL;
 
789
        m_topSide = NULL;
 
790
        m_bottomSide = NULL;
 
791
        m_handleSide = DIVISION_SIDE_NONE;
 
792
        m_leftSidePen = (wxPen *) wxBLACK_PEN;
 
793
        m_topSidePen = (wxPen *) wxBLACK_PEN;
 
794
        m_leftSideColour = wxT("BLACK");
 
795
        m_topSideColour = wxT("BLACK");
 
796
        m_leftSideStyle = wxT("Solid");
 
797
        m_topSideStyle = wxT("Solid");
 
798
        ClearRegions();
 
799
}
 
800
 
 
801
wxDivisionShape::~wxDivisionShape()
 
802
{
 
803
}
 
804
 
 
805
void wxDivisionShape::OnDraw(wxDC &dc)
 
806
{
 
807
        dc.SetBrush(* wxTRANSPARENT_BRUSH);
 
808
        dc.SetBackgroundMode(wxTRANSPARENT);
 
809
 
 
810
        double x1 = (double)(GetX() - (GetWidth() / 2.0));
 
811
        double y1 = (double)(GetY() - (GetHeight() / 2.0));
 
812
        double x2 = (double)(GetX() + (GetWidth() / 2.0));
 
813
        double y2 = (double)(GetY() + (GetHeight() / 2.0));
 
814
 
 
815
        // Should subtract 1 pixel if drawing under Windows
 
816
#ifdef __WXMSW__
 
817
        y2 -= (double)1.0;
 
818
#endif
 
819
 
 
820
        if (m_leftSide)
 
821
        {
 
822
                dc.SetPen(* m_leftSidePen);
 
823
                dc.DrawLine(WXROUND(x1), WXROUND(y2), WXROUND(x1), WXROUND(y1));
 
824
        }
 
825
        if (m_topSide)
 
826
        {
 
827
                dc.SetPen(* m_topSidePen);
 
828
                dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y1));
 
829
        }
 
830
 
 
831
        // For testing purposes, draw a rectangle so we know
 
832
        // how big the division is.
 
833
//    SetBrush(* wxCYAN_BRUSH);
 
834
//    wxRectangleShape::OnDraw(dc);
 
835
}
 
836
 
 
837
void wxDivisionShape::OnDrawContents(wxDC &dc)
 
838
{
 
839
        wxCompositeShape::OnDrawContents(dc);
 
840
}
 
841
 
 
842
bool wxDivisionShape::OnMovePre(double x, double y, double oldx, double oldy, bool display)
 
843
{
 
844
        double diffX = x - oldx;
 
845
        double diffY = y - oldy;
 
846
        wxNode *node = m_children.GetFirst();
 
847
        while (node)
 
848
        {
 
849
                wxShape *object = (wxShape *)node->GetData();
 
850
                object->Erase();
 
851
                object->Move(object->GetX() + diffX, object->GetY() + diffY, display);
 
852
                node = node->GetNext();
 
853
        }
 
854
        return TRUE;
 
855
}
 
856
 
 
857
void wxDivisionShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
 
858
{
 
859
        if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
 
860
        {
 
861
                attachment = 0;
 
862
                double dist;
 
863
                if (m_parent)
 
864
                {
 
865
                        m_parent->HitTest(x, y, &attachment, &dist);
 
866
                        m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment);
 
867
                }
 
868
                return;
 
869
        }
 
870
        wxShape::OnDragLeft(draw, x, y, keys, attachment);
 
871
}
 
872
 
 
873
void wxDivisionShape::OnBeginDragLeft(double x, double y, int keys, int attachment)
 
874
{
 
875
        if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
 
876
        {
 
877
                attachment = 0;
 
878
                double dist;
 
879
                if (m_parent)
 
880
                {
 
881
                        m_parent->HitTest(x, y, &attachment, &dist);
 
882
                        m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment);
 
883
                }
 
884
                return;
 
885
        }
 
886
 
 
887
        wxShape::OnBeginDragLeft(x, y, keys, attachment);
 
888
}
 
889
 
 
890
void wxDivisionShape::OnEndDragLeft(double x, double y, int keys, int attachment)
 
891
{
 
892
        m_canvas->ReleaseMouse();
 
893
        if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
 
894
        {
 
895
                attachment = 0;
 
896
                double dist;
 
897
                if (m_parent)
 
898
                {
 
899
                        m_parent->HitTest(x, y, &attachment, &dist);
 
900
                        m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment);
 
901
                }
 
902
                return;
 
903
        }
 
904
 
 
905
#if 0
 
906
        wxClientDC dc(GetCanvas());
 
907
        GetCanvas()->PrepareDC(dc);
 
908
 
 
909
        dc.SetLogicalFunction(wxCOPY);
 
910
#endif
 
911
 
 
912
        m_canvas->Snap(&m_xpos, &m_ypos);
 
913
        GetEventHandler()->OnMovePre(x, y, m_oldX, m_oldY);
 
914
 
 
915
        ResetControlPoints();
 
916
        MoveLinks();
 
917
 
 
918
        if (m_canvas)
 
919
                m_canvas->Refresh();
 
920
}
 
921
 
 
922
void wxDivisionShape::SetSize(double w, double h, bool recursive)
 
923
{
 
924
        m_width = w;
 
925
        m_height = h;
 
926
        wxRectangleShape::SetSize(w, h, recursive);
 
927
}
 
928
 
 
929
void wxDivisionShape::CalculateSize()
 
930
{
 
931
}
 
932
 
 
933
void wxDivisionShape::Copy(wxShape &copy)
 
934
{
 
935
        wxCompositeShape::Copy(copy);
 
936
 
 
937
        wxASSERT( copy.IsKindOf(CLASSINFO(wxDivisionShape)) ) ;
 
938
 
 
939
        wxDivisionShape &divisionCopy = (wxDivisionShape &) copy;
 
940
 
 
941
        divisionCopy.m_leftSideStyle = m_leftSideStyle;
 
942
        divisionCopy.m_topSideStyle = m_topSideStyle;
 
943
        divisionCopy.m_leftSideColour = m_leftSideColour;
 
944
        divisionCopy.m_topSideColour = m_topSideColour;
 
945
 
 
946
        divisionCopy.m_leftSidePen = m_leftSidePen;
 
947
        divisionCopy.m_topSidePen = m_topSidePen;
 
948
        divisionCopy.m_handleSide = m_handleSide;
 
949
 
 
950
        // Division geometry copying is handled at the wxCompositeShape level.
 
951
}
 
952
 
 
953
#if wxUSE_PROLOGIO
 
954
void wxDivisionShape::WriteAttributes(wxExpr *clause)
 
955
{
 
956
        wxCompositeShape::WriteAttributes(clause);
 
957
 
 
958
        if (m_leftSide)
 
959
                clause->AddAttributeValue(_T("left_side"), (long)m_leftSide->GetId());
 
960
        if (m_topSide)
 
961
                clause->AddAttributeValue(_T("top_side"), (long)m_topSide->GetId());
 
962
        if (m_rightSide)
 
963
                clause->AddAttributeValue(_T("right_side"), (long)m_rightSide->GetId());
 
964
        if (m_bottomSide)
 
965
                clause->AddAttributeValue(_T("bottom_side"), (long)m_bottomSide->GetId());
 
966
 
 
967
        clause->AddAttributeValue(_T("handle_side"), (long)m_handleSide);
 
968
        clause->AddAttributeValueString(_T("left_colour"), m_leftSideColour);
 
969
        clause->AddAttributeValueString(_T("top_colour"), m_topSideColour);
 
970
        clause->AddAttributeValueString(_T("left_style"), m_leftSideStyle);
 
971
        clause->AddAttributeValueString(_T("top_style"), m_topSideStyle);
 
972
}
 
973
 
 
974
void wxDivisionShape::ReadAttributes(wxExpr *clause)
 
975
{
 
976
        wxCompositeShape::ReadAttributes(clause);
 
977
 
 
978
        clause->GetAttributeValue(_T("handle_side"), m_handleSide);
 
979
        clause->GetAttributeValue(_T("left_colour"), m_leftSideColour);
 
980
        clause->GetAttributeValue(_T("top_colour"), m_topSideColour);
 
981
        clause->GetAttributeValue(_T("left_style"), m_leftSideStyle);
 
982
        clause->GetAttributeValue(_T("top_style"), m_topSideStyle);
 
983
}
 
984
#endif
 
985
 
 
986
// Experimental
 
987
void wxDivisionShape::OnRightClick(double x, double y, int keys, int attachment)
 
988
{
 
989
        if (keys & KEY_CTRL)
 
990
        {
 
991
                PopupMenu(x, y);
 
992
        }
 
993
        /*
 
994
          else if (keys & KEY_SHIFT)
 
995
          {
 
996
            if (m_leftSide || m_topSide || m_rightSide || m_bottomSide)
 
997
            {
 
998
              if (Selected())
 
999
              {
 
1000
                Select(FALSE);
 
1001
                GetParent()->Draw(dc);
 
1002
              }
 
1003
              else
 
1004
                Select(TRUE);
 
1005
            }
 
1006
          }
 
1007
        */
 
1008
        else
 
1009
        {
 
1010
                attachment = 0;
 
1011
                double dist;
 
1012
                if (m_parent)
 
1013
                {
 
1014
                        m_parent->HitTest(x, y, &attachment, &dist);
 
1015
                        m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment);
 
1016
                }
 
1017
                return;
 
1018
        }
 
1019
}
 
1020
 
 
1021
 
 
1022
// Divide wxHORIZONTALly or wxVERTICALly
 
1023
bool wxDivisionShape::Divide(int direction)
 
1024
{
 
1025
        // Calculate existing top-left, bottom-right
 
1026
        double x1 = (double)(GetX() - (GetWidth() / 2.0));
 
1027
        double y1 = (double)(GetY() - (GetHeight() / 2.0));
 
1028
        wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent();
 
1029
        double oldWidth = GetWidth();
 
1030
        double oldHeight = GetHeight();
 
1031
        if (Selected())
 
1032
                Select(FALSE);
 
1033
 
 
1034
        //wxClientDC dc(GetCanvas());
 
1035
        //GetCanvas()->PrepareDC(dc);
 
1036
 
 
1037
        if (direction == wxVERTICAL)
 
1038
        {
 
1039
                // Dividing vertically means notionally putting a horizontal line through it.
 
1040
                // Break existing piece into two.
 
1041
                double newXPos1 = GetX();
 
1042
                double newYPos1 = (double)(y1 + (GetHeight() / 4.0));
 
1043
                double newXPos2 = GetX();
 
1044
                double newYPos2 = (double)(y1 + (3.0 * GetHeight() / 4.0));
 
1045
                wxDivisionShape *newDivision = compositeParent->OnCreateDivision();
 
1046
                newDivision->Show(TRUE);
 
1047
 
 
1048
                // Erase();
 
1049
 
 
1050
                // Anything adjoining the bottom of this division now adjoins the
 
1051
                // bottom of the new division.
 
1052
                wxNode *node = compositeParent->GetDivisions().GetFirst();
 
1053
                while (node)
 
1054
                {
 
1055
                        wxDivisionShape *obj = (wxDivisionShape *)node->GetData();
 
1056
                        if (obj->GetTopSide() == this)
 
1057
                                obj->SetTopSide(newDivision);
 
1058
                        node = node->GetNext();
 
1059
                }
 
1060
                newDivision->SetTopSide(this);
 
1061
                newDivision->SetBottomSide(m_bottomSide);
 
1062
                newDivision->SetLeftSide(m_leftSide);
 
1063
                newDivision->SetRightSide(m_rightSide);
 
1064
                m_bottomSide = newDivision;
 
1065
 
 
1066
                compositeParent->GetDivisions().Append(newDivision);
 
1067
 
 
1068
                // CHANGE: Need to insert this division at start of divisions in the object
 
1069
                // list, because e.g.:
 
1070
                // 1) Add division
 
1071
                // 2) Add contained object
 
1072
                // 3) Add division
 
1073
                // Division is now receiving mouse events _before_ the contained object,
 
1074
                // because it was added last (on top of all others)
 
1075
 
 
1076
                // Add after the image that visualizes the container
 
1077
                compositeParent->AddChild(newDivision, compositeParent->FindContainerImage());
 
1078
 
 
1079
                m_handleSide = DIVISION_SIDE_BOTTOM;
 
1080
                newDivision->SetHandleSide(DIVISION_SIDE_TOP);
 
1081
 
 
1082
                SetSize(oldWidth, (double)(oldHeight / 2.0));
 
1083
                Move(newXPos1, newYPos1);
 
1084
 
 
1085
                newDivision->SetSize(oldWidth, (double)(oldHeight / 2.0));
 
1086
                newDivision->Move(newXPos2, newYPos2);
 
1087
        }
 
1088
        else
 
1089
        {
 
1090
                // Dividing horizontally means notionally putting a vertical line through it.
 
1091
                // Break existing piece into two.
 
1092
                double newXPos1 = (double)(x1 + (GetWidth() / 4.0));
 
1093
                double newYPos1 = GetY();
 
1094
                double newXPos2 = (double)(x1 + (3.0 * GetWidth() / 4.0));
 
1095
                double newYPos2 = GetY();
 
1096
                wxDivisionShape *newDivision = compositeParent->OnCreateDivision();
 
1097
                newDivision->Show(TRUE);
 
1098
 
 
1099
                // Erase(dc);
 
1100
 
 
1101
                // Anything adjoining the left of this division now adjoins the
 
1102
                // left of the new division.
 
1103
                wxNode *node = compositeParent->GetDivisions().GetFirst();
 
1104
                while (node)
 
1105
                {
 
1106
                        wxDivisionShape *obj = (wxDivisionShape *)node->GetData();
 
1107
                        if (obj->GetLeftSide() == this)
 
1108
                                obj->SetLeftSide(newDivision);
 
1109
                        node = node->GetNext();
 
1110
                }
 
1111
                newDivision->SetTopSide(m_topSide);
 
1112
                newDivision->SetBottomSide(m_bottomSide);
 
1113
                newDivision->SetLeftSide(this);
 
1114
                newDivision->SetRightSide(m_rightSide);
 
1115
                m_rightSide = newDivision;
 
1116
 
 
1117
                compositeParent->GetDivisions().Append(newDivision);
 
1118
                compositeParent->AddChild(newDivision, compositeParent->FindContainerImage());
 
1119
 
 
1120
                m_handleSide = DIVISION_SIDE_RIGHT;
 
1121
                newDivision->SetHandleSide(DIVISION_SIDE_LEFT);
 
1122
 
 
1123
                SetSize((double)(oldWidth / 2.0), oldHeight);
 
1124
                Move(newXPos1, newYPos1);
 
1125
 
 
1126
                newDivision->SetSize((double)(oldWidth / 2.0), oldHeight);
 
1127
                newDivision->Move(newXPos2, newYPos2);
 
1128
        }
 
1129
        if (compositeParent->Selected())
 
1130
        {
 
1131
                compositeParent->DeleteControlPoints();
 
1132
                compositeParent->MakeControlPoints();
 
1133
                compositeParent->MakeMandatoryControlPoints();
 
1134
        }
 
1135
        // compositeParent->Draw(dc);
 
1136
 
 
1137
        if (GetCanvas())
 
1138
                GetCanvas()->Refresh();
 
1139
        return TRUE;
 
1140
}
 
1141
 
 
1142
// Make one control point for every visible line
 
1143
void wxDivisionShape::MakeControlPoints()
 
1144
{
 
1145
        MakeMandatoryControlPoints();
 
1146
}
 
1147
 
 
1148
void wxDivisionShape::MakeMandatoryControlPoints()
 
1149
{
 
1150
        double maxX, maxY;
 
1151
 
 
1152
        GetBoundingBoxMax(&maxX, &maxY);
 
1153
        double x = 0.0 , y = 0.0;
 
1154
        int direction = 0;
 
1155
        /*
 
1156
          if (m_leftSide)
 
1157
          {
 
1158
            x = (double)(-maxX/2.0);
 
1159
            y = 0.0;
 
1160
            wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
 
1161
                                                     CONTROL_POINT_HORIZONTAL);
 
1162
            m_canvas->AddShape(control);
 
1163
            m_controlPoints.Append(control);
 
1164
          }
 
1165
          if (m_topSide)
 
1166
          {
 
1167
            x = 0.0;
 
1168
            y = (double)(-maxY/2.0);
 
1169
            wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
 
1170
                                                     CONTROL_POINT_VERTICAL);
 
1171
            m_canvas->AddShape(control);
 
1172
            m_controlPoints.Append(control);
 
1173
          }
 
1174
        */
 
1175
        switch (m_handleSide)
 
1176
        {
 
1177
                case DIVISION_SIDE_LEFT:
 
1178
                {
 
1179
                        x = (double)(-maxX / 2.0);
 
1180
                        y = 0.0;
 
1181
                        direction = CONTROL_POINT_HORIZONTAL;
 
1182
                        break;
 
1183
                }
 
1184
                case DIVISION_SIDE_TOP:
 
1185
                {
 
1186
                        x = 0.0;
 
1187
                        y = (double)(-maxY / 2.0);
 
1188
                        direction = CONTROL_POINT_VERTICAL;
 
1189
                        break;
 
1190
                }
 
1191
                case DIVISION_SIDE_RIGHT:
 
1192
                {
 
1193
                        x = (double)(maxX / 2.0);
 
1194
                        y = 0.0;
 
1195
                        direction = CONTROL_POINT_HORIZONTAL;
 
1196
                        break;
 
1197
                }
 
1198
                case DIVISION_SIDE_BOTTOM:
 
1199
                {
 
1200
                        x = 0.0;
 
1201
                        y = (double)(maxY / 2.0);
 
1202
                        direction = CONTROL_POINT_VERTICAL;
 
1203
                        break;
 
1204
                }
 
1205
                default:
 
1206
                        break;
 
1207
        }
 
1208
        if (m_handleSide != DIVISION_SIDE_NONE)
 
1209
        {
 
1210
                wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
 
1211
                        direction);
 
1212
                m_canvas->AddShape(control);
 
1213
                m_controlPoints.Append(control);
 
1214
        }
 
1215
}
 
1216
 
 
1217
void wxDivisionShape::ResetControlPoints()
 
1218
{
 
1219
        ResetMandatoryControlPoints();
 
1220
}
 
1221
 
 
1222
void wxDivisionShape::ResetMandatoryControlPoints()
 
1223
{
 
1224
        if (m_controlPoints.GetCount() < 1)
 
1225
                return;
 
1226
 
 
1227
        double maxX, maxY;
 
1228
 
 
1229
        GetBoundingBoxMax(&maxX, &maxY);
 
1230
        /*
 
1231
          wxNode *node = m_controlPoints.GetFirst();
 
1232
          while (node)
 
1233
          {
 
1234
            wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
 
1235
            if (control->type == CONTROL_POINT_HORIZONTAL)
 
1236
            {
 
1237
              control->xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0;
 
1238
            }
 
1239
            else if (control->type == CONTROL_POINT_VERTICAL)
 
1240
            {
 
1241
              control->xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0);
 
1242
            }
 
1243
            node = node->GetNext();
 
1244
          }
 
1245
        */
 
1246
        wxNode *node = m_controlPoints.GetFirst();
 
1247
        if ((m_handleSide == DIVISION_SIDE_LEFT) && node)
 
1248
        {
 
1249
                wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
 
1250
                control->m_xoffset = (double)(-maxX / 2.0);
 
1251
                control->m_yoffset = 0.0;
 
1252
        }
 
1253
 
 
1254
        if ((m_handleSide == DIVISION_SIDE_TOP) && node)
 
1255
        {
 
1256
                wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
 
1257
                control->m_xoffset = 0.0;
 
1258
                control->m_yoffset = (double)(-maxY / 2.0);
 
1259
        }
 
1260
 
 
1261
        if ((m_handleSide == DIVISION_SIDE_RIGHT) && node)
 
1262
        {
 
1263
                wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
 
1264
                control->m_xoffset = (double)(maxX / 2.0);
 
1265
                control->m_yoffset = 0.0;
 
1266
        }
 
1267
 
 
1268
        if ((m_handleSide == DIVISION_SIDE_BOTTOM) && node)
 
1269
        {
 
1270
                wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
 
1271
                control->m_xoffset = 0.0;
 
1272
                control->m_yoffset = (double)(maxY / 2.0);
 
1273
        }
 
1274
}
 
1275
 
 
1276
// Adjust a side, returning FALSE if it's not physically possible.
 
1277
bool wxDivisionShape::AdjustLeft(double left, bool test)
 
1278
{
 
1279
        double x2 = (double)(GetX() + (GetWidth() / 2.0));
 
1280
 
 
1281
        if (left >= x2)
 
1282
                return FALSE;
 
1283
        if (test)
 
1284
                return TRUE;
 
1285
 
 
1286
        double newW = x2 - left;
 
1287
        double newX = (double)(left + newW / 2.0);
 
1288
        SetSize(newW, GetHeight());
 
1289
 
 
1290
        Move(newX, GetY());
 
1291
 
 
1292
        if (GetCanvas())
 
1293
                GetCanvas()->Refresh();
 
1294
 
 
1295
        return TRUE;
 
1296
}
 
1297
 
 
1298
bool wxDivisionShape::AdjustTop(double top, bool test)
 
1299
{
 
1300
        double y2 = (double)(GetY() + (GetHeight() / 2.0));
 
1301
 
 
1302
        if (top >= y2)
 
1303
                return FALSE;
 
1304
        if (test)
 
1305
                return TRUE;
 
1306
 
 
1307
        double newH = y2 - top;
 
1308
        double newY = (double)(top + newH / 2.0);
 
1309
        SetSize(GetWidth(), newH);
 
1310
 
 
1311
        Move(GetX(), newY);
 
1312
 
 
1313
        if (GetCanvas())
 
1314
                GetCanvas()->Refresh();
 
1315
 
 
1316
        return TRUE;
 
1317
}
 
1318
 
 
1319
bool wxDivisionShape::AdjustRight(double right, bool test)
 
1320
{
 
1321
        double x1 = (double)(GetX() - (GetWidth() / 2.0));
 
1322
 
 
1323
        if (right <= x1)
 
1324
                return FALSE;
 
1325
        if (test)
 
1326
                return TRUE;
 
1327
 
 
1328
        double newW = right - x1;
 
1329
        double newX = (double)(x1 + newW / 2.0);
 
1330
        SetSize(newW, GetHeight());
 
1331
 
 
1332
        Move(newX, GetY());
 
1333
 
 
1334
        if (GetCanvas())
 
1335
                GetCanvas()->Refresh();
 
1336
 
 
1337
        return TRUE;
 
1338
}
 
1339
 
 
1340
bool wxDivisionShape::AdjustBottom(double bottom, bool test)
 
1341
{
 
1342
        double y1 = (double)(GetY() - (GetHeight() / 2.0));
 
1343
 
 
1344
        if (bottom <= y1)
 
1345
                return FALSE;
 
1346
        if (test)
 
1347
                return TRUE;
 
1348
 
 
1349
        double newH = bottom - y1;
 
1350
        double newY = (double)(y1 + newH / 2.0);
 
1351
        SetSize(GetWidth(), newH);
 
1352
 
 
1353
        Move(GetX(), newY);
 
1354
 
 
1355
        if (GetCanvas())
 
1356
                GetCanvas()->Refresh();
 
1357
 
 
1358
        return TRUE;
 
1359
}
 
1360
 
 
1361
wxDivisionControlPoint::wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type):
 
1362
        wxControlPoint(the_canvas, object, size, the_xoffset, the_yoffset, the_type)
 
1363
{
 
1364
        SetEraseObject(FALSE);
 
1365
}
 
1366
 
 
1367
wxDivisionControlPoint::~wxDivisionControlPoint()
 
1368
{
 
1369
}
 
1370
 
 
1371
static double originalX = 0.0;
 
1372
static double originalY = 0.0;
 
1373
static double originalW = 0.0;
 
1374
static double originalH = 0.0;
 
1375
 
 
1376
// Implement resizing of canvas object
 
1377
void wxDivisionControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
 
1378
{
 
1379
        wxControlPoint::OnDragLeft(draw, x, y, keys, attachment);
 
1380
}
 
1381
 
 
1382
void wxDivisionControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment)
 
1383
{
 
1384
        wxDivisionShape *division = (wxDivisionShape *)m_shape;
 
1385
        originalX = division->GetX();
 
1386
        originalY = division->GetY();
 
1387
        originalW = division->GetWidth();
 
1388
        originalH = division->GetHeight();
 
1389
 
 
1390
        wxControlPoint::OnBeginDragLeft(x, y, keys, attachment);
 
1391
}
 
1392
 
 
1393
void wxDivisionControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment)
 
1394
{
 
1395
        wxControlPoint::OnEndDragLeft(x, y, keys, attachment);
 
1396
 
 
1397
        wxDivisionShape *division = (wxDivisionShape *)m_shape;
 
1398
        wxCompositeShape *divisionParent = (wxCompositeShape *)division->GetParent();
 
1399
 
 
1400
        // Need to check it's within the bounds of the parent composite.
 
1401
        double x1 = (double)(divisionParent->GetX() - (divisionParent->GetWidth() / 2.0));
 
1402
        double y1 = (double)(divisionParent->GetY() - (divisionParent->GetHeight() / 2.0));
 
1403
        double x2 = (double)(divisionParent->GetX() + (divisionParent->GetWidth() / 2.0));
 
1404
        double y2 = (double)(divisionParent->GetY() + (divisionParent->GetHeight() / 2.0));
 
1405
 
 
1406
        // Need to check it has not made the division zero or negative width/height
 
1407
        double dx1 = (double)(division->GetX() - (division->GetWidth() / 2.0));
 
1408
        double dy1 = (double)(division->GetY() - (division->GetHeight() / 2.0));
 
1409
        double dx2 = (double)(division->GetX() + (division->GetWidth() / 2.0));
 
1410
        double dy2 = (double)(division->GetY() + (division->GetHeight() / 2.0));
 
1411
 
 
1412
        bool success = TRUE;
 
1413
        switch (division->GetHandleSide())
 
1414
        {
 
1415
                case DIVISION_SIDE_LEFT:
 
1416
                {
 
1417
                        if ((x <= x1) || (x >= x2) || (x >= dx2))
 
1418
                                success = FALSE;
 
1419
                        // Try it out first...
 
1420
                        else if (!division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, TRUE))
 
1421
                                success = FALSE;
 
1422
                        else
 
1423
                                division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, FALSE);
 
1424
 
 
1425
                        break;
 
1426
                }
 
1427
                case DIVISION_SIDE_TOP:
 
1428
                {
 
1429
                        if ((y <= y1) || (y >= y2) || (y >= dy2))
 
1430
                                success = FALSE;
 
1431
                        else if (!division->ResizeAdjoining(DIVISION_SIDE_TOP, y, TRUE))
 
1432
                                success = FALSE;
 
1433
                        else
 
1434
                                division->ResizeAdjoining(DIVISION_SIDE_TOP, y, FALSE);
 
1435
 
 
1436
                        break;
 
1437
                }
 
1438
                case DIVISION_SIDE_RIGHT:
 
1439
                {
 
1440
                        if ((x <= x1) || (x >= x2) || (x <= dx1))
 
1441
                                success = FALSE;
 
1442
                        else if (!division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, TRUE))
 
1443
                                success = FALSE;
 
1444
                        else
 
1445
                                division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, FALSE);
 
1446
 
 
1447
                        break;
 
1448
                }
 
1449
                case DIVISION_SIDE_BOTTOM:
 
1450
                {
 
1451
                        if ((y <= y1) || (y >= y2) || (y <= dy1))
 
1452
                                success = FALSE;
 
1453
                        else if (!division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, TRUE))
 
1454
                                success = FALSE;
 
1455
                        else
 
1456
                                division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, FALSE);
 
1457
 
 
1458
                        break;
 
1459
                }
 
1460
        }
 
1461
        if (!success)
 
1462
        {
 
1463
                division->SetSize(originalW, originalH);
 
1464
                division->Move(originalX, originalY);
 
1465
        }
 
1466
 
 
1467
        if (GetCanvas())
 
1468
                GetCanvas()->Refresh();
 
1469
 
 
1470
}
 
1471
 
 
1472
/* Resize adjoining divisions.
 
1473
 *
 
1474
   Behaviour should be as follows:
 
1475
   If right edge moves, find all objects whose left edge
 
1476
   adjoins this object, and move left edge accordingly.
 
1477
   If left..., move ... right.
 
1478
   If top..., move ... bottom.
 
1479
   If bottom..., move top.
 
1480
   If size goes to zero or end position is other side of start position,
 
1481
   resize to original size and return.
 
1482
 */
 
1483
bool wxDivisionShape::ResizeAdjoining(int side, double newPos, bool test)
 
1484
{
 
1485
        wxCompositeShape *divisionParent = (wxCompositeShape *)GetParent();
 
1486
        wxNode *node = divisionParent->GetDivisions().GetFirst();
 
1487
        while (node)
 
1488
        {
 
1489
                wxDivisionShape *division = (wxDivisionShape *)node->GetData();
 
1490
                switch (side)
 
1491
                {
 
1492
                        case DIVISION_SIDE_LEFT:
 
1493
                        {
 
1494
                                if (division->m_rightSide == this)
 
1495
                                {
 
1496
                                        bool success = division->AdjustRight(newPos, test);
 
1497
                                        if (!success && test)
 
1498
                                                return FALSE;
 
1499
                                }
 
1500
                                break;
 
1501
                        }
 
1502
                        case DIVISION_SIDE_TOP:
 
1503
                        {
 
1504
                                if (division->m_bottomSide == this)
 
1505
                                {
 
1506
                                        bool success = division->AdjustBottom(newPos, test);
 
1507
                                        if (!success && test)
 
1508
                                                return FALSE;
 
1509
                                }
 
1510
                                break;
 
1511
                        }
 
1512
                        case DIVISION_SIDE_RIGHT:
 
1513
                        {
 
1514
                                if (division->m_leftSide == this)
 
1515
                                {
 
1516
                                        bool success = division->AdjustLeft(newPos, test);
 
1517
                                        if (!success && test)
 
1518
                                                return FALSE;
 
1519
                                }
 
1520
                                break;
 
1521
                        }
 
1522
                        case DIVISION_SIDE_BOTTOM:
 
1523
                        {
 
1524
                                if (division->m_topSide == this)
 
1525
                                {
 
1526
                                        bool success = division->AdjustTop(newPos, test);
 
1527
                                        if (!success && test)
 
1528
                                                return FALSE;
 
1529
                                }
 
1530
                                break;
 
1531
                        }
 
1532
                        default:
 
1533
                                break;
 
1534
                }
 
1535
                node = node->GetNext();
 
1536
        }
 
1537
 
 
1538
        return TRUE;
 
1539
}
 
1540
 
 
1541
/*
 
1542
 * Popup menu for editing divisions
 
1543
 *
 
1544
 */
 
1545
class OGLPopupDivisionMenu : public wxMenu
 
1546
{
 
1547
public:
 
1548
        OGLPopupDivisionMenu() : wxMenu()
 
1549
        {
 
1550
                Append(DIVISION_MENU_SPLIT_HORIZONTALLY, wxT("Split horizontally"));
 
1551
                Append(DIVISION_MENU_SPLIT_VERTICALLY, wxT("Split vertically"));
 
1552
                AppendSeparator();
 
1553
                Append(DIVISION_MENU_EDIT_LEFT_EDGE, wxT("Edit left edge"));
 
1554
                Append(DIVISION_MENU_EDIT_TOP_EDGE, wxT("Edit top edge"));
 
1555
        }
 
1556
 
 
1557
        void OnMenu(wxCommandEvent &event);
 
1558
 
 
1559
        DECLARE_EVENT_TABLE()
 
1560
};
 
1561
 
 
1562
BEGIN_EVENT_TABLE(OGLPopupDivisionMenu, wxMenu)
 
1563
        EVT_MENU_RANGE(DIVISION_MENU_SPLIT_HORIZONTALLY,
 
1564
                       DIVISION_MENU_EDIT_BOTTOM_EDGE,
 
1565
                       OGLPopupDivisionMenu::OnMenu)
 
1566
END_EVENT_TABLE()
 
1567
 
 
1568
 
 
1569
void OGLPopupDivisionMenu::OnMenu(wxCommandEvent &event)
 
1570
{
 
1571
        wxDivisionShape *division = (wxDivisionShape *)GetClientData();
 
1572
        switch (event.GetInt())
 
1573
        {
 
1574
                case DIVISION_MENU_SPLIT_HORIZONTALLY:
 
1575
                {
 
1576
                        division->Divide(wxHORIZONTAL);
 
1577
                        break;
 
1578
                }
 
1579
                case DIVISION_MENU_SPLIT_VERTICALLY:
 
1580
                {
 
1581
                        division->Divide(wxVERTICAL);
 
1582
                        break;
 
1583
                }
 
1584
                case DIVISION_MENU_EDIT_LEFT_EDGE:
 
1585
                {
 
1586
                        division->EditEdge(DIVISION_SIDE_LEFT);
 
1587
                        break;
 
1588
                }
 
1589
                case DIVISION_MENU_EDIT_TOP_EDGE:
 
1590
                {
 
1591
                        division->EditEdge(DIVISION_SIDE_TOP);
 
1592
                        break;
 
1593
                }
 
1594
                default:
 
1595
                        break;
 
1596
        }
 
1597
}
 
1598
 
 
1599
void wxDivisionShape::EditEdge(int WXUNUSED(side))
 
1600
{
 
1601
        wxMessageBox(wxT("EditEdge() not implemented"), wxT("OGL"), wxOK);
 
1602
 
 
1603
#if 0
 
1604
        wxBeginBusyCursor();
 
1605
 
 
1606
        wxPen *currentPen = NULL;
 
1607
        char **pColour = NULL;
 
1608
        char **pStyle = NULL;
 
1609
        if (side == DIVISION_SIDE_LEFT)
 
1610
        {
 
1611
                currentPen = m_leftSidePen;
 
1612
                pColour = &m_leftSideColour;
 
1613
                pStyle = &m_leftSideStyle;
 
1614
        }
 
1615
        else
 
1616
        {
 
1617
                currentPen = m_topSidePen;
 
1618
                pColour = &m_topSideColour;
 
1619
                pStyle = &m_topSideStyle;
 
1620
        }
 
1621
 
 
1622
        GraphicsForm *form = new GraphicsForm("Containers");
 
1623
        int lineWidth = currentPen->GetWidth();
 
1624
 
 
1625
        form->Add(wxMakeFormShort("Width", &lineWidth, wxFORM_DEFAULT, NULL, NULL, wxVERTICAL,
 
1626
                                  150));
 
1627
        form->Add(wxMakeFormString("Colour", pColour, wxFORM_CHOICE,
 
1628
                                   new wxList(wxMakeConstraintStrings(
 
1629
                                           "BLACK"            ,
 
1630
                                           "BLUE"             ,
 
1631
                                           "BROWN"            ,
 
1632
                                           "CORAL"            ,
 
1633
                                           "CYAN"             ,
 
1634
                                           "DARK GREY"        ,
 
1635
                                           "DARK GREEN"       ,
 
1636
                                           "DIM GREY"         ,
 
1637
                                           "GREY"             ,
 
1638
                                           "GREEN"            ,
 
1639
                                           "LIGHT BLUE"       ,
 
1640
                                           "LIGHT GREY"       ,
 
1641
                                           "MAGENTA"          ,
 
1642
                                           "MAROON"           ,
 
1643
                                           "NAVY"             ,
 
1644
                                           "ORANGE"           ,
 
1645
                                           "PURPLE"           ,
 
1646
                                           "RED"              ,
 
1647
                                           "TURQUOISE"        ,
 
1648
                                           "VIOLET"           ,
 
1649
                                           "WHITE"            ,
 
1650
                                           "YELLOW"           ,
 
1651
                                           NULL),
 
1652
                                              NULL), NULL, wxVERTICAL, 150));
 
1653
        form->Add(wxMakeFormString("Style", pStyle, wxFORM_CHOICE,
 
1654
                                   new wxList(wxMakeConstraintStrings(
 
1655
                                           "Solid"            ,
 
1656
                                           "Short Dash"       ,
 
1657
                                           "Long Dash"        ,
 
1658
                                           "Dot"              ,
 
1659
                                           "Dot Dash"         ,
 
1660
                                           NULL),
 
1661
                                              NULL), NULL, wxVERTICAL, 100));
 
1662
 
 
1663
        wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Division properties", 10, 10, 500, 500);
 
1664
        if (GraphicsLabelFont)
 
1665
                dialog->SetLabelFont(GraphicsLabelFont);
 
1666
        if (GraphicsButtonFont)
 
1667
                dialog->SetButtonFont(GraphicsButtonFont);
 
1668
 
 
1669
        form->AssociatePanel(dialog);
 
1670
        form->dialog = dialog;
 
1671
 
 
1672
        dialog->Fit();
 
1673
        dialog->Centre(wxBOTH);
 
1674
 
 
1675
        wxEndBusyCursor();
 
1676
        dialog->Show(TRUE);
 
1677
 
 
1678
        int lineStyle = wxSOLID;
 
1679
        if (*pStyle)
 
1680
        {
 
1681
                if (strcmp(*pStyle, "Solid") == 0)
 
1682
                        lineStyle = wxSOLID;
 
1683
                else if (strcmp(*pStyle, "Dot") == 0)
 
1684
                        lineStyle = wxDOT;
 
1685
                else if (strcmp(*pStyle, "Short Dash") == 0)
 
1686
                        lineStyle = wxSHORT_DASH;
 
1687
                else if (strcmp(*pStyle, "Long Dash") == 0)
 
1688
                        lineStyle = wxLONG_DASH;
 
1689
                else if (strcmp(*pStyle, "Dot Dash") == 0)
 
1690
                        lineStyle = wxDOT_DASH;
 
1691
        }
 
1692
 
 
1693
        wxPen *newPen = wxThePenList->FindOrCreatePen(*pColour, lineWidth, lineStyle);
 
1694
        if (!pen)
 
1695
                pen = wxBLACK_PEN;
 
1696
        if (side == DIVISION_SIDE_LEFT)
 
1697
                m_leftSidePen = newPen;
 
1698
        else
 
1699
                m_topSidePen = newPen;
 
1700
 
 
1701
        // Need to draw whole image again
 
1702
        wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent();
 
1703
        compositeParent->Draw(dc);
 
1704
#endif
 
1705
}
 
1706
 
 
1707
// Popup menu
 
1708
void wxDivisionShape::PopupMenu(double x, double y)
 
1709
{
 
1710
        wxMenu *oglPopupDivisionMenu = new OGLPopupDivisionMenu;
 
1711
 
 
1712
        oglPopupDivisionMenu->SetClientData((void *)this);
 
1713
        if (m_leftSide)
 
1714
                oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, TRUE);
 
1715
        else
 
1716
                oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, FALSE);
 
1717
        if (m_topSide)
 
1718
                oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, TRUE);
 
1719
        else
 
1720
                oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, FALSE);
 
1721
 
 
1722
        int x1, y1;
 
1723
        m_canvas->GetViewStart(&x1, &y1);
 
1724
 
 
1725
        int unit_x, unit_y;
 
1726
        m_canvas->GetScrollPixelsPerUnit(&unit_x, &unit_y);
 
1727
 
 
1728
        wxClientDC dc(GetCanvas());
 
1729
        GetCanvas()->PrepareDC(dc);
 
1730
 
 
1731
        int mouse_x = (int)(dc.LogicalToDeviceX((long)(x - x1 * unit_x)));
 
1732
        int mouse_y = (int)(dc.LogicalToDeviceY((long)(y - y1 * unit_y)));
 
1733
 
 
1734
        m_canvas->PopupMenu(oglPopupDivisionMenu, mouse_x, mouse_y);
 
1735
        delete oglPopupDivisionMenu;
 
1736
}
 
1737
 
 
1738
void wxDivisionShape::SetLeftSideColour(const wxString &colour)
 
1739
{
 
1740
        m_leftSideColour = colour;
 
1741
}
 
1742
 
 
1743
void wxDivisionShape::SetTopSideColour(const wxString &colour)
 
1744
{
 
1745
        m_topSideColour = colour;
 
1746
}
 
1747
 
 
1748
void wxDivisionShape::SetLeftSideStyle(const wxString &style)
 
1749
{
 
1750
        m_leftSideStyle = style;
 
1751
}
 
1752
 
 
1753
void wxDivisionShape::SetTopSideStyle(const wxString &style)
 
1754
{
 
1755
        m_topSideStyle = style;
 
1756
}
 
1757