1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Basic OGL classes
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
24 #include "wx/deprecated/wxexpr.h"
34 #include "wx/ogl/ogl.h"
37 // Control point types
38 // Rectangle and most other shapes
39 #define CONTROL_POINT_VERTICAL 1
40 #define CONTROL_POINT_HORIZONTAL 2
41 #define CONTROL_POINT_DIAGONAL 3
44 #define CONTROL_POINT_ENDPOINT_TO 4
45 #define CONTROL_POINT_ENDPOINT_FROM 5
46 #define CONTROL_POINT_LINE 6
48 IMPLEMENT_DYNAMIC_CLASS(wxShapeTextLine
, wxObject
)
49 IMPLEMENT_DYNAMIC_CLASS(wxAttachmentPoint
, wxObject
)
51 wxShapeTextLine::wxShapeTextLine(double the_x
, double the_y
, const wxString
& the_line
)
53 m_x
= the_x
; m_y
= the_y
; m_line
= the_line
;
56 wxShapeTextLine::~wxShapeTextLine()
60 IMPLEMENT_ABSTRACT_CLASS(wxShapeEvtHandler
, wxObject
)
62 wxShapeEvtHandler::wxShapeEvtHandler(wxShapeEvtHandler
*prev
, wxShape
*shape
)
64 m_previousHandler
= prev
;
65 m_handlerShape
= shape
;
68 wxShapeEvtHandler::~wxShapeEvtHandler()
72 // Creates a copy of this event handler.
73 wxShapeEvtHandler
* wxShapeEvtHandler::CreateNewCopy()
75 wxShapeEvtHandler
* newObject
= (wxShapeEvtHandler
*) GetClassInfo()->CreateObject();
77 wxASSERT( (newObject
!= NULL
) );
78 wxASSERT( (newObject
->IsKindOf(CLASSINFO(wxShapeEvtHandler
))) );
80 newObject
->m_previousHandler
= newObject
;
88 void wxShapeEvtHandler::OnDelete()
90 if (this != GetShape())
94 void wxShapeEvtHandler::OnDraw(wxDC
& dc
)
96 if (m_previousHandler
)
97 m_previousHandler
->OnDraw(dc
);
100 void wxShapeEvtHandler::OnMoveLinks(wxDC
& dc
)
102 if (m_previousHandler
)
103 m_previousHandler
->OnMoveLinks(dc
);
106 void wxShapeEvtHandler::OnMoveLink(wxDC
& dc
, bool moveControlPoints
)
108 if (m_previousHandler
)
109 m_previousHandler
->OnMoveLink(dc
, moveControlPoints
);
112 void wxShapeEvtHandler::OnDrawContents(wxDC
& dc
)
114 if (m_previousHandler
)
115 m_previousHandler
->OnDrawContents(dc
);
118 void wxShapeEvtHandler::OnDrawBranches(wxDC
& dc
, bool erase
)
120 if (m_previousHandler
)
121 m_previousHandler
->OnDrawBranches(dc
, erase
);
124 void wxShapeEvtHandler::OnSize(double x
, double y
)
126 if (m_previousHandler
)
127 m_previousHandler
->OnSize(x
, y
);
130 bool wxShapeEvtHandler::OnMovePre(wxDC
& dc
, double x
, double y
, double old_x
, double old_y
, bool display
)
132 if (m_previousHandler
)
133 return m_previousHandler
->OnMovePre(dc
, x
, y
, old_x
, old_y
, display
);
138 void wxShapeEvtHandler::OnMovePost(wxDC
& dc
, double x
, double y
, double old_x
, double old_y
, bool display
)
140 if (m_previousHandler
)
141 m_previousHandler
->OnMovePost(dc
, x
, y
, old_x
, old_y
, display
);
144 void wxShapeEvtHandler::OnErase(wxDC
& dc
)
146 if (m_previousHandler
)
147 m_previousHandler
->OnErase(dc
);
150 void wxShapeEvtHandler::OnEraseContents(wxDC
& dc
)
152 if (m_previousHandler
)
153 m_previousHandler
->OnEraseContents(dc
);
156 void wxShapeEvtHandler::OnHighlight(wxDC
& dc
)
158 if (m_previousHandler
)
159 m_previousHandler
->OnHighlight(dc
);
162 void wxShapeEvtHandler::OnLeftClick(double x
, double y
, int keys
, int attachment
)
164 if (m_previousHandler
)
165 m_previousHandler
->OnLeftClick(x
, y
, keys
, attachment
);
168 void wxShapeEvtHandler::OnLeftDoubleClick(double x
, double y
, int keys
, int attachment
)
170 if (m_previousHandler
)
171 m_previousHandler
->OnLeftDoubleClick(x
, y
, keys
, attachment
);
174 void wxShapeEvtHandler::OnRightClick(double x
, double y
, int keys
, int attachment
)
176 if (m_previousHandler
)
177 m_previousHandler
->OnRightClick(x
, y
, keys
, attachment
);
180 void wxShapeEvtHandler::OnDragLeft(bool draw
, double x
, double y
, int keys
, int attachment
)
182 if (m_previousHandler
)
183 m_previousHandler
->OnDragLeft(draw
, x
, y
, keys
, attachment
);
186 void wxShapeEvtHandler::OnBeginDragLeft(double x
, double y
, int keys
, int attachment
)
188 if (m_previousHandler
)
189 m_previousHandler
->OnBeginDragLeft(x
, y
, keys
, attachment
);
192 void wxShapeEvtHandler::OnEndDragLeft(double x
, double y
, int keys
, int attachment
)
194 if (m_previousHandler
)
195 m_previousHandler
->OnEndDragLeft(x
, y
, keys
, attachment
);
198 void wxShapeEvtHandler::OnDragRight(bool draw
, double x
, double y
, int keys
, int attachment
)
200 if (m_previousHandler
)
201 m_previousHandler
->OnDragRight(draw
, x
, y
, keys
, attachment
);
204 void wxShapeEvtHandler::OnBeginDragRight(double x
, double y
, int keys
, int attachment
)
206 if (m_previousHandler
)
207 m_previousHandler
->OnBeginDragRight(x
, y
, keys
, attachment
);
210 void wxShapeEvtHandler::OnEndDragRight(double x
, double y
, int keys
, int attachment
)
212 if (m_previousHandler
)
213 m_previousHandler
->OnEndDragRight(x
, y
, keys
, attachment
);
216 // Control points ('handles') redirect control to the actual shape, to make it easier
217 // to override sizing behaviour.
218 void wxShapeEvtHandler::OnSizingDragLeft(wxControlPoint
* pt
, bool draw
, double x
, double y
, int keys
, int attachment
)
220 if (m_previousHandler
)
221 m_previousHandler
->OnSizingDragLeft(pt
, draw
, x
, y
, keys
, attachment
);
224 void wxShapeEvtHandler::OnSizingBeginDragLeft(wxControlPoint
* pt
, double x
, double y
, int keys
, int attachment
)
226 if (m_previousHandler
)
227 m_previousHandler
->OnSizingBeginDragLeft(pt
, x
, y
, keys
, attachment
);
230 void wxShapeEvtHandler::OnSizingEndDragLeft(wxControlPoint
* pt
, double x
, double y
, int keys
, int attachment
)
232 if (m_previousHandler
)
233 m_previousHandler
->OnSizingEndDragLeft(pt
, x
, y
, keys
, attachment
);
236 void wxShapeEvtHandler::OnDrawOutline(wxDC
& dc
, double x
, double y
, double w
, double h
)
238 if (m_previousHandler
)
239 m_previousHandler
->OnDrawOutline(dc
, x
, y
, w
, h
);
242 void wxShapeEvtHandler::OnDrawControlPoints(wxDC
& dc
)
244 if (m_previousHandler
)
245 m_previousHandler
->OnDrawControlPoints(dc
);
248 void wxShapeEvtHandler::OnEraseControlPoints(wxDC
& dc
)
250 if (m_previousHandler
)
251 m_previousHandler
->OnEraseControlPoints(dc
);
254 // Can override this to prevent or intercept line reordering.
255 void wxShapeEvtHandler::OnChangeAttachment(int attachment
, wxLineShape
* line
, wxList
& ordering
)
257 if (m_previousHandler
)
258 m_previousHandler
->OnChangeAttachment(attachment
, line
, ordering
);
261 IMPLEMENT_ABSTRACT_CLASS(wxShape
, wxShapeEvtHandler
)
263 wxShape::wxShape(wxShapeCanvas
*can
)
265 m_eventHandler
= this;
270 m_xpos
= 0.0; m_ypos
= 0.0;
271 m_pen
= g_oglBlackPen
;
272 m_brush
= wxWHITE_BRUSH
;
273 m_font
= g_oglNormalFont
;
274 m_textColour
= wxT("BLACK");
275 m_textColourName
= wxT("BLACK");
278 m_attachmentMode
= ATTACHMENT_MODE_NONE
;
279 m_spaceAttachments
= true;
280 m_disableLabel
= false;
281 m_fixedWidth
= false;
282 m_fixedHeight
= false;
283 m_drawHandles
= true;
284 m_sensitivity
= OP_ALL
;
287 m_formatMode
= FORMAT_CENTRE_HORIZ
| FORMAT_CENTRE_VERT
;
288 m_shadowMode
= SHADOW_NONE
;
291 m_shadowBrush
= wxBLACK_BRUSH
;
294 m_regionName
= wxT("0");
295 m_centreResize
= true;
296 m_maintainAspectRatio
= false;
297 m_highlighted
= false;
299 m_branchNeckLength
= 10;
300 m_branchStemLength
= 10;
301 m_branchSpacing
= 10;
302 m_branchStyle
= BRANCHING_ATTACHMENT_NORMAL
;
304 // Set up a default region. Much of the above will be put into
305 // the region eventually (the duplication is for compatibility)
306 wxShapeRegion
*region
= new wxShapeRegion
;
307 m_regions
.Append(region
);
308 region
->SetName(wxT("0"));
309 region
->SetFont(g_oglNormalFont
);
310 region
->SetFormatMode(FORMAT_CENTRE_HORIZ
| FORMAT_CENTRE_VERT
);
311 region
->SetColour(wxT("BLACK"));
317 m_parent
->GetChildren().DeleteObject(this);
324 m_canvas
->RemoveShape(this);
326 GetEventHandler()->OnDelete();
329 void wxShape::SetHighlight(bool hi
, bool recurse
)
334 wxNode
*node
= m_children
.GetFirst();
337 wxShape
*child
= (wxShape
*)node
->GetData();
338 child
->SetHighlight(hi
, recurse
);
339 node
= node
->GetNext();
344 void wxShape::SetSensitivityFilter(int sens
, bool recursive
)
346 if (sens
& OP_DRAG_LEFT
)
351 m_sensitivity
= sens
;
354 wxNode
*node
= m_children
.GetFirst();
357 wxShape
*obj
= (wxShape
*)node
->GetData();
358 obj
->SetSensitivityFilter(sens
, true);
359 node
= node
->GetNext();
364 void wxShape::SetDraggable(bool drag
, bool recursive
)
368 m_sensitivity
|= OP_DRAG_LEFT
;
370 if (m_sensitivity
& OP_DRAG_LEFT
)
371 m_sensitivity
= m_sensitivity
- OP_DRAG_LEFT
;
375 wxNode
*node
= m_children
.GetFirst();
378 wxShape
*obj
= (wxShape
*)node
->GetData();
379 obj
->SetDraggable(drag
, true);
380 node
= node
->GetNext();
385 void wxShape::SetDrawHandles(bool drawH
)
387 m_drawHandles
= drawH
;
388 wxNode
*node
= m_children
.GetFirst();
391 wxShape
*obj
= (wxShape
*)node
->GetData();
392 obj
->SetDrawHandles(drawH
);
393 node
= node
->GetNext();
397 void wxShape::SetShadowMode(int mode
, bool redraw
)
399 if (redraw
&& GetCanvas())
401 wxClientDC
dc(GetCanvas());
402 GetCanvas()->PrepareDC(dc
);
415 void wxShape::SetCanvas(wxShapeCanvas
*theCanvas
)
417 m_canvas
= theCanvas
;
418 wxNode
*node
= m_children
.GetFirst();
421 wxShape
*child
= (wxShape
*)node
->GetData();
422 child
->SetCanvas(theCanvas
);
423 node
= node
->GetNext();
427 void wxShape::AddToCanvas(wxShapeCanvas
*theCanvas
, wxShape
*addAfter
)
429 theCanvas
->AddShape(this, addAfter
);
430 wxNode
*node
= m_children
.GetFirst();
431 wxShape
*lastImage
= this;
434 wxShape
*object
= (wxShape
*)node
->GetData();
435 object
->AddToCanvas(theCanvas
, lastImage
);
438 node
= node
->GetNext();
442 // Insert at front of canvas
443 void wxShape::InsertInCanvas(wxShapeCanvas
*theCanvas
)
445 theCanvas
->InsertShape(this);
446 wxNode
*node
= m_children
.GetFirst();
447 wxShape
*lastImage
= this;
450 wxShape
*object
= (wxShape
*)node
->GetData();
451 object
->AddToCanvas(theCanvas
, lastImage
);
454 node
= node
->GetNext();
458 void wxShape::RemoveFromCanvas(wxShapeCanvas
*theCanvas
)
462 theCanvas
->RemoveShape(this);
463 wxNode
*node
= m_children
.GetFirst();
466 wxShape
*object
= (wxShape
*)node
->GetData();
467 object
->RemoveFromCanvas(theCanvas
);
469 node
= node
->GetNext();
473 void wxShape::ClearAttachments()
475 wxNode
*node
= m_attachmentPoints
.GetFirst();
478 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
480 node
= node
->GetNext();
482 m_attachmentPoints
.Clear();
485 void wxShape::ClearText(int regionId
)
489 m_text
.DeleteContents(true);
491 m_text
.DeleteContents(false);
493 wxNode
*node
= m_regions
.Item(regionId
);
496 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
500 void wxShape::ClearRegions()
502 wxNode
*node
= m_regions
.GetFirst();
505 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
506 wxNode
*next
= node
->GetNext();
513 void wxShape::AddRegion(wxShapeRegion
*region
)
515 m_regions
.Append(region
);
518 void wxShape::SetDefaultRegionSize()
520 wxNode
*node
= m_regions
.GetFirst();
522 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
524 GetBoundingBoxMin(&w
, &h
);
525 region
->SetSize(w
, h
);
528 bool wxShape::HitTest(double x
, double y
, int *attachment
, double *distance
)
533 double width
= 0.0, height
= 0.0;
534 GetBoundingBoxMin(&width
, &height
);
535 if (fabs(width
) < 4.0) width
= 4.0;
536 if (fabs(height
) < 4.0) height
= 4.0;
538 width
+= (double)4.0; height
+= (double)4.0; // Allowance for inaccurate mousing
540 double left
= (double)(m_xpos
- (width
/2.0));
541 double top
= (double)(m_ypos
- (height
/2.0));
542 double right
= (double)(m_xpos
+ (width
/2.0));
543 double bottom
= (double)(m_ypos
+ (height
/2.0));
545 int nearest_attachment
= 0;
547 // If within the bounding box, check the attachment points
548 // within the object.
550 if (x
>= left
&& x
<= right
&& y
>= top
&& y
<= bottom
)
552 int n
= GetNumberOfAttachments();
553 double nearest
= 999999.0;
555 // GetAttachmentPosition[Edge] takes a logical attachment position,
556 // i.e. if it's rotated through 90%, position 0 is East-facing.
558 for (int i
= 0; i
< n
; i
++)
561 if (GetAttachmentPositionEdge(i
, &xp
, &yp
))
563 double l
= (double)sqrt(((xp
- x
) * (xp
- x
)) +
564 ((yp
- y
) * (yp
- y
)));
569 nearest_attachment
= i
;
573 *attachment
= nearest_attachment
;
580 // Format a text string according to the region size, adding
581 // strings with positions to region text list
583 static bool GraphicsInSizeToContents
= false; // Infinite recursion elimination
584 void wxShape::FormatText(wxDC
& dc
, const wxString
& s
, int i
)
589 if (m_regions
.GetCount() < 1)
591 wxNode
*node
= m_regions
.Item(i
);
595 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
596 // region->SetText(s); // don't set the formatted text yet, it will be done below
597 region
->m_regionText
= s
;
598 dc
.SetFont(* region
->GetFont());
600 region
->GetSize(&w
, &h
);
602 wxStringList
*stringList
= oglFormatText(dc
, s
, (w
-2*m_textMarginX
), (h
-2*m_textMarginY
), region
->GetFormatMode());
603 node
= (wxNode
*)stringList
->GetFirst();
606 wxChar
*s
= (wxChar
*)node
->GetData();
607 wxShapeTextLine
*line
= new wxShapeTextLine(0.0, 0.0, s
);
608 region
->GetFormattedText().Append((wxObject
*)line
);
609 node
= node
->GetNext();
614 // Don't try to resize an object with more than one image (this case should be dealt
615 // with by overriden handlers)
616 if ((region
->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS
) &&
617 (region
->GetFormattedText().GetCount() > 0) &&
618 (m_regions
.GetCount() == 1) && !GraphicsInSizeToContents
)
620 oglGetCentredTextExtent(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, w
, h
, &actualW
, &actualH
);
621 if ((actualW
+2*m_textMarginX
!= w
) || (actualH
+2*m_textMarginY
!= h
))
623 // If we are a descendant of a composite, must make sure the composite gets
625 wxShape
*topAncestor
= GetTopAncestor();
627 if (topAncestor
!= this)
629 // Make sure we don't recurse infinitely
630 GraphicsInSizeToContents
= true;
632 wxCompositeShape
*composite
= (wxCompositeShape
*)topAncestor
;
633 composite
->Erase(dc
);
634 SetSize(actualW
+2*m_textMarginX
, actualH
+2*m_textMarginY
);
635 Move(dc
, m_xpos
, m_ypos
);
636 composite
->CalculateSize();
637 if (composite
->Selected())
639 composite
->DeleteControlPoints(& dc
);
640 composite
->MakeControlPoints();
641 composite
->MakeMandatoryControlPoints();
643 // Where infinite recursion might happen if we didn't stop it
646 GraphicsInSizeToContents
= false;
651 SetSize(actualW
+2*m_textMarginX
, actualH
+2*m_textMarginY
);
652 Move(dc
, m_xpos
, m_ypos
);
654 SetSize(actualW
+2*m_textMarginX
, actualH
+2*m_textMarginY
);
655 Move(dc
, m_xpos
, m_ypos
);
659 oglCentreText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, actualW
-2*m_textMarginX
, actualH
-2*m_textMarginY
, region
->GetFormatMode());
663 void wxShape::Recentre(wxDC
& dc
)
666 GetBoundingBoxMin(&w
, &h
);
668 int noRegions
= m_regions
.GetCount();
669 for (int i
= 0; i
< noRegions
; i
++)
671 wxNode
*node
= m_regions
.Item(i
);
674 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
675 oglCentreText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, w
-2*m_textMarginX
, h
-2*m_textMarginY
, region
->GetFormatMode());
680 bool wxShape::GetPerimeterPoint(double WXUNUSED(x1
), double WXUNUSED(y1
),
681 double WXUNUSED(x2
), double WXUNUSED(y2
),
682 double *WXUNUSED(x3
), double *WXUNUSED(y3
))
687 void wxShape::SetPen(wxPen
*the_pen
)
692 void wxShape::SetBrush(wxBrush
*the_brush
)
697 // Get the top-most (non-division) ancestor, or self
698 wxShape
*wxShape::GetTopAncestor()
703 if (GetParent()->IsKindOf(CLASSINFO(wxDivisionShape
)))
705 else return GetParent()->GetTopAncestor();
712 void wxShape::SetFont(wxFont
*the_font
, int regionId
)
715 wxNode
*node
= m_regions
.Item(regionId
);
718 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
719 region
->SetFont(the_font
);
722 wxFont
*wxShape::GetFont(int n
) const
724 wxNode
*node
= m_regions
.Item(n
);
727 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
728 return region
->GetFont();
731 void wxShape::SetFormatMode(int mode
, int regionId
)
733 wxNode
*node
= m_regions
.Item(regionId
);
736 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
737 region
->SetFormatMode(mode
);
740 int wxShape::GetFormatMode(int regionId
) const
742 wxNode
*node
= m_regions
.Item(regionId
);
745 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
746 return region
->GetFormatMode();
749 void wxShape::SetTextColour(const wxString
& the_colour
, int regionId
)
751 m_textColour
= wxTheColourDatabase
->Find(the_colour
);
752 m_textColourName
= the_colour
;
754 wxNode
*node
= m_regions
.Item(regionId
);
757 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
758 region
->SetColour(the_colour
);
761 wxString
wxShape::GetTextColour(int regionId
) const
763 wxNode
*node
= m_regions
.Item(regionId
);
765 return wxEmptyString
;
766 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
767 return region
->GetColour();
770 void wxShape::SetRegionName(const wxString
& name
, int regionId
)
772 wxNode
*node
= m_regions
.Item(regionId
);
775 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
776 region
->SetName(name
);
779 wxString
wxShape::GetRegionName(int regionId
)
781 wxNode
*node
= m_regions
.Item(regionId
);
783 return wxEmptyString
;
784 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
785 return region
->GetName();
788 int wxShape::GetRegionId(const wxString
& name
)
790 wxNode
*node
= m_regions
.GetFirst();
794 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
795 if (region
->GetName() == name
)
797 node
= node
->GetNext();
803 // Name all m_regions in all subimages recursively.
804 void wxShape::NameRegions(const wxString
& parentName
)
806 int n
= GetNumberOfTextRegions();
808 for (int i
= 0; i
< n
; i
++)
810 if (parentName
.Length() > 0)
811 buff
<< parentName
<< wxT(".") << i
;
814 SetRegionName(buff
, i
);
816 wxNode
*node
= m_children
.GetFirst();
821 wxShape
*child
= (wxShape
*)node
->GetData();
822 if (parentName
.Length() > 0)
823 buff
<< parentName
<< wxT(".") << j
;
826 child
->NameRegions(buff
);
827 node
= node
->GetNext();
832 // Get a region by name, possibly looking recursively into composites.
833 wxShape
*wxShape::FindRegion(const wxString
& name
, int *regionId
)
835 int id
= GetRegionId(name
);
842 wxNode
*node
= m_children
.GetFirst();
845 wxShape
*child
= (wxShape
*)node
->GetData();
846 wxShape
*actualImage
= child
->FindRegion(name
, regionId
);
849 node
= node
->GetNext();
854 // Finds all region names for this image (composite or simple).
855 // Supply empty string list.
856 void wxShape::FindRegionNames(wxStringList
& list
)
858 int n
= GetNumberOfTextRegions();
859 for (int i
= 0; i
< n
; i
++)
861 wxString
name(GetRegionName(i
));
865 wxNode
*node
= m_children
.GetFirst();
868 wxShape
*child
= (wxShape
*)node
->GetData();
869 child
->FindRegionNames(list
);
870 node
= node
->GetNext();
874 void wxShape::AssignNewIds()
878 wxNode
*node
= m_children
.GetFirst();
881 wxShape
*child
= (wxShape
*)node
->GetData();
882 child
->AssignNewIds();
883 node
= node
->GetNext();
887 void wxShape::OnDraw(wxDC
& WXUNUSED(dc
))
891 void wxShape::OnMoveLinks(wxDC
& dc
)
893 // Want to set the ends of all attached links
894 // to point to/from this object
896 wxNode
*current
= m_lines
.GetFirst();
899 wxLineShape
*line
= (wxLineShape
*)current
->GetData();
900 line
->GetEventHandler()->OnMoveLink(dc
);
901 current
= current
->GetNext();
906 void wxShape::OnDrawContents(wxDC
& dc
)
908 double bound_x
, bound_y
;
909 GetBoundingBoxMin(&bound_x
, &bound_y
);
910 if (m_regions
.GetCount() < 1) return;
912 if (m_pen
) dc
.SetPen(* m_pen
);
914 wxShapeRegion
*region
= (wxShapeRegion
*)m_regions
.GetFirst()->GetData();
915 if (region
->GetFont()) dc
.SetFont(* region
->GetFont());
917 dc
.SetTextForeground(region
->GetActualColourObject());
918 dc
.SetBackgroundMode(wxTRANSPARENT
);
921 oglCentreText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, bound_x
-2*m_textMarginX
, bound_y
-2*m_textMarginY
, region
->GetFormatMode());
924 if (!GetDisableLabel())
926 oglDrawFormattedText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, bound_x
-2*m_textMarginX
, bound_y
-2*m_textMarginY
, region
->GetFormatMode());
930 void wxShape::DrawContents(wxDC
& dc
)
932 GetEventHandler()->OnDrawContents(dc
);
935 void wxShape::OnSize(double WXUNUSED(x
), double WXUNUSED(y
))
939 bool wxShape::OnMovePre(wxDC
& WXUNUSED(dc
), double WXUNUSED(x
), double WXUNUSED(y
), double WXUNUSED(old_x
), double WXUNUSED(old_y
), bool WXUNUSED(display
))
944 void wxShape::OnMovePost(wxDC
& WXUNUSED(dc
), double WXUNUSED(x
), double WXUNUSED(y
), double WXUNUSED(old_x
), double WXUNUSED(old_y
), bool WXUNUSED(display
))
948 void wxShape::OnErase(wxDC
& dc
)
954 wxNode
*current
= m_lines
.GetFirst();
957 wxLineShape
*line
= (wxLineShape
*)current
->GetData();
958 line
->GetEventHandler()->OnErase(dc
);
959 current
= current
->GetNext();
961 GetEventHandler()->OnEraseContents(dc
);
964 void wxShape::OnEraseContents(wxDC
& dc
)
969 double maxX
, maxY
, minX
, minY
;
972 GetBoundingBoxMin(&minX
, &minY
);
973 GetBoundingBoxMax(&maxX
, &maxY
);
974 double topLeftX
= (double)(xp
- (maxX
/ 2.0) - 2.0);
975 double topLeftY
= (double)(yp
- (maxY
/ 2.0) - 2.0);
979 penWidth
= m_pen
->GetWidth();
981 dc
.SetPen(GetBackgroundPen());
982 dc
.SetBrush(GetBackgroundBrush());
984 dc
.DrawRectangle(WXROUND(topLeftX
- penWidth
), WXROUND(topLeftY
- penWidth
),
985 WXROUND(maxX
+ penWidth
*2.0 + 4.0), WXROUND(maxY
+ penWidth
*2.0 + 4.0));
988 void wxShape::EraseLinks(wxDC
& dc
, int attachment
, bool recurse
)
993 wxNode
*current
= m_lines
.GetFirst();
996 wxLineShape
*line
= (wxLineShape
*)current
->GetData();
997 if (attachment
== -1 || ((line
->GetTo() == this && line
->GetAttachmentTo() == attachment
) ||
998 (line
->GetFrom() == this && line
->GetAttachmentFrom() == attachment
)))
999 line
->GetEventHandler()->OnErase(dc
);
1000 current
= current
->GetNext();
1004 wxNode
*node
= m_children
.GetFirst();
1007 wxShape
*child
= (wxShape
*)node
->GetData();
1008 child
->EraseLinks(dc
, attachment
, recurse
);
1009 node
= node
->GetNext();
1014 void wxShape::DrawLinks(wxDC
& dc
, int attachment
, bool recurse
)
1019 wxNode
*current
= m_lines
.GetFirst();
1022 wxLineShape
*line
= (wxLineShape
*)current
->GetData();
1023 if (attachment
== -1 ||
1024 (line
->GetTo() == this && line
->GetAttachmentTo() == attachment
) ||
1025 (line
->GetFrom() == this && line
->GetAttachmentFrom() == attachment
))
1027 current
= current
->GetNext();
1031 wxNode
*node
= m_children
.GetFirst();
1034 wxShape
*child
= (wxShape
*)node
->GetData();
1035 child
->DrawLinks(dc
, attachment
, recurse
);
1036 node
= node
->GetNext();
1041 // Returns true if pt1 <= pt2 in the sense that one point comes before another on an
1042 // edge of the shape.
1043 // attachmentPoint is the attachment point (= side) in question.
1045 // This is the default, rectangular implementation.
1046 bool wxShape::AttachmentSortTest(int attachmentPoint
, const wxRealPoint
& pt1
, const wxRealPoint
& pt2
)
1048 int physicalAttachment
= LogicalToPhysicalAttachment(attachmentPoint
);
1049 switch (physicalAttachment
)
1054 return (pt1
.x
<= pt2
.x
) ;
1059 return (pt1
.y
<= pt2
.y
) ;
1066 bool wxShape::MoveLineToNewAttachment(wxDC
& dc
, wxLineShape
*to_move
,
1069 if (GetAttachmentMode() == ATTACHMENT_MODE_NONE
)
1072 int newAttachment
, oldAttachment
;
1075 // Is (x, y) on this object? If so, find the new attachment point
1076 // the user has moved the point to
1077 bool hit
= HitTest(x
, y
, &newAttachment
, &distance
);
1083 if (to_move
->GetTo() == this)
1084 oldAttachment
= to_move
->GetAttachmentTo();
1086 oldAttachment
= to_move
->GetAttachmentFrom();
1088 // The links in a new ordering.
1091 // First, add all links to the new list.
1092 wxNode
*node
= m_lines
.GetFirst();
1095 newOrdering
.Append(node
->GetData());
1096 node
= node
->GetNext();
1099 // Delete the line object from the list of links; we're going to move
1100 // it to another position in the list
1101 newOrdering
.DeleteObject(to_move
);
1103 double old_x
= (double) -99999.9;
1104 double old_y
= (double) -99999.9;
1106 node
= newOrdering
.GetFirst();
1109 while (!found
&& node
)
1111 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1112 if ((line
->GetTo() == this && oldAttachment
== line
->GetAttachmentTo()) ||
1113 (line
->GetFrom() == this && oldAttachment
== line
->GetAttachmentFrom()))
1115 double startX
, startY
, endX
, endY
;
1117 line
->GetEnds(&startX
, &startY
, &endX
, &endY
);
1118 if (line
->GetTo() == this)
1128 wxRealPoint
thisPoint(xp
, yp
);
1129 wxRealPoint
lastPoint(old_x
, old_y
);
1130 wxRealPoint
newPoint(x
, y
);
1132 if (AttachmentSortTest(newAttachment
, newPoint
, thisPoint
) && AttachmentSortTest(newAttachment
, lastPoint
, newPoint
))
1135 newOrdering
.Insert(node
, to_move
);
1141 node
= node
->GetNext();
1145 newOrdering
.Append(to_move
);
1147 GetEventHandler()->OnChangeAttachment(newAttachment
, to_move
, newOrdering
);
1152 void wxShape::OnChangeAttachment(int attachment
, wxLineShape
* line
, wxList
& ordering
)
1154 if (line
->GetTo() == this)
1155 line
->SetAttachmentTo(attachment
);
1157 line
->SetAttachmentFrom(attachment
);
1159 ApplyAttachmentOrdering(ordering
);
1161 wxClientDC
dc(GetCanvas());
1162 GetCanvas()->PrepareDC(dc
);
1166 if (!GetCanvas()->GetQuickEditMode()) GetCanvas()->Redraw(dc
);
1169 // Reorders the lines according to the given list.
1170 void wxShape::ApplyAttachmentOrdering(wxList
& linesToSort
)
1172 // This is a temporary store of all the lines.
1175 wxNode
*node
= m_lines
.GetFirst();
1178 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1179 linesStore
.Append(line
);
1180 node
= node
->GetNext();;
1185 node
= linesToSort
.GetFirst();
1188 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1189 if (linesStore
.Member(line
))
1192 linesStore
.DeleteObject(line
);
1193 m_lines
.Append(line
);
1195 node
= node
->GetNext();
1198 // Now add any lines that haven't been listed in linesToSort.
1199 node
= linesStore
.GetFirst();
1202 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1203 m_lines
.Append(line
);
1204 node
= node
->GetNext();
1208 // Reorders the lines coming into the node image at this attachment
1209 // position, in the order in which they appear in linesToSort.
1210 // Any remaining lines not in the list will be added to the end.
1211 void wxShape::SortLines(int attachment
, wxList
& linesToSort
)
1213 // This is a temporary store of all the lines at this attachment
1214 // point. We'll tick them off as we've processed them.
1215 wxList linesAtThisAttachment
;
1217 wxNode
*node
= m_lines
.GetFirst();
1220 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1221 wxNode
*next
= node
->GetNext();
1222 if ((line
->GetTo() == this && line
->GetAttachmentTo() == attachment
) ||
1223 (line
->GetFrom() == this && line
->GetAttachmentFrom() == attachment
))
1225 linesAtThisAttachment
.Append(line
);
1229 else node
= node
->GetNext();
1232 node
= linesToSort
.GetFirst();
1235 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1236 if (linesAtThisAttachment
.Member(line
))
1239 linesAtThisAttachment
.DeleteObject(line
);
1240 m_lines
.Append(line
);
1242 node
= node
->GetNext();
1245 // Now add any lines that haven't been listed in linesToSort.
1246 node
= linesAtThisAttachment
.GetFirst();
1249 wxLineShape
*line
= (wxLineShape
*)node
->GetData();
1250 m_lines
.Append(line
);
1251 node
= node
->GetNext();
1255 void wxShape::OnHighlight(wxDC
& WXUNUSED(dc
))
1259 void wxShape::OnLeftClick(double x
, double y
, int keys
, int attachment
)
1261 if ((m_sensitivity
& OP_CLICK_LEFT
) != OP_CLICK_LEFT
)
1267 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1268 m_parent
->GetEventHandler()->OnLeftClick(x
, y
, keys
, attachment
);
1274 void wxShape::OnRightClick(double x
, double y
, int keys
, int attachment
)
1276 if ((m_sensitivity
& OP_CLICK_RIGHT
) != OP_CLICK_RIGHT
)
1282 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1283 m_parent
->GetEventHandler()->OnRightClick(x
, y
, keys
, attachment
);
1289 double DragOffsetX
= 0.0;
1290 double DragOffsetY
= 0.0;
1292 void wxShape::OnDragLeft(bool draw
, double x
, double y
, int keys
, int attachment
)
1294 if ((m_sensitivity
& OP_DRAG_LEFT
) != OP_DRAG_LEFT
)
1300 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1301 m_parent
->GetEventHandler()->OnDragLeft(draw
, x
, y
, keys
, attachment
);
1306 wxClientDC
dc(GetCanvas());
1307 GetCanvas()->PrepareDC(dc
);
1309 dc
.SetLogicalFunction(OGLRBLF
);
1311 wxPen
dottedPen(*wxBLACK
, 1, wxDOT
);
1312 dc
.SetPen(dottedPen
);
1313 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1316 xx
= x
+ DragOffsetX
;
1317 yy
= y
+ DragOffsetY
;
1319 m_canvas
->Snap(&xx
, &yy
);
1320 // m_xpos = xx; m_ypos = yy;
1322 GetBoundingBoxMax(&w
, &h
);
1323 GetEventHandler()->OnDrawOutline(dc
, xx
, yy
, w
, h
);
1326 void wxShape::OnBeginDragLeft(double x
, double y
, int keys
, int attachment
)
1328 if ((m_sensitivity
& OP_DRAG_LEFT
) != OP_DRAG_LEFT
)
1334 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1335 m_parent
->GetEventHandler()->OnBeginDragLeft(x
, y
, keys
, attachment
);
1340 DragOffsetX
= m_xpos
- x
;
1341 DragOffsetY
= m_ypos
- y
;
1343 wxClientDC
dc(GetCanvas());
1344 GetCanvas()->PrepareDC(dc
);
1346 // New policy: don't erase shape until end of drag.
1350 xx
= x
+ DragOffsetX
;
1351 yy
= y
+ DragOffsetY
;
1352 m_canvas
->Snap(&xx
, &yy
);
1353 // m_xpos = xx; m_ypos = yy;
1354 dc
.SetLogicalFunction(OGLRBLF
);
1356 wxPen
dottedPen(*wxBLACK
, 1, wxDOT
);
1357 dc
.SetPen(dottedPen
);
1358 dc
.SetBrush((* wxTRANSPARENT_BRUSH
));
1361 GetBoundingBoxMax(&w
, &h
);
1362 GetEventHandler()->OnDrawOutline(dc
, xx
, yy
, w
, h
);
1363 m_canvas
->CaptureMouse();
1366 void wxShape::OnEndDragLeft(double x
, double y
, int keys
, int attachment
)
1370 m_canvas
->ReleaseMouse();
1371 if ((m_sensitivity
& OP_DRAG_LEFT
) != OP_DRAG_LEFT
)
1377 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1378 m_parent
->GetEventHandler()->OnEndDragLeft(x
, y
, keys
, attachment
);
1383 wxClientDC
dc(GetCanvas());
1384 GetCanvas()->PrepareDC(dc
);
1386 dc
.SetLogicalFunction(wxCOPY
);
1388 double xx
= x
+ DragOffsetX
;
1389 double yy
= y
+ DragOffsetY
;
1390 m_canvas
->Snap(&xx
, &yy
);
1391 // canvas->Snap(&m_xpos, &m_ypos);
1393 // New policy: erase shape at end of drag.
1397 if (m_canvas
&& !m_canvas
->GetQuickEditMode()) m_canvas
->Redraw(dc
);
1400 void wxShape::OnDragRight(bool draw
, double x
, double y
, int keys
, int attachment
)
1402 if ((m_sensitivity
& OP_DRAG_RIGHT
) != OP_DRAG_RIGHT
)
1408 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1409 m_parent
->GetEventHandler()->OnDragRight(draw
, x
, y
, keys
, attachment
);
1415 void wxShape::OnBeginDragRight(double x
, double y
, int keys
, int attachment
)
1417 if ((m_sensitivity
& OP_DRAG_RIGHT
) != OP_DRAG_RIGHT
)
1423 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1424 m_parent
->GetEventHandler()->OnBeginDragRight(x
, y
, keys
, attachment
);
1430 void wxShape::OnEndDragRight(double x
, double y
, int keys
, int attachment
)
1432 if ((m_sensitivity
& OP_DRAG_RIGHT
) != OP_DRAG_RIGHT
)
1438 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1439 m_parent
->GetEventHandler()->OnEndDragRight(x
, y
, keys
, attachment
);
1445 void wxShape::OnDrawOutline(wxDC
& dc
, double x
, double y
, double w
, double h
)
1447 double top_left_x
= (double)(x
- w
/2.0);
1448 double top_left_y
= (double)(y
- h
/2.0);
1449 double top_right_x
= (double)(top_left_x
+ w
);
1450 double top_right_y
= (double)top_left_y
;
1451 double bottom_left_x
= (double)top_left_x
;
1452 double bottom_left_y
= (double)(top_left_y
+ h
);
1453 double bottom_right_x
= (double)top_right_x
;
1454 double bottom_right_y
= (double)bottom_left_y
;
1457 points
[0].x
= WXROUND(top_left_x
); points
[0].y
= WXROUND(top_left_y
);
1458 points
[1].x
= WXROUND(top_right_x
); points
[1].y
= WXROUND(top_right_y
);
1459 points
[2].x
= WXROUND(bottom_right_x
); points
[2].y
= WXROUND(bottom_right_y
);
1460 points
[3].x
= WXROUND(bottom_left_x
); points
[3].y
= WXROUND(bottom_left_y
);
1461 points
[4].x
= WXROUND(top_left_x
); points
[4].y
= WXROUND(top_left_y
);
1463 dc
.DrawLines(5, points
);
1466 void wxShape::Attach(wxShapeCanvas
*can
)
1471 void wxShape::Detach()
1476 void wxShape::Move(wxDC
& dc
, double x
, double y
, bool display
)
1478 double old_x
= m_xpos
;
1479 double old_y
= m_ypos
;
1481 if (!GetEventHandler()->OnMovePre(dc
, x
, y
, old_x
, old_y
, display
))
1488 m_xpos
= x
; m_ypos
= y
;
1490 ResetControlPoints();
1497 GetEventHandler()->OnMovePost(dc
, x
, y
, old_x
, old_y
, display
);
1500 void wxShape::MoveLinks(wxDC
& dc
)
1502 GetEventHandler()->OnMoveLinks(dc
);
1506 void wxShape::Draw(wxDC
& dc
)
1510 GetEventHandler()->OnDraw(dc
);
1511 GetEventHandler()->OnDrawContents(dc
);
1512 GetEventHandler()->OnDrawControlPoints(dc
);
1513 GetEventHandler()->OnDrawBranches(dc
);
1517 void wxShape::Flash()
1521 wxClientDC
dc(GetCanvas());
1522 GetCanvas()->PrepareDC(dc
);
1524 dc
.SetLogicalFunction(OGLRBLF
);
1526 dc
.SetLogicalFunction(wxCOPY
);
1531 void wxShape::Show(bool show
)
1534 wxNode
*node
= m_children
.GetFirst();
1537 wxShape
*image
= (wxShape
*)node
->GetData();
1539 node
= node
->GetNext();
1543 void wxShape::Erase(wxDC
& dc
)
1545 GetEventHandler()->OnErase(dc
);
1546 GetEventHandler()->OnEraseControlPoints(dc
);
1547 GetEventHandler()->OnDrawBranches(dc
, true);
1550 void wxShape::EraseContents(wxDC
& dc
)
1552 GetEventHandler()->OnEraseContents(dc
);
1555 void wxShape::AddText(const wxString
& string
)
1557 wxNode
*node
= m_regions
.GetFirst();
1560 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
1561 region
->ClearText();
1562 wxShapeTextLine
*new_line
=
1563 new wxShapeTextLine(0.0, 0.0, string
);
1564 region
->GetFormattedText().Append(new_line
);
1566 m_formatted
= false;
1569 void wxShape::SetSize(double x
, double y
, bool WXUNUSED(recursive
))
1571 SetAttachmentSize(x
, y
);
1572 SetDefaultRegionSize();
1575 void wxShape::SetAttachmentSize(double w
, double h
)
1579 double width
, height
;
1580 GetBoundingBoxMin(&width
, &height
);
1583 else scaleX
= w
/width
;
1586 else scaleY
= h
/height
;
1588 wxNode
*node
= m_attachmentPoints
.GetFirst();
1591 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
1592 point
->m_x
= (double)(point
->m_x
* scaleX
);
1593 point
->m_y
= (double)(point
->m_y
* scaleY
);
1594 node
= node
->GetNext();
1598 // Add line FROM this object
1599 void wxShape::AddLine(wxLineShape
*line
, wxShape
*other
,
1600 int attachFrom
, int attachTo
,
1601 // The line ordering
1602 int positionFrom
, int positionTo
)
1604 if (positionFrom
== -1)
1606 if (!m_lines
.Member(line
))
1607 m_lines
.Append(line
);
1611 // Don't preserve old ordering if we have new ordering instructions
1612 m_lines
.DeleteObject(line
);
1613 if (positionFrom
< (int) m_lines
.GetCount())
1615 wxNode
* node
= m_lines
.Item(positionFrom
);
1616 m_lines
.Insert(node
, line
);
1619 m_lines
.Append(line
);
1622 if (positionTo
== -1)
1624 if (!other
->m_lines
.Member(line
))
1625 other
->m_lines
.Append(line
);
1629 // Don't preserve old ordering if we have new ordering instructions
1630 other
->m_lines
.DeleteObject(line
);
1631 if (positionTo
< (int) other
->m_lines
.GetCount())
1633 wxNode
* node
= other
->m_lines
.Item(positionTo
);
1634 other
->m_lines
.Insert(node
, line
);
1637 other
->m_lines
.Append(line
);
1640 // Wrong: doesn't preserve ordering of shape already linked
1641 m_lines
.DeleteObject(line
);
1642 other
->m_lines
.DeleteObject(line
);
1644 if (positionFrom
== -1)
1645 m_lines
.Append(line
);
1648 if (positionFrom
< m_lines
.GetCount())
1650 wxNode
* node
= m_lines
.Item(positionFrom
);
1651 m_lines
.Insert(node
, line
);
1654 m_lines
.Append(line
);
1657 if (positionTo
== -1)
1658 other
->m_lines
.Append(line
);
1661 if (positionTo
< other
->m_lines
.GetCount())
1663 wxNode
* node
= other
->m_lines
.Item(positionTo
);
1664 other
->m_lines
.Insert(node
, line
);
1667 other
->m_lines
.Append(line
);
1671 line
->SetFrom(this);
1673 line
->SetAttachments(attachFrom
, attachTo
);
1676 void wxShape::RemoveLine(wxLineShape
*line
)
1678 if (line
->GetFrom() == this)
1679 line
->GetTo()->m_lines
.DeleteObject(line
);
1681 line
->GetFrom()->m_lines
.DeleteObject(line
);
1683 m_lines
.DeleteObject(line
);
1687 void wxShape::WriteAttributes(wxExpr
*clause
)
1689 clause
->AddAttributeValueString(_T("type"), GetClassInfo()->GetClassName());
1690 clause
->AddAttributeValue(_T("id"), m_id
);
1694 int penWidth
= m_pen
->GetWidth();
1695 int penStyle
= m_pen
->GetStyle();
1697 clause
->AddAttributeValue(_T("pen_width"), (long)penWidth
);
1698 if (penStyle
!= wxSOLID
)
1699 clause
->AddAttributeValue(_T("pen_style"), (long)penStyle
);
1701 wxString penColour
= wxTheColourDatabase
->FindName(m_pen
->GetColour());
1702 if (penColour
== wxEmptyString
)
1704 wxString
hex(oglColourToHex(m_pen
->GetColour()));
1705 hex
= wxString(_T("#")) + hex
;
1706 clause
->AddAttributeValueString(_T("pen_colour"), hex
);
1708 else if (penColour
!= _T("BLACK"))
1709 clause
->AddAttributeValueString(_T("pen_colour"), penColour
);
1714 wxString brushColour
= wxTheColourDatabase
->FindName(m_brush
->GetColour());
1716 if (brushColour
== wxEmptyString
)
1718 wxString
hex(oglColourToHex(m_brush
->GetColour()));
1719 hex
= wxString(_T("#")) + hex
;
1720 clause
->AddAttributeValueString(_T("brush_colour"), hex
);
1722 else if (brushColour
!= _T("WHITE"))
1723 clause
->AddAttributeValueString(_T("brush_colour"), brushColour
);
1725 if (m_brush
->GetStyle() != wxSOLID
)
1726 clause
->AddAttributeValue(_T("brush_style"), (long)m_brush
->GetStyle());
1731 int n_lines
= m_lines
.GetCount();
1734 wxExpr
*list
= new wxExpr(wxExprList
);
1735 wxNode
*node
= m_lines
.GetFirst();
1738 wxShape
*line
= (wxShape
*)node
->GetData();
1739 wxExpr
*id_expr
= new wxExpr(line
->GetId());
1740 list
->Append(id_expr
);
1741 node
= node
->GetNext();
1743 clause
->AddAttributeValue(_T("arcs"), list
);
1746 // Miscellaneous members
1747 if (m_attachmentMode
!= 0)
1748 clause
->AddAttributeValue(_T("use_attachments"), (long)m_attachmentMode
);
1749 if (m_sensitivity
!= OP_ALL
)
1750 clause
->AddAttributeValue(_T("sensitivity"), (long)m_sensitivity
);
1751 if (!m_spaceAttachments
)
1752 clause
->AddAttributeValue(_T("space_attachments"), (long)m_spaceAttachments
);
1754 clause
->AddAttributeValue(_T("fixed_width"), (long)m_fixedWidth
);
1756 clause
->AddAttributeValue(_T("fixed_height"), (long)m_fixedHeight
);
1757 if (m_shadowMode
!= SHADOW_NONE
)
1758 clause
->AddAttributeValue(_T("shadow_mode"), (long)m_shadowMode
);
1759 if (m_centreResize
!= true)
1760 clause
->AddAttributeValue(_T("centre_resize"), (long)0);
1761 clause
->AddAttributeValue(_T("maintain_aspect_ratio"), (long) m_maintainAspectRatio
);
1762 if (m_highlighted
!= false)
1763 clause
->AddAttributeValue(_T("hilite"), (long)m_highlighted
);
1765 if (m_parent
) // For composite objects
1766 clause
->AddAttributeValue(_T("parent"), (long)m_parent
->GetId());
1768 if (m_rotation
!= 0.0)
1769 clause
->AddAttributeValue(_T("rotation"), m_rotation
);
1771 if (!this->IsKindOf(CLASSINFO(wxLineShape
)))
1773 clause
->AddAttributeValue(_T("neck_length"), (long) m_branchNeckLength
);
1774 clause
->AddAttributeValue(_T("stem_length"), (long) m_branchStemLength
);
1775 clause
->AddAttributeValue(_T("branch_spacing"), (long) m_branchSpacing
);
1776 clause
->AddAttributeValue(_T("branch_style"), (long) m_branchStyle
);
1779 // Write user-defined attachment points, if any
1780 if (m_attachmentPoints
.GetCount() > 0)
1782 wxExpr
*attachmentList
= new wxExpr(wxExprList
);
1783 wxNode
*node
= m_attachmentPoints
.GetFirst();
1786 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
1787 wxExpr
*pointExpr
= new wxExpr(wxExprList
);
1788 pointExpr
->Append(new wxExpr((long)point
->m_id
));
1789 pointExpr
->Append(new wxExpr(point
->m_x
));
1790 pointExpr
->Append(new wxExpr(point
->m_y
));
1791 attachmentList
->Append(pointExpr
);
1792 node
= node
->GetNext();
1794 clause
->AddAttributeValue(_T("user_attachments"), attachmentList
);
1797 // Write text regions
1798 WriteRegions(clause
);
1801 void wxShape::WriteRegions(wxExpr
*clause
)
1803 // Output regions as region1 = (...), region2 = (...), etc
1804 // and formatted text as text1 = (...), text2 = (...) etc.
1806 wxChar regionNameBuf
[20];
1807 wxChar textNameBuf
[20];
1808 wxNode
*node
= m_regions
.GetFirst();
1811 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
1812 wxSprintf(regionNameBuf
, _T("region%d"), regionNo
);
1813 wxSprintf(textNameBuf
, _T("text%d"), regionNo
);
1815 // Original text and region attributes:
1816 // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
1817 // formatMode fontSize fontFamily fontStyle fontWeight textColour)
1818 wxExpr
*regionExpr
= new wxExpr(wxExprList
);
1819 regionExpr
->Append(new wxExpr(wxExprString
, region
->m_regionName
));
1820 regionExpr
->Append(new wxExpr(wxExprString
, region
->m_regionText
));
1822 regionExpr
->Append(new wxExpr(region
->m_x
));
1823 regionExpr
->Append(new wxExpr(region
->m_y
));
1824 regionExpr
->Append(new wxExpr(region
->GetWidth()));
1825 regionExpr
->Append(new wxExpr(region
->GetHeight()));
1827 regionExpr
->Append(new wxExpr(region
->m_minWidth
));
1828 regionExpr
->Append(new wxExpr(region
->m_minHeight
));
1829 regionExpr
->Append(new wxExpr(region
->m_regionProportionX
));
1830 regionExpr
->Append(new wxExpr(region
->m_regionProportionY
));
1832 regionExpr
->Append(new wxExpr((long)region
->m_formatMode
));
1834 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetPointSize() : 10)));
1835 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetFamily() : wxDEFAULT
)));
1836 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetStyle() : wxDEFAULT
)));
1837 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetWeight() : wxNORMAL
)));
1838 regionExpr
->Append(new wxExpr(wxExprString
, region
->m_textColour
));
1840 // New members for pen colour/style
1841 regionExpr
->Append(new wxExpr(wxExprString
, region
->m_penColour
));
1842 regionExpr
->Append(new wxExpr((long)region
->m_penStyle
));
1845 // text1 = ((x y string) (x y string) ...)
1846 wxExpr
*textExpr
= new wxExpr(wxExprList
);
1848 wxNode
*textNode
= region
->m_formattedText
.GetFirst();
1851 wxShapeTextLine
*line
= (wxShapeTextLine
*)textNode
->GetData();
1852 wxExpr
*list2
= new wxExpr(wxExprList
);
1853 list2
->Append(new wxExpr(line
->GetX()));
1854 list2
->Append(new wxExpr(line
->GetY()));
1855 list2
->Append(new wxExpr(wxExprString
, line
->GetText()));
1856 textExpr
->Append(list2
);
1857 textNode
= textNode
->GetNext();
1860 // Now add both attributes to the clause
1861 clause
->AddAttributeValue(regionNameBuf
, regionExpr
);
1862 clause
->AddAttributeValue(textNameBuf
, textExpr
);
1864 node
= node
->GetNext();
1869 void wxShape::ReadAttributes(wxExpr
*clause
)
1871 clause
->GetAttributeValue(_T("id"), m_id
);
1874 clause
->GetAttributeValue(_T("x"), m_xpos
);
1875 clause
->GetAttributeValue(_T("y"), m_ypos
);
1877 // Input text strings (FOR COMPATIBILITY WITH OLD FILES ONLY. SEE REGION CODE BELOW.)
1879 wxExpr
*strings
= clause
->AttributeValue(_T("text"));
1880 if (strings
&& strings
->Type() == wxExprList
)
1882 m_formatted
= true; // Assume text is formatted unless we prove otherwise
1883 wxExpr
*node
= strings
->value
.first
;
1886 wxExpr
*string_expr
= node
;
1889 wxString the_string
= wxEmptyString
;
1891 // string_expr can either be a string, or a list of
1892 // 3 elements: x, y, and string.
1893 if (string_expr
->Type() == wxExprString
)
1895 the_string
= string_expr
->StringValue();
1896 m_formatted
= false;
1898 else if (string_expr
->Type() == wxExprList
)
1900 wxExpr
*first
= string_expr
->value
.first
;
1901 wxExpr
*second
= first
? first
->next
: (wxExpr
*) NULL
;
1902 wxExpr
*third
= second
? second
->next
: (wxExpr
*) NULL
;
1904 if (first
&& second
&& third
&&
1905 (first
->Type() == wxExprReal
|| first
->Type() == wxExprInteger
) &&
1906 (second
->Type() == wxExprReal
|| second
->Type() == wxExprInteger
) &&
1907 third
->Type() == wxExprString
)
1909 if (first
->Type() == wxExprReal
)
1910 the_x
= first
->RealValue();
1911 else the_x
= (double)first
->IntegerValue();
1913 if (second
->Type() == wxExprReal
)
1914 the_y
= second
->RealValue();
1915 else the_y
= (double)second
->IntegerValue();
1917 the_string
= third
->StringValue();
1920 wxShapeTextLine
*line
=
1921 new wxShapeTextLine(the_x
, the_y
, the_string
);
1922 m_text
.Append(line
);
1928 wxString pen_string
= wxEmptyString
;
1929 wxString brush_string
= wxEmptyString
;
1931 int pen_style
= wxSOLID
;
1932 int brush_style
= wxSOLID
;
1933 m_attachmentMode
= ATTACHMENT_MODE_NONE
;
1935 clause
->GetAttributeValue(_T("pen_colour"), pen_string
);
1936 clause
->GetAttributeValue(_T("text_colour"), m_textColourName
);
1938 SetTextColour(m_textColourName
);
1940 clause
->GetAttributeValue(_T("region_name"), m_regionName
);
1942 clause
->GetAttributeValue(_T("brush_colour"), brush_string
);
1943 clause
->GetAttributeValue(_T("pen_width"), pen_width
);
1944 clause
->GetAttributeValue(_T("pen_style"), pen_style
);
1945 clause
->GetAttributeValue(_T("brush_style"), brush_style
);
1947 int iVal
= (int) m_attachmentMode
;
1948 clause
->GetAttributeValue(_T("use_attachments"), iVal
);
1949 m_attachmentMode
= iVal
;
1951 clause
->GetAttributeValue(_T("sensitivity"), m_sensitivity
);
1953 iVal
= (int) m_spaceAttachments
;
1954 clause
->GetAttributeValue(_T("space_attachments"), iVal
);
1955 m_spaceAttachments
= (iVal
!= 0);
1957 iVal
= (int) m_fixedWidth
;
1958 clause
->GetAttributeValue(_T("fixed_width"), iVal
);
1959 m_fixedWidth
= (iVal
!= 0);
1961 iVal
= (int) m_fixedHeight
;
1962 clause
->GetAttributeValue(_T("fixed_height"), iVal
);
1963 m_fixedHeight
= (iVal
!= 0);
1965 clause
->GetAttributeValue(_T("format_mode"), m_formatMode
);
1966 clause
->GetAttributeValue(_T("shadow_mode"), m_shadowMode
);
1968 iVal
= m_branchNeckLength
;
1969 clause
->GetAttributeValue(_T("neck_length"), iVal
);
1970 m_branchNeckLength
= iVal
;
1972 iVal
= m_branchStemLength
;
1973 clause
->GetAttributeValue(_T("stem_length"), iVal
);
1974 m_branchStemLength
= iVal
;
1976 iVal
= m_branchSpacing
;
1977 clause
->GetAttributeValue(_T("branch_spacing"), iVal
);
1978 m_branchSpacing
= iVal
;
1980 clause
->GetAttributeValue(_T("branch_style"), m_branchStyle
);
1982 iVal
= (int) m_centreResize
;
1983 clause
->GetAttributeValue(_T("centre_resize"), iVal
);
1984 m_centreResize
= (iVal
!= 0);
1986 iVal
= (int) m_maintainAspectRatio
;
1987 clause
->GetAttributeValue(_T("maintain_aspect_ratio"), iVal
);
1988 m_maintainAspectRatio
= (iVal
!= 0);
1990 iVal
= (int) m_highlighted
;
1991 clause
->GetAttributeValue(_T("hilite"), iVal
);
1992 m_highlighted
= (iVal
!= 0);
1994 clause
->GetAttributeValue(_T("rotation"), m_rotation
);
1996 if (pen_string
== wxEmptyString
)
1997 pen_string
= _T("BLACK");
1998 if (brush_string
== wxEmptyString
)
1999 brush_string
= _T("WHITE");
2001 if (pen_string
.GetChar(0) == '#')
2003 wxColour
col(oglHexToColour(pen_string
.After('#')));
2004 m_pen
= wxThePenList
->FindOrCreatePen(col
, pen_width
, pen_style
);
2007 m_pen
= wxThePenList
->FindOrCreatePen(pen_string
, pen_width
, pen_style
);
2010 m_pen
= wxBLACK_PEN
;
2012 if (brush_string
.GetChar(0) == '#')
2014 wxColour
col(oglHexToColour(brush_string
.After('#')));
2015 m_brush
= wxTheBrushList
->FindOrCreateBrush(col
, brush_style
);
2018 m_brush
= wxTheBrushList
->FindOrCreateBrush(brush_string
, brush_style
);
2021 m_brush
= wxWHITE_BRUSH
;
2023 int point_size
= 10;
2024 clause
->GetAttributeValue(_T("point_size"), point_size
);
2025 SetFont(oglMatchFont(point_size
));
2027 // Read user-defined attachment points, if any
2028 wxExpr
*attachmentList
= clause
->AttributeValue(_T("user_attachments"));
2031 wxExpr
*pointExpr
= attachmentList
->GetFirst();
2034 wxExpr
*idExpr
= pointExpr
->Nth(0);
2035 wxExpr
*xExpr
= pointExpr
->Nth(1);
2036 wxExpr
*yExpr
= pointExpr
->Nth(2);
2037 if (idExpr
&& xExpr
&& yExpr
)
2039 wxAttachmentPoint
*point
= new wxAttachmentPoint
;
2040 point
->m_id
= (int)idExpr
->IntegerValue();
2041 point
->m_x
= xExpr
->RealValue();
2042 point
->m_y
= yExpr
->RealValue();
2043 m_attachmentPoints
.Append((wxObject
*)point
);
2045 pointExpr
= pointExpr
->GetNext();
2049 // Read text regions
2050 ReadRegions(clause
);
2053 void wxShape::ReadRegions(wxExpr
*clause
)
2057 // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
2058 // formatMode fontSize fontFamily fontStyle fontWeight textColour)
2060 wxChar regionNameBuf
[20];
2061 wxChar textNameBuf
[20];
2064 wxExpr
*textExpr
= NULL
;
2065 wxSprintf(regionNameBuf
, _T("region%d"), regionNo
);
2066 wxSprintf(textNameBuf
, _T("text%d"), regionNo
);
2068 m_formatted
= true; // Assume text is formatted unless we prove otherwise
2070 while ((regionExpr
= clause
->AttributeValue(regionNameBuf
)) != NULL
)
2073 * Get the region information
2077 wxString regionName
= wxEmptyString
;
2078 wxString regionText
= wxEmptyString
;
2082 double height
= 0.0;
2083 double minWidth
= 5.0;
2084 double minHeight
= 5.0;
2085 double m_regionProportionX
= -1.0;
2086 double m_regionProportionY
= -1.0;
2087 int formatMode
= FORMAT_NONE
;
2089 int fontFamily
= wxSWISS
;
2090 int fontStyle
= wxNORMAL
;
2091 int fontWeight
= wxNORMAL
;
2092 wxString regionTextColour
= wxEmptyString
;
2093 wxString penColour
= wxEmptyString
;
2094 int penStyle
= wxSOLID
;
2096 if (regionExpr
->Type() == wxExprList
)
2098 wxExpr
*nameExpr
= regionExpr
->Nth(0);
2099 wxExpr
*textExpr
= regionExpr
->Nth(1);
2100 wxExpr
*xExpr
= regionExpr
->Nth(2);
2101 wxExpr
*yExpr
= regionExpr
->Nth(3);
2102 wxExpr
*widthExpr
= regionExpr
->Nth(4);
2103 wxExpr
*heightExpr
= regionExpr
->Nth(5);
2104 wxExpr
*minWidthExpr
= regionExpr
->Nth(6);
2105 wxExpr
*minHeightExpr
= regionExpr
->Nth(7);
2106 wxExpr
*propXExpr
= regionExpr
->Nth(8);
2107 wxExpr
*propYExpr
= regionExpr
->Nth(9);
2108 wxExpr
*formatExpr
= regionExpr
->Nth(10);
2109 wxExpr
*sizeExpr
= regionExpr
->Nth(11);
2110 wxExpr
*familyExpr
= regionExpr
->Nth(12);
2111 wxExpr
*styleExpr
= regionExpr
->Nth(13);
2112 wxExpr
*weightExpr
= regionExpr
->Nth(14);
2113 wxExpr
*colourExpr
= regionExpr
->Nth(15);
2114 wxExpr
*penColourExpr
= regionExpr
->Nth(16);
2115 wxExpr
*penStyleExpr
= regionExpr
->Nth(17);
2117 regionName
= nameExpr
->StringValue();
2118 regionText
= textExpr
->StringValue();
2120 x
= xExpr
->RealValue();
2121 y
= yExpr
->RealValue();
2123 width
= widthExpr
->RealValue();
2124 height
= heightExpr
->RealValue();
2126 minWidth
= minWidthExpr
->RealValue();
2127 minHeight
= minHeightExpr
->RealValue();
2129 m_regionProportionX
= propXExpr
->RealValue();
2130 m_regionProportionY
= propYExpr
->RealValue();
2132 formatMode
= (int) formatExpr
->IntegerValue();
2133 fontSize
= (int)sizeExpr
->IntegerValue();
2134 fontFamily
= (int)familyExpr
->IntegerValue();
2135 fontStyle
= (int)styleExpr
->IntegerValue();
2136 fontWeight
= (int)weightExpr
->IntegerValue();
2140 regionTextColour
= colourExpr
->StringValue();
2143 regionTextColour
= _T("BLACK");
2146 penColour
= penColourExpr
->StringValue();
2148 penStyle
= (int)penStyleExpr
->IntegerValue();
2150 wxFont
*font
= wxTheFontList
->FindOrCreateFont(fontSize
, fontFamily
, fontStyle
, fontWeight
);
2152 wxShapeRegion
*region
= new wxShapeRegion
;
2153 region
->SetProportions(m_regionProportionX
, m_regionProportionY
);
2154 region
->SetFont(font
);
2155 region
->SetSize(width
, height
);
2156 region
->SetPosition(x
, y
);
2157 region
->SetMinSize(minWidth
, minHeight
);
2158 region
->SetFormatMode(formatMode
);
2159 region
->SetPenStyle(penStyle
);
2160 if (penColour
!= wxEmptyString
)
2161 region
->SetPenColour(penColour
);
2163 region
->m_textColour
= regionTextColour
;
2164 region
->m_regionText
= regionText
;
2165 region
->m_regionName
= regionName
;
2167 m_regions
.Append(region
);
2170 * Get the formatted text strings
2173 textExpr
= clause
->AttributeValue(textNameBuf
);
2174 if (textExpr
&& (textExpr
->Type() == wxExprList
))
2176 wxExpr
*node
= textExpr
->value
.first
;
2179 wxExpr
*string_expr
= node
;
2182 wxString the_string
= wxEmptyString
;
2184 // string_expr can either be a string, or a list of
2185 // 3 elements: x, y, and string.
2186 if (string_expr
->Type() == wxExprString
)
2188 the_string
= string_expr
->StringValue();
2189 m_formatted
= false;
2191 else if (string_expr
->Type() == wxExprList
)
2193 wxExpr
*first
= string_expr
->value
.first
;
2194 wxExpr
*second
= first
? first
->next
: (wxExpr
*) NULL
;
2195 wxExpr
*third
= second
? second
->next
: (wxExpr
*) NULL
;
2197 if (first
&& second
&& third
&&
2198 (first
->Type() == wxExprReal
|| first
->Type() == wxExprInteger
) &&
2199 (second
->Type() == wxExprReal
|| second
->Type() == wxExprInteger
) &&
2200 third
->Type() == wxExprString
)
2202 if (first
->Type() == wxExprReal
)
2203 the_x
= first
->RealValue();
2204 else the_x
= (double)first
->IntegerValue();
2206 if (second
->Type() == wxExprReal
)
2207 the_y
= second
->RealValue();
2208 else the_y
= (double)second
->IntegerValue();
2210 the_string
= third
->StringValue();
2215 wxShapeTextLine
*line
=
2216 new wxShapeTextLine(the_x
, the_y
, the_string
);
2217 region
->m_formattedText
.Append(line
);
2224 wxSprintf(regionNameBuf
, _T("region%d"), regionNo
);
2225 wxSprintf(textNameBuf
, _T("text%d"), regionNo
);
2228 // Compatibility: check for no regions (old file).
2229 // Lines and divided rectangles must deal with this compatibility
2230 // theirselves. Composites _may_ not have any regions anyway.
2231 if ((m_regions
.GetCount() == 0) &&
2232 !this->IsKindOf(CLASSINFO(wxLineShape
)) && !this->IsKindOf(CLASSINFO(wxDividedShape
)) &&
2233 !this->IsKindOf(CLASSINFO(wxCompositeShape
)))
2235 wxShapeRegion
*newRegion
= new wxShapeRegion
;
2236 newRegion
->SetName(_T("0"));
2237 m_regions
.Append((wxObject
*)newRegion
);
2238 if (m_text
.GetCount() > 0)
2240 newRegion
->ClearText();
2241 wxNode
*node
= m_text
.GetFirst();
2244 wxShapeTextLine
*textLine
= (wxShapeTextLine
*)node
->GetData();
2245 wxNode
*next
= node
->GetNext();
2246 newRegion
->GetFormattedText().Append((wxObject
*)textLine
);
2256 void wxShape::Copy(wxShape
& copy
)
2259 copy
.m_xpos
= m_xpos
;
2260 copy
.m_ypos
= m_ypos
;
2262 copy
.m_brush
= m_brush
;
2263 copy
.m_textColour
= m_textColour
;
2264 copy
.m_centreResize
= m_centreResize
;
2265 copy
.m_maintainAspectRatio
= m_maintainAspectRatio
;
2266 copy
.m_attachmentMode
= m_attachmentMode
;
2267 copy
.m_spaceAttachments
= m_spaceAttachments
;
2268 copy
.m_highlighted
= m_highlighted
;
2269 copy
.m_rotation
= m_rotation
;
2270 copy
.m_textColourName
= m_textColourName
;
2271 copy
.m_regionName
= m_regionName
;
2273 copy
.m_sensitivity
= m_sensitivity
;
2274 copy
.m_draggable
= m_draggable
;
2275 copy
.m_fixedWidth
= m_fixedWidth
;
2276 copy
.m_fixedHeight
= m_fixedHeight
;
2277 copy
.m_formatMode
= m_formatMode
;
2278 copy
.m_drawHandles
= m_drawHandles
;
2280 copy
.m_visible
= m_visible
;
2281 copy
.m_shadowMode
= m_shadowMode
;
2282 copy
.m_shadowOffsetX
= m_shadowOffsetX
;
2283 copy
.m_shadowOffsetY
= m_shadowOffsetY
;
2284 copy
.m_shadowBrush
= m_shadowBrush
;
2286 copy
.m_branchNeckLength
= m_branchNeckLength
;
2287 copy
.m_branchStemLength
= m_branchStemLength
;
2288 copy
.m_branchSpacing
= m_branchSpacing
;
2290 // Copy text regions
2291 copy
.ClearRegions();
2292 wxNode
*node
= m_regions
.GetFirst();
2295 wxShapeRegion
*region
= (wxShapeRegion
*)node
->GetData();
2296 wxShapeRegion
*newRegion
= new wxShapeRegion(*region
);
2297 copy
.m_regions
.Append(newRegion
);
2298 node
= node
->GetNext();
2302 copy
.ClearAttachments();
2303 node
= m_attachmentPoints
.GetFirst();
2306 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
2307 wxAttachmentPoint
*newPoint
= new wxAttachmentPoint
;
2308 newPoint
->m_id
= point
->m_id
;
2309 newPoint
->m_x
= point
->m_x
;
2310 newPoint
->m_y
= point
->m_y
;
2311 copy
.m_attachmentPoints
.Append((wxObject
*)newPoint
);
2312 node
= node
->GetNext();
2316 copy
.m_lines
.Clear();
2317 node
= m_lines
.GetFirst();
2320 wxLineShape
* line
= (wxLineShape
*) node
->GetData();
2321 copy
.m_lines
.Append(line
);
2322 node
= node
->GetNext();
2326 // Create and return a new, fully copied object.
2327 wxShape
*wxShape::CreateNewCopy(bool resetMapping
, bool recompute
)
2330 oglObjectCopyMapping
.Clear();
2332 wxShape
* newObject
= (wxShape
*) GetClassInfo()->CreateObject();
2334 wxASSERT( (newObject
!= NULL
) );
2335 wxASSERT( (newObject
->IsKindOf(CLASSINFO(wxShape
))) );
2339 if (GetEventHandler() != this)
2341 wxShapeEvtHandler
* newHandler
= GetEventHandler()->CreateNewCopy();
2342 newObject
->SetEventHandler(newHandler
);
2343 newObject
->SetPreviousHandler(NULL
);
2344 newHandler
->SetPreviousHandler(newObject
);
2345 newHandler
->SetShape(newObject
);
2349 newObject
->Recompute();
2353 // Does the copying for this object, including copying event
2354 // handler data if any. Calls the virtual Copy function.
2355 void wxShape::CopyWithHandler(wxShape
& copy
)
2359 if (GetEventHandler() != this)
2361 wxASSERT( copy
.GetEventHandler() != NULL
);
2362 wxASSERT( copy
.GetEventHandler() != (©
) );
2363 wxASSERT( GetEventHandler()->GetClassInfo() == copy
.GetEventHandler()->GetClassInfo() );
2364 GetEventHandler()->CopyData(* (copy
.GetEventHandler()));
2369 // Default - make 6 control points
2370 void wxShape::MakeControlPoints()
2372 double maxX
, maxY
, minX
, minY
;
2374 GetBoundingBoxMax(&maxX
, &maxY
);
2375 GetBoundingBoxMin(&minX
, &minY
);
2377 double widthMin
= (double)(minX
+ CONTROL_POINT_SIZE
+ 2);
2378 double heightMin
= (double)(minY
+ CONTROL_POINT_SIZE
+ 2);
2380 // Offsets from main object
2381 double top
= (double)(- (heightMin
/ 2.0));
2382 double bottom
= (double)(heightMin
/ 2.0 + (maxY
- minY
));
2383 double left
= (double)(- (widthMin
/ 2.0));
2384 double right
= (double)(widthMin
/ 2.0 + (maxX
- minX
));
2386 wxControlPoint
*control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, top
,
2387 CONTROL_POINT_DIAGONAL
);
2388 m_canvas
->AddShape(control
);
2389 m_controlPoints
.Append(control
);
2391 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, 0, top
,
2392 CONTROL_POINT_VERTICAL
);
2393 m_canvas
->AddShape(control
);
2394 m_controlPoints
.Append(control
);
2396 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, top
,
2397 CONTROL_POINT_DIAGONAL
);
2398 m_canvas
->AddShape(control
);
2399 m_controlPoints
.Append(control
);
2401 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, 0,
2402 CONTROL_POINT_HORIZONTAL
);
2403 m_canvas
->AddShape(control
);
2404 m_controlPoints
.Append(control
);
2406 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, bottom
,
2407 CONTROL_POINT_DIAGONAL
);
2408 m_canvas
->AddShape(control
);
2409 m_controlPoints
.Append(control
);
2411 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, 0, bottom
,
2412 CONTROL_POINT_VERTICAL
);
2413 m_canvas
->AddShape(control
);
2414 m_controlPoints
.Append(control
);
2416 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, bottom
,
2417 CONTROL_POINT_DIAGONAL
);
2418 m_canvas
->AddShape(control
);
2419 m_controlPoints
.Append(control
);
2421 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, 0,
2422 CONTROL_POINT_HORIZONTAL
);
2423 m_canvas
->AddShape(control
);
2424 m_controlPoints
.Append(control
);
2428 void wxShape::MakeMandatoryControlPoints()
2430 wxNode
*node
= m_children
.GetFirst();
2433 wxShape
*child
= (wxShape
*)node
->GetData();
2434 child
->MakeMandatoryControlPoints();
2435 node
= node
->GetNext();
2439 void wxShape::ResetMandatoryControlPoints()
2441 wxNode
*node
= m_children
.GetFirst();
2444 wxShape
*child
= (wxShape
*)node
->GetData();
2445 child
->ResetMandatoryControlPoints();
2446 node
= node
->GetNext();
2450 void wxShape::ResetControlPoints()
2452 ResetMandatoryControlPoints();
2454 if (m_controlPoints
.GetCount() < 1)
2457 double maxX
, maxY
, minX
, minY
;
2459 GetBoundingBoxMax(&maxX
, &maxY
);
2460 GetBoundingBoxMin(&minX
, &minY
);
2462 double widthMin
= (double)(minX
+ CONTROL_POINT_SIZE
+ 2);
2463 double heightMin
= (double)(minY
+ CONTROL_POINT_SIZE
+ 2);
2465 // Offsets from main object
2466 double top
= (double)(- (heightMin
/ 2.0));
2467 double bottom
= (double)(heightMin
/ 2.0 + (maxY
- minY
));
2468 double left
= (double)(- (widthMin
/ 2.0));
2469 double right
= (double)(widthMin
/ 2.0 + (maxX
- minX
));
2471 wxNode
*node
= m_controlPoints
.GetFirst();
2472 wxControlPoint
*control
= (wxControlPoint
*)node
->GetData();
2473 control
->m_xoffset
= left
; control
->m_yoffset
= top
;
2475 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2476 control
->m_xoffset
= 0; control
->m_yoffset
= top
;
2478 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2479 control
->m_xoffset
= right
; control
->m_yoffset
= top
;
2481 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2482 control
->m_xoffset
= right
; control
->m_yoffset
= 0;
2484 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2485 control
->m_xoffset
= right
; control
->m_yoffset
= bottom
;
2487 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2488 control
->m_xoffset
= 0; control
->m_yoffset
= bottom
;
2490 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2491 control
->m_xoffset
= left
; control
->m_yoffset
= bottom
;
2493 node
= node
->GetNext(); control
= (wxControlPoint
*)node
->GetData();
2494 control
->m_xoffset
= left
; control
->m_yoffset
= 0;
2497 void wxShape::DeleteControlPoints(wxDC
*dc
)
2499 wxNode
*node
= m_controlPoints
.GetFirst();
2502 wxControlPoint
*control
= (wxControlPoint
*)node
->GetData();
2504 control
->GetEventHandler()->OnErase(*dc
);
2505 m_canvas
->RemoveShape(control
);
2508 node
= m_controlPoints
.GetFirst();
2510 // Children of divisions are contained objects,
2512 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2514 node
= m_children
.GetFirst();
2517 wxShape
*child
= (wxShape
*)node
->GetData();
2518 child
->DeleteControlPoints(dc
);
2519 node
= node
->GetNext();
2524 void wxShape::OnDrawControlPoints(wxDC
& dc
)
2529 dc
.SetBrush(* wxBLACK_BRUSH
);
2530 dc
.SetPen(* wxBLACK_PEN
);
2532 wxNode
*node
= m_controlPoints
.GetFirst();
2535 wxControlPoint
*control
= (wxControlPoint
*)node
->GetData();
2537 node
= node
->GetNext();
2539 // Children of divisions are contained objects,
2541 // This test bypasses the type facility for speed
2542 // (critical when drawing)
2543 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2545 node
= m_children
.GetFirst();
2548 wxShape
*child
= (wxShape
*)node
->GetData();
2549 child
->GetEventHandler()->OnDrawControlPoints(dc
);
2550 node
= node
->GetNext();
2555 void wxShape::OnEraseControlPoints(wxDC
& dc
)
2557 wxNode
*node
= m_controlPoints
.GetFirst();
2560 wxControlPoint
*control
= (wxControlPoint
*)node
->GetData();
2562 node
= node
->GetNext();
2564 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2566 node
= m_children
.GetFirst();
2569 wxShape
*child
= (wxShape
*)node
->GetData();
2570 child
->GetEventHandler()->OnEraseControlPoints(dc
);
2571 node
= node
->GetNext();
2576 void wxShape::Select(bool select
, wxDC
* dc
)
2578 m_selected
= select
;
2581 MakeControlPoints();
2582 // Children of divisions are contained objects,
2584 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2586 wxNode
*node
= m_children
.GetFirst();
2589 wxShape
*child
= (wxShape
*)node
->GetData();
2590 child
->MakeMandatoryControlPoints();
2591 node
= node
->GetNext();
2595 GetEventHandler()->OnDrawControlPoints(*dc
);
2599 DeleteControlPoints(dc
);
2600 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2602 wxNode
*node
= m_children
.GetFirst();
2605 wxShape
*child
= (wxShape
*)node
->GetData();
2606 child
->DeleteControlPoints(dc
);
2607 node
= node
->GetNext();
2613 bool wxShape::Selected() const
2618 bool wxShape::AncestorSelected() const
2620 if (m_selected
) return true;
2624 return GetParent()->AncestorSelected();
2627 int wxShape::GetNumberOfAttachments() const
2629 // Should return the MAXIMUM attachment point id here,
2630 // so higher-level functions can iterate through all attachments,
2631 // even if they're not contiguous.
2632 if (m_attachmentPoints
.GetCount() == 0)
2637 wxNode
*node
= m_attachmentPoints
.GetFirst();
2640 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
2641 if (point
->m_id
> maxN
)
2643 node
= node
->GetNext();
2649 bool wxShape::AttachmentIsValid(int attachment
) const
2651 if (m_attachmentPoints
.GetCount() == 0)
2653 return ((attachment
>= 0) && (attachment
< 4)) ;
2656 wxNode
*node
= m_attachmentPoints
.GetFirst();
2659 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
2660 if (point
->m_id
== attachment
)
2662 node
= node
->GetNext();
2667 bool wxShape::GetAttachmentPosition(int attachment
, double *x
, double *y
,
2668 int nth
, int no_arcs
, wxLineShape
*line
)
2670 if (m_attachmentMode
== ATTACHMENT_MODE_NONE
)
2672 *x
= m_xpos
; *y
= m_ypos
;
2675 else if (m_attachmentMode
== ATTACHMENT_MODE_BRANCHING
)
2677 wxRealPoint pt
, stemPt
;
2678 GetBranchingAttachmentPoint(attachment
, nth
, pt
, stemPt
);
2683 else if (m_attachmentMode
== ATTACHMENT_MODE_EDGE
)
2685 if (m_attachmentPoints
.GetCount() > 0)
2687 wxNode
*node
= m_attachmentPoints
.GetFirst();
2690 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->GetData();
2691 if (point
->m_id
== attachment
)
2693 *x
= (double)(m_xpos
+ point
->m_x
);
2694 *y
= (double)(m_ypos
+ point
->m_y
);
2697 node
= node
->GetNext();
2699 *x
= m_xpos
; *y
= m_ypos
;
2704 // Assume is rectangular
2706 GetBoundingBoxMax(&w
, &h
);
2707 double top
= (double)(m_ypos
+ h
/2.0);
2708 double bottom
= (double)(m_ypos
- h
/2.0);
2709 double left
= (double)(m_xpos
- w
/2.0);
2710 double right
= (double)(m_xpos
+ w
/2.0);
2713 /* bool isEnd = */ (line
&& line
->IsEnd(this));
2716 int physicalAttachment
= LogicalToPhysicalAttachment(attachment
);
2719 switch (physicalAttachment
)
2723 wxRealPoint pt
= CalcSimpleAttachment(wxRealPoint(left
, bottom
), wxRealPoint(right
, bottom
),
2724 nth
, no_arcs
, line
);
2726 *x
= pt
.x
; *y
= pt
.y
;
2731 wxRealPoint pt
= CalcSimpleAttachment(wxRealPoint(right
, bottom
), wxRealPoint(right
, top
),
2732 nth
, no_arcs
, line
);
2734 *x
= pt
.x
; *y
= pt
.y
;
2739 wxRealPoint pt
= CalcSimpleAttachment(wxRealPoint(left
, top
), wxRealPoint(right
, top
),
2740 nth
, no_arcs
, line
);
2742 *x
= pt
.x
; *y
= pt
.y
;
2747 wxRealPoint pt
= CalcSimpleAttachment(wxRealPoint(left
, bottom
), wxRealPoint(left
, top
),
2748 nth
, no_arcs
, line
);
2750 *x
= pt
.x
; *y
= pt
.y
;
2764 void wxShape::GetBoundingBoxMax(double *w
, double *h
)
2767 GetBoundingBoxMin(&ww
, &hh
);
2768 if (m_shadowMode
!= SHADOW_NONE
)
2770 ww
+= m_shadowOffsetX
;
2771 hh
+= m_shadowOffsetY
;
2777 // Returns true if image is a descendant of this composite
2778 bool wxShape::HasDescendant(wxShape
*image
)
2782 wxNode
*node
= m_children
.GetFirst();
2785 wxShape
*child
= (wxShape
*)node
->GetData();
2786 bool ans
= child
->HasDescendant(image
);
2789 node
= node
->GetNext();
2794 // Clears points from a list of wxRealPoints, and clears list
2795 void wxShape::ClearPointList(wxList
& list
)
2797 wxNode
* node
= list
.GetFirst();
2800 wxRealPoint
* pt
= (wxRealPoint
*) node
->GetData();
2803 node
= node
->GetNext();
2808 // Assuming the attachment lies along a vertical or horizontal line,
2809 // calculate the position on that point.
2810 wxRealPoint
wxShape::CalcSimpleAttachment(const wxRealPoint
& pt1
, const wxRealPoint
& pt2
,
2811 int nth
, int noArcs
, wxLineShape
* line
)
2813 bool isEnd
= (line
&& line
->IsEnd(this));
2815 // Are we horizontal or vertical?
2816 bool isHorizontal
= (oglRoughlyEqual(pt1
.y
, pt2
.y
) == true);
2822 wxRealPoint firstPoint
, secondPoint
;
2834 if (m_spaceAttachments
)
2836 if (line
&& (line
->GetAlignmentType(isEnd
) == LINE_ALIGNMENT_TO_NEXT_HANDLE
))
2838 // Align line according to the next handle along
2839 wxRealPoint
*point
= line
->GetNextControlPoint(this);
2840 if (point
->x
< firstPoint
.x
)
2842 else if (point
->x
> secondPoint
.x
)
2848 x
= firstPoint
.x
+ (nth
+ 1)*(secondPoint
.x
- firstPoint
.x
)/(noArcs
+ 1);
2850 else x
= (secondPoint
.x
- firstPoint
.x
)/2.0; // Midpoint
2856 wxASSERT( oglRoughlyEqual(pt1
.x
, pt2
.x
) == true );
2858 wxRealPoint firstPoint
, secondPoint
;
2870 if (m_spaceAttachments
)
2872 if (line
&& (line
->GetAlignmentType(isEnd
) == LINE_ALIGNMENT_TO_NEXT_HANDLE
))
2874 // Align line according to the next handle along
2875 wxRealPoint
*point
= line
->GetNextControlPoint(this);
2876 if (point
->y
< firstPoint
.y
)
2878 else if (point
->y
> secondPoint
.y
)
2884 y
= firstPoint
.y
+ (nth
+ 1)*(secondPoint
.y
- firstPoint
.y
)/(noArcs
+ 1);
2886 else y
= (secondPoint
.y
- firstPoint
.y
)/2.0; // Midpoint
2891 return wxRealPoint(x
, y
);
2894 // Return the zero-based position in m_lines of line.
2895 int wxShape::GetLinePosition(wxLineShape
* line
)
2897 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2898 if ((wxLineShape
*) (m_lines
.Item(i
)->GetData()) == line
)
2908 // shoulder1 ->---------<- shoulder2
2910 // <- branching attachment point N-1
2912 // This function gets information about where branching connections go.
2913 // Returns false if there are no lines at this attachment.
2914 bool wxShape::GetBranchingAttachmentInfo(int attachment
, wxRealPoint
& root
, wxRealPoint
& neck
,
2915 wxRealPoint
& shoulder1
, wxRealPoint
& shoulder2
)
2917 int physicalAttachment
= LogicalToPhysicalAttachment(attachment
);
2919 // Number of lines at this attachment.
2920 int lineCount
= GetAttachmentLineCount(attachment
);
2925 int totalBranchLength
= m_branchSpacing
* (lineCount
- 1);
2927 root
= GetBranchingAttachmentRoot(attachment
);
2929 // Assume that we have attachment points 0 to 3: top, right, bottom, left.
2930 switch (physicalAttachment
)
2935 neck
.y
= root
.y
- m_branchNeckLength
;
2937 shoulder1
.x
= root
.x
- (totalBranchLength
/2.0) ;
2938 shoulder2
.x
= root
.x
+ (totalBranchLength
/2.0) ;
2940 shoulder1
.y
= neck
.y
;
2941 shoulder2
.y
= neck
.y
;
2946 neck
.x
= root
.x
+ m_branchNeckLength
;
2949 shoulder1
.x
= neck
.x
;
2950 shoulder2
.x
= neck
.x
;
2952 shoulder1
.y
= neck
.y
- (totalBranchLength
/2.0) ;
2953 shoulder2
.y
= neck
.y
+ (totalBranchLength
/2.0) ;
2959 neck
.y
= root
.y
+ m_branchNeckLength
;
2961 shoulder1
.x
= root
.x
- (totalBranchLength
/2.0) ;
2962 shoulder2
.x
= root
.x
+ (totalBranchLength
/2.0) ;
2964 shoulder1
.y
= neck
.y
;
2965 shoulder2
.y
= neck
.y
;
2970 neck
.x
= root
.x
- m_branchNeckLength
;
2973 shoulder1
.x
= neck
.x
;
2974 shoulder2
.x
= neck
.x
;
2976 shoulder1
.y
= neck
.y
- (totalBranchLength
/2.0) ;
2977 shoulder2
.y
= neck
.y
+ (totalBranchLength
/2.0) ;
2982 wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentInfo.") );
2989 // n is the number of the adjoining line, from 0 to N-1 where N is the number of lines
2990 // at this attachment point.
2991 // Get the attachment point where the arc joins the stem, and also the point where the
2992 // the stem meets the shoulder.
2993 bool wxShape::GetBranchingAttachmentPoint(int attachment
, int n
, wxRealPoint
& pt
, wxRealPoint
& stemPt
)
2995 int physicalAttachment
= LogicalToPhysicalAttachment(attachment
);
2997 wxRealPoint root
, neck
, shoulder1
, shoulder2
;
2998 GetBranchingAttachmentInfo(attachment
, root
, neck
, shoulder1
, shoulder2
);
3000 // Assume that we have attachment points 0 to 3: top, right, bottom, left.
3001 switch (physicalAttachment
)
3005 pt
.y
= neck
.y
- m_branchStemLength
;
3006 pt
.x
= shoulder1
.x
+ n
*m_branchSpacing
;
3014 pt
.y
= neck
.y
+ m_branchStemLength
;
3015 pt
.x
= shoulder1
.x
+ n
*m_branchSpacing
;
3023 pt
.x
= neck
.x
+ m_branchStemLength
;
3024 pt
.y
= shoulder1
.y
+ n
*m_branchSpacing
;
3032 pt
.x
= neck
.x
- m_branchStemLength
;
3033 pt
.y
= shoulder1
.y
+ n
*m_branchSpacing
;
3041 wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentPoint.") );
3049 // Get the number of lines at this attachment position.
3050 int wxShape::GetAttachmentLineCount(int attachment
) const
3053 wxNode
* node
= m_lines
.GetFirst();
3056 wxLineShape
* lineShape
= (wxLineShape
*) node
->GetData();
3057 if ((lineShape
->GetFrom() == this) && (lineShape
->GetAttachmentFrom() == attachment
))
3059 else if ((lineShape
->GetTo() == this) && (lineShape
->GetAttachmentTo() == attachment
))
3062 node
= node
->GetNext();
3067 // This function gets the root point at the given attachment.
3068 wxRealPoint
wxShape::GetBranchingAttachmentRoot(int attachment
)
3070 int physicalAttachment
= LogicalToPhysicalAttachment(attachment
);
3074 double width
, height
;
3075 GetBoundingBoxMax(& width
, & height
);
3077 // Assume that we have attachment points 0 to 3: top, right, bottom, left.
3078 switch (physicalAttachment
)
3083 root
.y
= GetY() - height
/2.0;
3088 root
.x
= GetX() + width
/2.0;
3095 root
.y
= GetY() + height
/2.0;
3100 root
.x
= GetX() - width
/2.0;
3106 wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentRoot.") );
3113 // Draw or erase the branches (not the actual arcs though)
3114 void wxShape::OnDrawBranches(wxDC
& dc
, int attachment
, bool erase
)
3116 int count
= GetAttachmentLineCount(attachment
);
3120 wxRealPoint root
, neck
, shoulder1
, shoulder2
;
3121 GetBranchingAttachmentInfo(attachment
, root
, neck
, shoulder1
, shoulder2
);
3125 dc
.SetPen(*wxWHITE_PEN
);
3126 dc
.SetBrush(*wxWHITE_BRUSH
);
3130 dc
.SetPen(*wxBLACK_PEN
);
3131 dc
.SetBrush(*wxBLACK_BRUSH
);
3135 dc
.DrawLine((long) root
.x
, (long) root
.y
, (long) neck
.x
, (long) neck
.y
);
3139 // Draw shoulder-to-shoulder line
3140 dc
.DrawLine((long) shoulder1
.x
, (long) shoulder1
.y
, (long) shoulder2
.x
, (long) shoulder2
.y
);
3142 // Draw all the little branches
3144 for (i
= 0; i
< count
; i
++)
3146 wxRealPoint pt
, stemPt
;
3147 GetBranchingAttachmentPoint(attachment
, i
, pt
, stemPt
);
3148 dc
.DrawLine((long) stemPt
.x
, (long) stemPt
.y
, (long) pt
.x
, (long) pt
.y
);
3150 if ((GetBranchStyle() & BRANCHING_ATTACHMENT_BLOB
) && (count
> 1))
3153 // dc.DrawEllipse((long) (stemPt.x + 0.5 - (blobSize/2.0)), (long) (stemPt.y + 0.5 - (blobSize/2.0)), blobSize, blobSize);
3154 dc
.DrawEllipse((long) (stemPt
.x
- (blobSize
/2.0)), (long) (stemPt
.y
- (blobSize
/2.0)), blobSize
, blobSize
);
3159 // Draw or erase the branches (not the actual arcs though)
3160 void wxShape::OnDrawBranches(wxDC
& dc
, bool erase
)
3162 if (m_attachmentMode
!= ATTACHMENT_MODE_BRANCHING
)
3165 int count
= GetNumberOfAttachments();
3167 for (i
= 0; i
< count
; i
++)
3168 OnDrawBranches(dc
, i
, erase
);
3171 // Only get the attachment position at the _edge_ of the shape, ignoring
3172 // branching mode. This is used e.g. to indicate the edge of interest, not the point
3173 // on the attachment branch.
3174 bool wxShape::GetAttachmentPositionEdge(int attachment
, double *x
, double *y
,
3175 int nth
, int no_arcs
, wxLineShape
*line
)
3177 int oldMode
= m_attachmentMode
;
3179 // Calculate as if to edge, not branch
3180 if (m_attachmentMode
== ATTACHMENT_MODE_BRANCHING
)
3181 m_attachmentMode
= ATTACHMENT_MODE_EDGE
;
3182 bool success
= GetAttachmentPosition(attachment
, x
, y
, nth
, no_arcs
, line
);
3183 m_attachmentMode
= oldMode
;
3188 // Rotate the standard attachment point from physical (0 is always North)
3189 // to logical (0 -> 1 if rotated by 90 degrees)
3190 int wxShape::PhysicalToLogicalAttachment(int physicalAttachment
) const
3192 const double pi
= M_PI
;
3194 if (oglRoughlyEqual(GetRotation(), 0.0))
3196 i
= physicalAttachment
;
3198 else if (oglRoughlyEqual(GetRotation(), (pi
/2.0)))
3200 i
= physicalAttachment
- 1;
3202 else if (oglRoughlyEqual(GetRotation(), pi
))
3204 i
= physicalAttachment
- 2;
3206 else if (oglRoughlyEqual(GetRotation(), (3.0*pi
/2.0)))
3208 i
= physicalAttachment
- 3;
3211 // Can't handle -- assume the same.
3212 return physicalAttachment
;
3220 // Rotate the standard attachment point from logical
3221 // to physical (0 is always North)
3222 int wxShape::LogicalToPhysicalAttachment(int logicalAttachment
) const
3224 const double pi
= M_PI
;
3226 if (oglRoughlyEqual(GetRotation(), 0.0))
3228 i
= logicalAttachment
;
3230 else if (oglRoughlyEqual(GetRotation(), (pi
/2.0)))
3232 i
= logicalAttachment
+ 1;
3234 else if (oglRoughlyEqual(GetRotation(), pi
))
3236 i
= logicalAttachment
+ 2;
3238 else if (oglRoughlyEqual(GetRotation(), (3.0*pi
/2.0)))
3240 i
= logicalAttachment
+ 3;
3243 // Can't handle -- assume the same.
3244 return logicalAttachment
;
3252 void wxShape::Rotate(double WXUNUSED(x
), double WXUNUSED(y
), double theta
)
3254 const double pi
= M_PI
;
3256 if (m_rotation
< 0.0)
3260 else if (m_rotation
> 2*pi
)
3267 wxPen
wxShape::GetBackgroundPen()
3271 wxColour c
= GetCanvas()->GetBackgroundColour();
3272 return wxPen(c
, 1, wxSOLID
);
3274 return * g_oglWhiteBackgroundPen
;
3278 wxBrush
wxShape::GetBackgroundBrush()
3282 wxColour c
= GetCanvas()->GetBackgroundColour();
3283 return wxBrush(c
, wxSOLID
);
3285 return * g_oglWhiteBackgroundBrush
;