1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Basic OGL classes
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "basic.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include <wx/wxprec.h>
28 #include <wx/wxexpr.h>
49 // Control point types
50 // Rectangle and most other shapes
51 #define CONTROL_POINT_VERTICAL 1
52 #define CONTROL_POINT_HORIZONTAL 2
53 #define CONTROL_POINT_DIAGONAL 3
56 #define CONTROL_POINT_ENDPOINT_TO 4
57 #define CONTROL_POINT_ENDPOINT_FROM 5
58 #define CONTROL_POINT_LINE 6
60 IMPLEMENT_DYNAMIC_CLASS(wxShapeTextLine
, wxObject
)
61 IMPLEMENT_DYNAMIC_CLASS(wxAttachmentPoint
, wxObject
)
63 wxShapeTextLine::wxShapeTextLine(float the_x
, float the_y
, const wxString
& the_line
)
65 m_x
= the_x
; m_y
= the_y
; m_line
= the_line
;
68 wxShapeTextLine::~wxShapeTextLine()
72 IMPLEMENT_ABSTRACT_CLASS(wxShapeEvtHandler
, wxObject
)
74 wxShapeEvtHandler::wxShapeEvtHandler(wxShapeEvtHandler
*prev
, wxShape
*shape
)
76 m_previousHandler
= prev
;
77 m_handlerShape
= shape
;
80 wxShapeEvtHandler::~wxShapeEvtHandler()
84 // Creates a copy of this event handler.
85 wxShapeEvtHandler
* wxShapeEvtHandler::CreateNewCopy()
87 wxShapeEvtHandler
* newObject
= (wxShapeEvtHandler
*) GetClassInfo()->CreateObject();
89 wxASSERT( (newObject
!= NULL
) );
90 wxASSERT( (newObject
->IsKindOf(CLASSINFO(wxShapeEvtHandler
))) );
92 newObject
->m_previousHandler
= newObject
;
100 void wxShapeEvtHandler::OnDelete()
102 if (this != GetShape())
106 void wxShapeEvtHandler::OnDraw(wxDC
& dc
)
108 if (m_previousHandler
)
109 m_previousHandler
->OnDraw(dc
);
112 void wxShapeEvtHandler::OnMoveLinks(wxDC
& dc
)
114 if (m_previousHandler
)
115 m_previousHandler
->OnMoveLinks(dc
);
118 void wxShapeEvtHandler::OnMoveLink(wxDC
& dc
, bool moveControlPoints
)
120 if (m_previousHandler
)
121 m_previousHandler
->OnMoveLink(dc
, moveControlPoints
);
124 void wxShapeEvtHandler::OnDrawContents(wxDC
& dc
)
126 if (m_previousHandler
)
127 m_previousHandler
->OnDrawContents(dc
);
130 void wxShapeEvtHandler::OnSize(float x
, float y
)
132 if (m_previousHandler
)
133 m_previousHandler
->OnSize(x
, y
);
136 bool wxShapeEvtHandler::OnMovePre(wxDC
& dc
, float x
, float y
, float old_x
, float old_y
, bool display
)
138 if (m_previousHandler
)
139 return m_previousHandler
->OnMovePre(dc
, x
, y
, old_x
, old_y
, display
);
144 void wxShapeEvtHandler::OnMovePost(wxDC
& dc
, float x
, float y
, float old_x
, float old_y
, bool display
)
146 if (m_previousHandler
)
147 m_previousHandler
->OnMovePost(dc
, x
, y
, old_x
, old_y
, display
);
150 void wxShapeEvtHandler::OnErase(wxDC
& dc
)
152 if (m_previousHandler
)
153 m_previousHandler
->OnErase(dc
);
156 void wxShapeEvtHandler::OnEraseContents(wxDC
& dc
)
158 if (m_previousHandler
)
159 m_previousHandler
->OnEraseContents(dc
);
162 void wxShapeEvtHandler::OnHighlight(wxDC
& dc
)
164 if (m_previousHandler
)
165 m_previousHandler
->OnHighlight(dc
);
168 void wxShapeEvtHandler::OnLeftClick(float x
, float y
, int keys
, int attachment
)
170 if (m_previousHandler
)
171 m_previousHandler
->OnLeftClick(x
, y
, keys
, attachment
);
174 void wxShapeEvtHandler::OnRightClick(float x
, float y
, int keys
, int attachment
)
176 if (m_previousHandler
)
177 m_previousHandler
->OnRightClick(x
, y
, keys
, attachment
);
180 void wxShapeEvtHandler::OnDragLeft(bool draw
, float x
, float y
, int keys
, int attachment
)
182 if (m_previousHandler
)
183 m_previousHandler
->OnDragLeft(draw
, x
, y
, keys
, attachment
);
186 void wxShapeEvtHandler::OnBeginDragLeft(float x
, float y
, int keys
, int attachment
)
188 if (m_previousHandler
)
189 m_previousHandler
->OnBeginDragLeft(x
, y
, keys
, attachment
);
192 void wxShapeEvtHandler::OnEndDragLeft(float x
, float y
, int keys
, int attachment
)
194 if (m_previousHandler
)
195 m_previousHandler
->OnEndDragLeft(x
, y
, keys
, attachment
);
198 void wxShapeEvtHandler::OnDragRight(bool draw
, float x
, float y
, int keys
, int attachment
)
200 if (m_previousHandler
)
201 m_previousHandler
->OnDragRight(draw
, x
, y
, keys
, attachment
);
204 void wxShapeEvtHandler::OnBeginDragRight(float x
, float y
, int keys
, int attachment
)
206 if (m_previousHandler
)
207 m_previousHandler
->OnBeginDragRight(x
, y
, keys
, attachment
);
210 void wxShapeEvtHandler::OnEndDragRight(float x
, float 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
, float x
, float 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
, float x
, float y
, int keys
, int attachment
)
226 if (m_previousHandler
)
227 m_previousHandler
->OnSizingBeginDragLeft(pt
, x
, y
, keys
, attachment
);
230 void wxShapeEvtHandler::OnSizingEndDragLeft(wxControlPoint
* pt
, float x
, float y
, int keys
, int attachment
)
232 if (m_previousHandler
)
233 m_previousHandler
->OnSizingEndDragLeft(pt
, x
, y
, keys
, attachment
);
236 void wxShapeEvtHandler::OnDrawOutline(wxDC
& dc
, float x
, float y
, float w
, float 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 IMPLEMENT_ABSTRACT_CLASS(wxShape
, wxShapeEvtHandler
)
256 wxShape::wxShape(wxShapeCanvas
*can
)
258 m_eventHandler
= this;
263 m_xpos
= 0.0; m_ypos
= 0.0;
265 m_brush
= wxWHITE_BRUSH
;
266 m_font
= g_oglNormalFont
;
267 m_textColour
= wxBLACK
;
268 m_textColourName
= "BLACK";
272 m_attachmentMode
= FALSE
;
273 m_spaceAttachments
= TRUE
;
274 m_disableLabel
= FALSE
;
275 m_fixedWidth
= FALSE
;
276 m_fixedHeight
= FALSE
;
277 m_drawHandles
= TRUE
;
278 m_sensitivity
= OP_ALL
;
281 m_formatMode
= FORMAT_CENTRE_HORIZ
| FORMAT_CENTRE_VERT
;
282 m_shadowMode
= SHADOW_NONE
;
283 m_shadowOffsetX
= 6.0;
284 m_shadowOffsetY
= 6.0;
285 m_shadowBrush
= wxBLACK_BRUSH
;
289 m_centreResize
= TRUE
;
290 m_highlighted
= FALSE
;
293 // Set up a default region. Much of the above will be put into
294 // the region eventually (the duplication is for compatibility)
295 wxShapeRegion
*region
= new wxShapeRegion
;
296 m_regions
.Append(region
);
297 region
->SetName("0");
298 region
->SetFont(g_oglNormalFont
);
299 region
->SetFormatMode(FORMAT_CENTRE_HORIZ
| FORMAT_CENTRE_VERT
);
300 region
->SetColour("BLACK");
306 m_parent
->GetChildren().DeleteObject(this);
313 m_canvas
->RemoveShape(this);
315 GetEventHandler()->OnDelete();
318 void wxShape::SetHighlight(bool hi
, bool recurse
)
323 wxNode
*node
= m_children
.First();
326 wxShape
*child
= (wxShape
*)node
->Data();
327 child
->SetHighlight(hi
, recurse
);
333 void wxShape::SetSensitivityFilter(int sens
, bool recursive
)
335 if (sens
& OP_DRAG_LEFT
)
340 m_sensitivity
= sens
;
343 wxNode
*node
= m_children
.First();
346 wxShape
*obj
= (wxShape
*)node
->Data();
347 obj
->SetSensitivityFilter(sens
, TRUE
);
353 void wxShape::SetDraggable(bool drag
, bool recursive
)
357 m_sensitivity
|= OP_DRAG_LEFT
;
359 if (m_sensitivity
& OP_DRAG_LEFT
)
360 m_sensitivity
= m_sensitivity
- OP_DRAG_LEFT
;
364 wxNode
*node
= m_children
.First();
367 wxShape
*obj
= (wxShape
*)node
->Data();
368 obj
->SetDraggable(drag
, TRUE
);
374 void wxShape::SetDrawHandles(bool drawH
)
376 m_drawHandles
= drawH
;
377 wxNode
*node
= m_children
.First();
380 wxShape
*obj
= (wxShape
*)node
->Data();
381 obj
->SetDrawHandles(drawH
);
386 void wxShape::SetShadowMode(int mode
, bool redraw
)
388 if (redraw
&& GetCanvas())
390 wxClientDC
dc(GetCanvas());
391 GetCanvas()->PrepareDC(dc
);
404 void wxShape::SetCanvas(wxShapeCanvas
*theCanvas
)
406 m_canvas
= theCanvas
;
407 wxNode
*node
= m_children
.First();
410 wxShape
*child
= (wxShape
*)node
->Data();
411 child
->SetCanvas(theCanvas
);
416 void wxShape::AddToCanvas(wxShapeCanvas
*theCanvas
, wxShape
*addAfter
)
418 theCanvas
->AddShape(this, addAfter
);
419 wxNode
*node
= m_children
.First();
420 wxShape
*lastImage
= this;
423 wxShape
*object
= (wxShape
*)node
->Data();
424 object
->AddToCanvas(theCanvas
, lastImage
);
431 // Insert at front of canvas
432 void wxShape::InsertInCanvas(wxShapeCanvas
*theCanvas
)
434 theCanvas
->InsertShape(this);
435 wxNode
*node
= m_children
.First();
436 wxShape
*lastImage
= this;
439 wxShape
*object
= (wxShape
*)node
->Data();
440 object
->AddToCanvas(theCanvas
, lastImage
);
447 void wxShape::RemoveFromCanvas(wxShapeCanvas
*theCanvas
)
451 theCanvas
->RemoveShape(this);
452 wxNode
*node
= m_children
.First();
455 wxShape
*object
= (wxShape
*)node
->Data();
456 object
->RemoveFromCanvas(theCanvas
);
462 void wxShape::ClearAttachments()
464 wxNode
*node
= m_attachmentPoints
.First();
467 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
471 m_attachmentPoints
.Clear();
474 void wxShape::ClearText(int regionId
)
478 m_text
.DeleteContents(TRUE
);
480 m_text
.DeleteContents(FALSE
);
482 wxNode
*node
= m_regions
.Nth(regionId
);
485 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
489 void wxShape::ClearRegions()
491 wxNode
*node
= m_regions
.First();
494 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
495 wxNode
*next
= node
->Next();
502 void wxShape::AddRegion(wxShapeRegion
*region
)
504 m_regions
.Append(region
);
507 void wxShape::SetDefaultRegionSize()
509 wxNode
*node
= m_regions
.First();
511 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
513 GetBoundingBoxMin(&w
, &h
);
514 region
->SetSize(w
, h
);
517 bool wxShape::HitTest(float x
, float y
, int *attachment
, float *distance
)
522 float width
= 0.0, height
= 0.0;
523 GetBoundingBoxMin(&width
, &height
);
524 if (fabs(width
) < 4.0) width
= 4.0;
525 if (fabs(height
) < 4.0) height
= 4.0;
527 width
+= (float)4.0; height
+= (float)4.0; // Allowance for inaccurate mousing
529 float left
= (float)(m_xpos
- (width
/2.0));
530 float top
= (float)(m_ypos
- (height
/2.0));
531 float right
= (float)(m_xpos
+ (width
/2.0));
532 float bottom
= (float)(m_ypos
+ (height
/2.0));
534 int nearest_attachment
= 0;
537 // If within the bounding box, check the attachment points
538 // within the object.
540 if (x
>= left
&& x
<= right
&& y
>= top
&& y
<= bottom
)
542 int n
= GetNumberOfAttachments();
543 float nearest
= 999999.0;
545 for (int i
= 0; i
< n
; i
++)
548 if (GetAttachmentPosition(i
, &xp
, &yp
))
550 float l
= (float)sqrt(((xp
- x
) * (xp
- x
)) +
551 ((yp
- y
) * (yp
- y
)));
556 nearest_attachment
= i
;
560 *attachment
= nearest_attachment
;
567 // Format a text string according to the region size, adding
568 // strings with positions to region text list
570 static bool GraphicsInSizeToContents
= FALSE
; // Infinite recursion elimination
571 void wxShape::FormatText(wxDC
& dc
, const wxString
& s
, int i
)
576 if (m_regions
.Number() < 1)
578 wxNode
*node
= m_regions
.Nth(i
);
582 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
584 dc
.SetFont(region
->GetFont());
586 region
->GetSize(&w
, &h
);
588 wxList
*string_list
= ::FormatText(dc
, s
, (w
-5), (h
-5), region
->GetFormatMode());
589 node
= string_list
->First();
592 char *s
= (char *)node
->Data();
593 wxShapeTextLine
*line
= new wxShapeTextLine(0.0, 0.0, s
);
594 region
->GetFormattedText().Append((wxObject
*)line
);
596 node
= string_list
->First();
601 // Don't try to resize an object with more than one image (this case should be dealt
602 // with by overriden handlers)
603 if ((region
->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS
) &&
604 (region
->GetFormattedText().Number() > 0) &&
605 (m_regions
.Number() == 1) && !GraphicsInSizeToContents
)
607 GetCentredTextExtent(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, w
, h
, &actualW
, &actualH
);
608 if ((actualW
+m_textMarginX
!= w
) || (actualH
+m_textMarginY
!= h
))
610 // If we are a descendant of a composite, must make sure the composite gets
612 wxShape
*topAncestor
= GetTopAncestor();
614 if (topAncestor
!= this)
616 // Make sure we don't recurse infinitely
617 GraphicsInSizeToContents
= TRUE
;
619 wxCompositeShape
*composite
= (wxCompositeShape
*)topAncestor
;
620 composite
->Erase(dc
);
621 SetSize(actualW
+m_textMarginX
, actualH
+m_textMarginY
);
622 Move(dc
, m_xpos
, m_ypos
);
623 composite
->CalculateSize();
624 if (composite
->Selected())
626 composite
->DeleteControlPoints(& dc
);
627 composite
->MakeControlPoints();
628 composite
->MakeMandatoryControlPoints();
630 // Where infinite recursion might happen if we didn't stop it
633 GraphicsInSizeToContents
= FALSE
;
638 SetSize(actualW
+m_textMarginX
, actualH
+m_textMarginY
);
639 Move(dc
, m_xpos
, m_ypos
);
641 SetSize(actualW
+m_textMarginX
, actualH
+m_textMarginY
);
642 Move(dc
, m_xpos
, m_ypos
);
646 CentreText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, actualW
, actualH
, region
->GetFormatMode());
650 void wxShape::Recentre(wxDC
& dc
)
653 GetBoundingBoxMin(&w
, &h
);
655 int noRegions
= m_regions
.Number();
656 for (int i
= 0; i
< noRegions
; i
++)
658 wxNode
*node
= m_regions
.Nth(i
);
661 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
662 CentreText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, w
, h
, region
->GetFormatMode());
667 bool wxShape::GetPerimeterPoint(float x1
, float y1
,
669 float *x3
, float *y3
)
674 void wxShape::SetPen(wxPen
*the_pen
)
679 void wxShape::SetBrush(wxBrush
*the_brush
)
684 // Get the top-most (non-division) ancestor, or self
685 wxShape
*wxShape::GetTopAncestor()
690 if (GetParent()->IsKindOf(CLASSINFO(wxDivisionShape
)))
692 else return GetParent()->GetTopAncestor();
699 void wxShape::SetFont(wxFont
*the_font
, int regionId
)
702 wxNode
*node
= m_regions
.Nth(regionId
);
705 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
706 region
->SetFont(the_font
);
709 wxFont
*wxShape::GetFont(int n
) const
711 wxNode
*node
= m_regions
.Nth(n
);
714 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
715 return region
->GetFont();
718 void wxShape::SetFormatMode(int mode
, int regionId
)
720 wxNode
*node
= m_regions
.Nth(regionId
);
723 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
724 region
->SetFormatMode(mode
);
727 int wxShape::GetFormatMode(int regionId
) const
729 wxNode
*node
= m_regions
.Nth(regionId
);
732 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
733 return region
->GetFormatMode();
736 void wxShape::SetTextColour(const wxString
& the_colour
, int regionId
)
738 wxColour
*wxcolour
= wxTheColourDatabase
->FindColour(the_colour
);
739 m_textColour
= wxcolour
;
740 m_textColourName
= the_colour
;
742 wxNode
*node
= m_regions
.Nth(regionId
);
745 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
746 region
->SetColour(the_colour
);
749 wxString
wxShape::GetTextColour(int regionId
) const
751 wxNode
*node
= m_regions
.Nth(regionId
);
754 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
755 return region
->GetColour();
758 void wxShape::SetRegionName(const wxString
& name
, int regionId
)
760 wxNode
*node
= m_regions
.Nth(regionId
);
763 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
764 region
->SetName(name
);
767 wxString
wxShape::GetRegionName(int regionId
)
769 wxNode
*node
= m_regions
.Nth(regionId
);
772 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
773 return region
->GetName();
776 int wxShape::GetRegionId(const wxString
& name
)
778 wxNode
*node
= m_regions
.First();
782 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
783 if (region
->GetName() == name
)
791 // Name all m_regions in all subimages recursively.
792 void wxShape::NameRegions(const wxString
& parentName
)
794 int n
= GetNumberOfTextRegions();
796 for (int i
= 0; i
< n
; i
++)
798 if (parentName
.Length() > 0)
799 sprintf(buf
, "%s.%d", (const char*) parentName
, i
);
801 sprintf(buf
, "%d", i
);
802 SetRegionName(buf
, i
);
804 wxNode
*node
= m_children
.First();
808 wxShape
*child
= (wxShape
*)node
->Data();
809 if (parentName
.Length() > 0)
810 sprintf(buf
, "%s.%d", (const char*) parentName
, j
);
812 sprintf(buf
, "%d", j
);
813 child
->NameRegions(buf
);
819 // Get a region by name, possibly looking recursively into composites.
820 wxShape
*wxShape::FindRegion(const wxString
& name
, int *regionId
)
822 int id
= GetRegionId(name
);
829 wxNode
*node
= m_children
.First();
832 wxShape
*child
= (wxShape
*)node
->Data();
833 wxShape
*actualImage
= child
->FindRegion(name
, regionId
);
841 // Finds all region names for this image (composite or simple).
842 // Supply empty string list.
843 void wxShape::FindRegionNames(wxStringList
& list
)
845 int n
= GetNumberOfTextRegions();
846 for (int i
= 0; i
< n
; i
++)
848 wxString
name(GetRegionName(i
));
849 list
.Add((const char*) name
);
852 wxNode
*node
= m_children
.First();
855 wxShape
*child
= (wxShape
*)node
->Data();
856 child
->FindRegionNames(list
);
861 void wxShape::AssignNewIds()
865 wxNode
*node
= m_children
.First();
868 wxShape
*child
= (wxShape
*)node
->Data();
869 child
->AssignNewIds();
874 void wxShape::OnDraw(wxDC
& dc
)
878 void wxShape::OnMoveLinks(wxDC
& dc
)
880 // Want to set the ends of all attached links
881 // to point to/from this object
883 wxNode
*current
= m_lines
.First();
886 wxLineShape
*line
= (wxLineShape
*)current
->Data();
887 line
->GetEventHandler()->OnMoveLink(dc
);
888 current
= current
->Next();
893 void wxShape::OnDrawContents(wxDC
& dc
)
895 float bound_x
, bound_y
;
896 GetBoundingBoxMin(&bound_x
, &bound_y
);
897 if (m_regions
.Number() < 1) return;
899 if (m_pen
) dc
.SetPen(m_pen
);
901 wxShapeRegion
*region
= (wxShapeRegion
*)m_regions
.First()->Data();
902 if (region
->GetFont()) dc
.SetFont(region
->GetFont());
904 dc
.SetTextForeground(* (region
->GetActualColourObject()));
905 dc
.SetBackgroundMode(wxTRANSPARENT
);
908 CentreText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, bound_x
, bound_y
, region
->GetFormatMode());
911 if (!GetDisableLabel())
913 DrawFormattedText(dc
, &(region
->GetFormattedText()), m_xpos
, m_ypos
, bound_x
, bound_y
, region
->GetFormatMode());
917 void wxShape::DrawContents(wxDC
& dc
)
919 GetEventHandler()->OnDrawContents(dc
);
922 void wxShape::OnSize(float x
, float y
)
926 bool wxShape::OnMovePre(wxDC
& dc
, float x
, float y
, float old_x
, float old_y
, bool display
)
931 void wxShape::OnMovePost(wxDC
& dc
, float x
, float y
, float old_x
, float old_y
, bool display
)
935 void wxShape::OnErase(wxDC
& dc
)
941 wxNode
*current
= m_lines
.First();
944 wxLineShape
*line
= (wxLineShape
*)current
->Data();
945 line
->GetEventHandler()->OnErase(dc
);
946 current
= current
->Next();
948 GetEventHandler()->OnEraseContents(dc
);
951 void wxShape::OnEraseContents(wxDC
& dc
)
956 float maxX
, maxY
, minX
, minY
;
959 GetBoundingBoxMin(&minX
, &minY
);
960 GetBoundingBoxMax(&maxX
, &maxY
);
961 float topLeftX
= (float)(xp
- (maxX
/ 2.0) - 2.0);
962 float topLeftY
= (float)(yp
- (maxY
/ 2.0) - 2.0);
966 penWidth
= m_pen
->GetWidth();
968 dc
.SetPen(white_background_pen
);
969 dc
.SetBrush(white_background_brush
);
970 dc
.DrawRectangle((float)(topLeftX
- penWidth
), (float)(topLeftY
- penWidth
),
971 (float)(maxX
+ penWidth
*2.0 + 4.0), (float)(maxY
+ penWidth
*2.0 + 4.0));
974 void wxShape::EraseLinks(wxDC
& dc
, int attachment
, bool recurse
)
979 wxNode
*current
= m_lines
.First();
982 wxLineShape
*line
= (wxLineShape
*)current
->Data();
983 if (attachment
== -1 || ((line
->GetTo() == this && line
->GetAttachmentTo() == attachment
) ||
984 (line
->GetFrom() == this && line
->GetAttachmentFrom() == attachment
)))
985 line
->GetEventHandler()->OnErase(dc
);
986 current
= current
->Next();
990 wxNode
*node
= m_children
.First();
993 wxShape
*child
= (wxShape
*)node
->Data();
994 child
->EraseLinks(dc
, attachment
, recurse
);
1000 void wxShape::DrawLinks(wxDC
& dc
, int attachment
, bool recurse
)
1005 wxNode
*current
= m_lines
.First();
1008 wxLineShape
*line
= (wxLineShape
*)current
->Data();
1009 if (attachment
== -1 ||
1010 (line
->GetTo() == this && line
->GetAttachmentTo() == attachment
) ||
1011 (line
->GetFrom() == this && line
->GetAttachmentFrom() == attachment
))
1013 current
= current
->Next();
1017 wxNode
*node
= m_children
.First();
1020 wxShape
*child
= (wxShape
*)node
->Data();
1021 child
->DrawLinks(dc
, attachment
, recurse
);
1022 node
= node
->Next();
1027 void wxShape::MoveLineToNewAttachment(wxDC
& dc
, wxLineShape
*to_move
,
1033 // Is (x, y) on this object? If so, find the new attachment point
1034 // the user has moved the point to
1035 bool hit
= HitTest(x
, y
, &new_point
, &distance
);
1042 if (to_move
->GetTo() == this)
1043 old_attachment
= to_move
->GetAttachmentTo();
1045 old_attachment
= to_move
->GetAttachmentFrom();
1047 // Delete the line object from the list of links; we're going to move
1048 // it to another position in the list
1049 m_lines
.DeleteObject(to_move
);
1051 float old_x
= (float) -9999.9;
1052 float old_y
= (float) -9999.9;
1054 wxNode
*node
= m_lines
.First();
1057 while (node
&& !found
)
1059 wxLineShape
*line
= (wxLineShape
*)node
->Data();
1060 if ((line
->GetTo() == this && old_attachment
== line
->GetAttachmentTo()) ||
1061 (line
->GetFrom() == this && old_attachment
== line
->GetAttachmentFrom()))
1063 float startX
, startY
, endX
, endY
;
1065 line
->GetEnds(&startX
, &startY
, &endX
, &endY
);
1066 if (line
->GetTo() == this)
1068 // xp = line->m_xpos2 + line->m_xpos;
1069 // yp = line->m_ypos2 + line->m_ypos;
1074 // xp = line->m_xpos1 + line->m_xpos;
1075 // yp = line->m_ypos1 + line->m_ypos;
1080 switch (old_attachment
)
1085 if (x
> old_x
&& x
<= xp
)
1088 m_lines
.Insert(node
, to_move
);
1095 if (y
> old_y
&& y
<= yp
)
1098 m_lines
.Insert(node
, to_move
);
1106 node
= node
->Next();
1109 m_lines
.Append(to_move
);
1112 // Reorders the lines coming into the node image at this attachment
1113 // position, in the order in which they appear in linesToSort.
1114 // Any remaining lines not in the list will be added to the end.
1115 void wxShape::SortLines(int attachment
, wxList
& linesToSort
)
1117 // This is a temporary store of all the lines at this attachment
1118 // point. We'll tick them off as we've processed them.
1119 wxList linesAtThisAttachment
;
1121 wxNode
*node
= m_lines
.First();
1124 wxLineShape
*line
= (wxLineShape
*)node
->Data();
1125 wxNode
*next
= node
->Next();
1126 if ((line
->GetTo() == this && line
->GetAttachmentTo() == attachment
) ||
1127 (line
->GetFrom() == this && line
->GetAttachmentFrom() == attachment
))
1129 linesAtThisAttachment
.Append(line
);
1133 else node
= node
->Next();
1136 node
= linesToSort
.First();
1139 wxLineShape
*line
= (wxLineShape
*)node
->Data();
1140 if (linesAtThisAttachment
.Member(line
))
1143 linesAtThisAttachment
.DeleteObject(line
);
1144 m_lines
.Append(line
);
1146 node
= node
->Next();
1149 // Now add any lines that haven't been listed in linesToSort.
1150 node
= linesAtThisAttachment
.First();
1153 wxLineShape
*line
= (wxLineShape
*)node
->Data();
1154 m_lines
.Append(line
);
1155 node
= node
->Next();
1159 void wxShape::OnHighlight(wxDC
& dc
)
1163 void wxShape::OnLeftClick(float x
, float y
, int keys
, int attachment
)
1165 if ((m_sensitivity
& OP_CLICK_LEFT
) != OP_CLICK_LEFT
)
1171 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1172 m_parent
->GetEventHandler()->OnLeftClick(x
, y
, keys
, attachment
);
1178 void wxShape::OnRightClick(float x
, float y
, int keys
, int attachment
)
1180 if ((m_sensitivity
& OP_CLICK_RIGHT
) != OP_CLICK_RIGHT
)
1186 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1187 m_parent
->GetEventHandler()->OnRightClick(x
, y
, keys
, attachment
);
1193 float DragOffsetX
= 0.0;
1194 float DragOffsetY
= 0.0;
1196 void wxShape::OnDragLeft(bool draw
, float x
, float y
, int keys
, int attachment
)
1198 if ((m_sensitivity
& OP_DRAG_LEFT
) != OP_DRAG_LEFT
)
1204 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1205 m_parent
->GetEventHandler()->OnDragLeft(draw
, x
, y
, keys
, attachment
);
1210 wxClientDC
dc(GetCanvas());
1211 GetCanvas()->PrepareDC(dc
);
1213 dc
.SetLogicalFunction(wxXOR
);
1215 wxPen
dottedPen(wxColour(0, 0, 0), 1, wxDOT
);
1216 dc
.SetPen(dottedPen
);
1217 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1220 xx
= x
+ DragOffsetX
;
1221 yy
= y
+ DragOffsetY
;
1223 m_canvas
->Snap(&xx
, &yy
);
1224 // m_xpos = xx; m_ypos = yy;
1226 GetBoundingBoxMax(&w
, &h
);
1227 GetEventHandler()->OnDrawOutline(dc
, xx
, yy
, w
, h
);
1230 void wxShape::OnBeginDragLeft(float x
, float y
, int keys
, int attachment
)
1232 if ((m_sensitivity
& OP_DRAG_LEFT
) != OP_DRAG_LEFT
)
1238 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1239 m_parent
->GetEventHandler()->OnBeginDragLeft(x
, y
, keys
, attachment
);
1244 DragOffsetX
= m_xpos
- x
;
1245 DragOffsetY
= m_ypos
- y
;
1247 wxClientDC
dc(GetCanvas());
1248 GetCanvas()->PrepareDC(dc
);
1252 xx
= x
+ DragOffsetX
;
1253 yy
= y
+ DragOffsetY
;
1254 m_canvas
->Snap(&xx
, &yy
);
1255 // m_xpos = xx; m_ypos = yy;
1256 dc
.SetLogicalFunction(wxXOR
);
1258 wxPen
dottedPen(wxColour(0, 0, 0), 1, wxDOT
);
1259 dc
.SetPen(dottedPen
);
1260 dc
.SetBrush((* wxTRANSPARENT_BRUSH
));
1263 GetBoundingBoxMax(&w
, &h
);
1264 GetEventHandler()->OnDrawOutline(dc
, xx
, yy
, w
, h
);
1265 m_canvas
->CaptureMouse();
1268 void wxShape::OnEndDragLeft(float x
, float y
, int keys
, int attachment
)
1270 m_canvas
->ReleaseMouse();
1271 if ((m_sensitivity
& OP_DRAG_LEFT
) != OP_DRAG_LEFT
)
1277 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1278 m_parent
->GetEventHandler()->OnEndDragLeft(x
, y
, keys
, attachment
);
1283 wxClientDC
dc(GetCanvas());
1284 GetCanvas()->PrepareDC(dc
);
1286 dc
.SetLogicalFunction(wxCOPY
);
1288 float xx
= x
+ DragOffsetX
;
1289 float yy
= y
+ DragOffsetY
;
1290 m_canvas
->Snap(&xx
, &yy
);
1291 // canvas->Snap(&m_xpos, &m_ypos);
1293 if (m_canvas
&& !m_canvas
->GetQuickEditMode()) m_canvas
->Redraw(dc
);
1296 void wxShape::OnDragRight(bool draw
, float x
, float y
, int keys
, int attachment
)
1298 if ((m_sensitivity
& OP_DRAG_RIGHT
) != OP_DRAG_RIGHT
)
1304 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1305 m_parent
->GetEventHandler()->OnDragRight(draw
, x
, y
, keys
, attachment
);
1311 void wxShape::OnBeginDragRight(float x
, float y
, int keys
, int attachment
)
1313 if ((m_sensitivity
& OP_DRAG_RIGHT
) != OP_DRAG_RIGHT
)
1319 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1320 m_parent
->GetEventHandler()->OnBeginDragRight(x
, y
, keys
, attachment
);
1326 void wxShape::OnEndDragRight(float x
, float y
, int keys
, int attachment
)
1328 if ((m_sensitivity
& OP_DRAG_RIGHT
) != OP_DRAG_RIGHT
)
1334 m_parent
->HitTest(x
, y
, &attachment
, &dist
);
1335 m_parent
->GetEventHandler()->OnEndDragRight(x
, y
, keys
, attachment
);
1341 void wxShape::OnDrawOutline(wxDC
& dc
, float x
, float y
, float w
, float h
)
1343 float top_left_x
= (float)(x
- w
/2.0);
1344 float top_left_y
= (float)(y
- h
/2.0);
1345 float top_right_x
= (float)(top_left_x
+ w
);
1346 float top_right_y
= (float)top_left_y
;
1347 float bottom_left_x
= (float)top_left_x
;
1348 float bottom_left_y
= (float)(top_left_y
+ h
);
1349 float bottom_right_x
= (float)top_right_x
;
1350 float bottom_right_y
= (float)bottom_left_y
;
1353 points
[0].x
= top_left_x
; points
[0].y
= top_left_y
;
1354 points
[1].x
= top_right_x
; points
[1].y
= top_right_y
;
1355 points
[2].x
= bottom_right_x
; points
[2].y
= bottom_right_y
;
1356 points
[3].x
= bottom_left_x
; points
[3].y
= bottom_left_y
;
1357 points
[4].x
= top_left_x
; points
[4].y
= top_left_y
;
1359 dc
.DrawLines(5, points
);
1362 void wxShape::Attach(wxShapeCanvas
*can
)
1367 void wxShape::Detach()
1372 void wxShape::Move(wxDC
& dc
, float x
, float y
, bool display
)
1374 float old_x
= m_xpos
;
1375 float old_y
= m_ypos
;
1377 m_xpos
= x
; m_ypos
= y
;
1379 if (!GetEventHandler()->OnMovePre(dc
, x
, y
, old_x
, old_y
, display
))
1386 ResetControlPoints();
1393 GetEventHandler()->OnMovePost(dc
, x
, y
, old_x
, old_y
, display
);
1396 void wxShape::MoveLinks(wxDC
& dc
)
1398 GetEventHandler()->OnMoveLinks(dc
);
1402 void wxShape::Draw(wxDC
& dc
)
1406 GetEventHandler()->OnDraw(dc
);
1407 GetEventHandler()->OnDrawContents(dc
);
1408 GetEventHandler()->OnDrawControlPoints(dc
);
1412 void wxShape::Flash()
1416 wxClientDC
dc(GetCanvas());
1417 GetCanvas()->PrepareDC(dc
);
1419 dc
.SetLogicalFunction(wxXOR
);
1421 dc
.SetLogicalFunction(wxCOPY
);
1426 void wxShape::Show(bool show
)
1429 wxNode
*node
= m_children
.First();
1432 wxShape
*image
= (wxShape
*)node
->Data();
1434 node
= node
->Next();
1438 void wxShape::Erase(wxDC
& dc
)
1440 GetEventHandler()->OnErase(dc
);
1441 GetEventHandler()->OnEraseControlPoints(dc
);
1444 void wxShape::EraseContents(wxDC
& dc
)
1446 GetEventHandler()->OnEraseContents(dc
);
1449 void wxShape::AddText(const wxString
& string
)
1451 wxNode
*node
= m_regions
.First();
1454 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
1455 region
->ClearText();
1456 wxShapeTextLine
*new_line
=
1457 new wxShapeTextLine(0.0, 0.0, string
);
1458 region
->GetFormattedText().Append(new_line
);
1460 m_formatted
= FALSE
;
1463 void wxShape::SetSize(float x
, float y
, bool recursive
)
1465 SetAttachmentSize(x
, y
);
1466 SetDefaultRegionSize();
1469 void wxShape::SetAttachmentSize(float w
, float h
)
1473 float width
, height
;
1474 GetBoundingBoxMin(&width
, &height
);
1477 else scaleX
= w
/width
;
1480 else scaleY
= h
/height
;
1482 wxNode
*node
= m_attachmentPoints
.First();
1485 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
1486 point
->m_x
= (float)(point
->m_x
* scaleX
);
1487 point
->m_y
= (float)(point
->m_y
* scaleY
);
1488 node
= node
->Next();
1492 // Add line FROM this object
1493 void wxShape::AddLine(wxLineShape
*line
, wxShape
*other
,
1494 int attachFrom
, int attachTo
)
1496 if (!m_lines
.Member(line
))
1497 m_lines
.Append(line
);
1499 if (!other
->m_lines
.Member(line
))
1500 other
->m_lines
.Append(line
);
1502 line
->SetFrom(this);
1504 line
->SetAttachments(attachFrom
, attachTo
);
1507 void wxShape::RemoveLine(wxLineShape
*line
)
1509 if (line
->GetFrom() == this)
1510 line
->GetTo()->m_lines
.DeleteObject(line
);
1512 line
->GetFrom()->m_lines
.DeleteObject(line
);
1514 m_lines
.DeleteObject(line
);
1518 char *wxShape::GetFunctor()
1520 return "node_image";
1523 void wxShape::WritePrologAttributes(wxExpr
*clause
)
1525 clause
->AddAttributeValueString("type", GetClassInfo()->GetClassName());
1526 clause
->AddAttributeValue("id", m_id
);
1530 int penWidth
= m_pen
->GetWidth();
1531 int penStyle
= m_pen
->GetStyle();
1533 clause
->AddAttributeValue("pen_width", (long)penWidth
);
1534 if (penStyle
!= wxSOLID
)
1535 clause
->AddAttributeValue("pen_style", (long)penStyle
);
1537 wxString penColour
= wxTheColourDatabase
->FindName(m_pen
->GetColour());
1538 if (penColour
== "")
1540 wxString
hex(oglColourToHex(m_pen
->GetColour()));
1541 hex
= wxString("#") + hex
;
1542 clause
->AddAttributeValueString("pen_colour", hex
);
1544 else if (penColour
!= "BLACK")
1545 clause
->AddAttributeValueString("pen_colour", penColour
);
1550 wxString brushColour
= wxTheColourDatabase
->FindName(m_brush
->GetColour());
1552 if (brushColour
== "")
1554 wxString
hex(oglColourToHex(m_brush
->GetColour()));
1555 hex
= wxString("#") + hex
;
1556 clause
->AddAttributeValueString("brush_colour", hex
);
1558 else if (brushColour
!= "WHITE")
1559 clause
->AddAttributeValueString("brush_colour", brushColour
);
1561 if (m_brush
->GetStyle() != wxSOLID
)
1562 clause
->AddAttributeValue("brush_style", (long)m_brush
->GetStyle());
1567 int n_lines
= m_lines
.Number();
1570 wxExpr
*list
= new wxExpr(PrologList
);
1571 wxNode
*node
= m_lines
.First();
1574 wxShape
*line
= (wxShape
*)node
->Data();
1575 wxExpr
*id_expr
= new wxExpr(line
->GetId());
1576 list
->Append(id_expr
);
1577 node
= node
->Next();
1579 clause
->AddAttributeValue("arcs", list
);
1582 // Miscellaneous members
1583 if (m_attachmentMode
!= 0)
1584 clause
->AddAttributeValue("use_attachments", (long)m_attachmentMode
);
1585 if (m_sensitivity
!= OP_ALL
)
1586 clause
->AddAttributeValue("sensitivity", (long)m_sensitivity
);
1587 if (!m_spaceAttachments
)
1588 clause
->AddAttributeValue("space_attachments", (long)m_spaceAttachments
);
1590 clause
->AddAttributeValue("fixed_width", (long)m_fixedWidth
);
1592 clause
->AddAttributeValue("fixed_height", (long)m_fixedHeight
);
1593 if (m_shadowMode
!= SHADOW_NONE
)
1594 clause
->AddAttributeValue("shadow_mode", (long)m_shadowMode
);
1595 if (m_centreResize
!= TRUE
)
1596 clause
->AddAttributeValue("centre_resize", (long)0);
1597 if (m_highlighted
!= FALSE
)
1598 clause
->AddAttributeValue("hilite", (long)m_highlighted
);
1600 if (m_parent
) // For composite objects
1601 clause
->AddAttributeValue("parent", (long)m_parent
->GetId());
1603 if (m_rotation
!= 0.0)
1604 clause
->AddAttributeValue("rotation", m_rotation
);
1606 // Write user-defined attachment points, if any
1607 if (m_attachmentPoints
.Number() > 0)
1609 wxExpr
*attachmentList
= new wxExpr(PrologList
);
1610 wxNode
*node
= m_attachmentPoints
.First();
1613 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
1614 wxExpr
*pointExpr
= new wxExpr(PrologList
);
1615 pointExpr
->Append(new wxExpr((long)point
->m_id
));
1616 pointExpr
->Append(new wxExpr(point
->m_x
));
1617 pointExpr
->Append(new wxExpr(point
->m_y
));
1618 attachmentList
->Append(pointExpr
);
1619 node
= node
->Next();
1621 clause
->AddAttributeValue("user_attachments", attachmentList
);
1624 // Write text regions
1625 WriteRegions(clause
);
1628 void wxShape::WriteRegions(wxExpr
*clause
)
1630 // Output regions as region1 = (...), region2 = (...), etc
1631 // and formatted text as text1 = (...), text2 = (...) etc.
1633 char regionNameBuf
[20];
1634 char textNameBuf
[20];
1635 wxNode
*node
= m_regions
.First();
1638 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
1639 sprintf(regionNameBuf
, "region%d", regionNo
);
1640 sprintf(textNameBuf
, "text%d", regionNo
);
1642 // Original text and region attributes:
1643 // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
1644 // formatMode fontSize fontFamily fontStyle fontWeight textColour)
1645 wxExpr
*regionExpr
= new wxExpr(PrologList
);
1646 regionExpr
->Append(new wxExpr(PrologString
, (region
->m_regionName
? region
->m_regionName
: "")));
1647 regionExpr
->Append(new wxExpr(PrologString
, (region
->m_regionText
? region
->m_regionText
: "")));
1649 regionExpr
->Append(new wxExpr(region
->m_x
));
1650 regionExpr
->Append(new wxExpr(region
->m_y
));
1651 regionExpr
->Append(new wxExpr(region
->GetWidth()));
1652 regionExpr
->Append(new wxExpr(region
->GetHeight()));
1654 regionExpr
->Append(new wxExpr(region
->m_minWidth
));
1655 regionExpr
->Append(new wxExpr(region
->m_minHeight
));
1656 regionExpr
->Append(new wxExpr(region
->m_regionProportionX
));
1657 regionExpr
->Append(new wxExpr(region
->m_regionProportionY
));
1659 regionExpr
->Append(new wxExpr((long)region
->m_formatMode
));
1661 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetPointSize() : 10)));
1662 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetFamily() : wxDEFAULT
)));
1663 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetStyle() : wxDEFAULT
)));
1664 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetWeight() : wxNORMAL
)));
1665 regionExpr
->Append(new wxExpr(PrologString
, region
->m_textColour
? region
->m_textColour
: "BLACK"));
1667 // New members for pen colour/style
1668 regionExpr
->Append(new wxExpr(PrologString
, region
->m_penColour
? region
->m_penColour
: "BLACK"));
1669 regionExpr
->Append(new wxExpr((long)region
->m_penStyle
));
1672 // text1 = ((x y string) (x y string) ...)
1673 wxExpr
*textExpr
= new wxExpr(PrologList
);
1675 wxNode
*textNode
= region
->m_formattedText
.First();
1678 wxShapeTextLine
*line
= (wxShapeTextLine
*)textNode
->Data();
1679 wxExpr
*list2
= new wxExpr(PrologList
);
1680 list2
->Append(new wxExpr(line
->GetX()));
1681 list2
->Append(new wxExpr(line
->GetY()));
1682 list2
->Append(new wxExpr(PrologString
, line
->GetText()));
1683 textExpr
->Append(list2
);
1684 textNode
= textNode
->Next();
1687 // Now add both attributes to the clause
1688 clause
->AddAttributeValue(regionNameBuf
, regionExpr
);
1689 clause
->AddAttributeValue(textNameBuf
, textExpr
);
1691 node
= node
->Next();
1696 void wxShape::ReadPrologAttributes(wxExpr
*clause
)
1698 clause
->GetAttributeValue("id", m_id
);
1701 clause
->GetAttributeValue("x", m_xpos
);
1702 clause
->GetAttributeValue("y", m_ypos
);
1704 // Input text strings (FOR COMPATIBILITY WITH OLD FILES ONLY. SEE REGION CODE BELOW.)
1706 wxExpr
*strings
= clause
->AttributeValue("text");
1707 if (strings
&& strings
->Type() == PrologList
)
1709 m_formatted
= TRUE
; // Assume text is formatted unless we prove otherwise
1710 wxExpr
*node
= strings
->value
.first
;
1713 wxExpr
*string_expr
= node
;
1716 wxString
the_string("");
1718 // string_expr can either be a string, or a list of
1719 // 3 elements: x, y, and string.
1720 if (string_expr
->Type() == PrologString
)
1722 the_string
= string_expr
->StringValue();
1723 m_formatted
= FALSE
;
1725 else if (string_expr
->Type() == PrologList
)
1727 wxExpr
*first
= string_expr
->value
.first
;
1728 wxExpr
*second
= first
? first
->next
: NULL
;
1729 wxExpr
*third
= second
? second
->next
: NULL
;
1731 if (first
&& second
&& third
&&
1732 (first
->Type() == PrologReal
|| first
->Type() == PrologInteger
) &&
1733 (second
->Type() == PrologReal
|| second
->Type() == PrologInteger
) &&
1734 third
->Type() == PrologString
)
1736 if (first
->Type() == PrologReal
)
1737 the_x
= first
->RealValue();
1738 else the_x
= (float)first
->IntegerValue();
1740 if (second
->Type() == PrologReal
)
1741 the_y
= second
->RealValue();
1742 else the_y
= (float)second
->IntegerValue();
1744 the_string
= third
->StringValue();
1747 wxShapeTextLine
*line
=
1748 new wxShapeTextLine(the_x
, the_y
, (char*) (const char*) the_string
);
1749 m_text
.Append(line
);
1755 wxString pen_string
= "";
1756 wxString brush_string
= "";
1758 int pen_style
= wxSOLID
;
1759 int brush_style
= wxSOLID
;
1760 m_attachmentMode
= FALSE
;
1762 clause
->GetAttributeValue("pen_colour", pen_string
);
1763 clause
->GetAttributeValue("text_colour", m_textColourName
);
1765 SetTextColour(m_textColourName
);
1767 clause
->GetAttributeValue("region_name", m_regionName
);
1769 clause
->GetAttributeValue("brush_colour", brush_string
);
1770 clause
->GetAttributeValue("pen_width", pen_width
);
1771 clause
->GetAttributeValue("pen_style", pen_style
);
1772 clause
->GetAttributeValue("brush_style", brush_style
);
1774 int iVal
= (int) m_attachmentMode
;
1775 clause
->GetAttributeValue("use_attachments", iVal
);
1776 m_attachmentMode
= (iVal
!= 0);
1778 clause
->GetAttributeValue("sensitivity", m_sensitivity
);
1780 iVal
= (int) m_spaceAttachments
;
1781 clause
->GetAttributeValue("space_attachments", iVal
);
1782 m_spaceAttachments
= (iVal
!= 0);
1784 iVal
= (int) m_fixedWidth
;
1785 clause
->GetAttributeValue("fixed_width", iVal
);
1786 m_fixedWidth
= (iVal
!= 0);
1788 iVal
= (int) m_fixedHeight
;
1789 clause
->GetAttributeValue("fixed_height", iVal
);
1790 m_fixedHeight
= (iVal
!= 0);
1792 clause
->GetAttributeValue("format_mode", m_formatMode
);
1793 clause
->GetAttributeValue("shadow_mode", m_shadowMode
);
1795 iVal
= (int) m_centreResize
;
1796 clause
->GetAttributeValue("centre_resize", iVal
);
1797 m_centreResize
= (iVal
!= 0);
1799 iVal
= (int) m_highlighted
;
1800 clause
->GetAttributeValue("hilite", iVal
);
1801 m_highlighted
= (iVal
!= 0);
1803 clause
->GetAttributeValue("rotation", m_rotation
);
1805 if (pen_string
== "")
1806 pen_string
= "BLACK";
1807 if (brush_string
== "")
1808 brush_string
= "WHITE";
1810 if (pen_string
[0] == '#')
1812 wxColour
col(oglHexToColour(pen_string
.After('#')));
1813 m_pen
= wxThePenList
->FindOrCreatePen(col
, pen_width
, pen_style
);
1816 m_pen
= wxThePenList
->FindOrCreatePen(pen_string
, pen_width
, pen_style
);
1819 m_pen
= wxBLACK_PEN
;
1821 if (brush_string
[0] == '#')
1823 wxColour
col(oglHexToColour(brush_string
.After('#')));
1824 m_brush
= wxTheBrushList
->FindOrCreateBrush(col
, brush_style
);
1827 m_brush
= wxTheBrushList
->FindOrCreateBrush(brush_string
, brush_style
);
1830 m_brush
= wxWHITE_BRUSH
;
1832 int point_size
= 10;
1833 clause
->GetAttributeValue("point_size", point_size
);
1834 SetFont(MatchFont(point_size
));
1836 // Read user-defined attachment points, if any
1837 wxExpr
*attachmentList
= clause
->AttributeValue("user_attachments");
1840 wxExpr
*pointExpr
= attachmentList
->GetFirst();
1843 wxExpr
*idExpr
= pointExpr
->Nth(0);
1844 wxExpr
*xExpr
= pointExpr
->Nth(1);
1845 wxExpr
*yExpr
= pointExpr
->Nth(2);
1846 if (idExpr
&& xExpr
&& yExpr
)
1848 wxAttachmentPoint
*point
= new wxAttachmentPoint
;
1849 point
->m_id
= (int)idExpr
->IntegerValue();
1850 point
->m_x
= xExpr
->RealValue();
1851 point
->m_y
= yExpr
->RealValue();
1852 m_attachmentPoints
.Append((wxObject
*)point
);
1854 pointExpr
= pointExpr
->GetNext();
1858 // Read text regions
1859 ReadRegions(clause
);
1862 void wxShape::ReadRegions(wxExpr
*clause
)
1866 // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
1867 // formatMode fontSize fontFamily fontStyle fontWeight textColour)
1869 char regionNameBuf
[20];
1870 char textNameBuf
[20];
1872 wxExpr
*regionExpr
= NULL
;
1873 wxExpr
*textExpr
= NULL
;
1874 sprintf(regionNameBuf
, "region%d", regionNo
);
1875 sprintf(textNameBuf
, "text%d", regionNo
);
1877 m_formatted
= TRUE
; // Assume text is formatted unless we prove otherwise
1879 while (regionExpr
= clause
->AttributeValue(regionNameBuf
))
1882 * Get the region information
1886 wxString
regionName("");
1887 wxString
regionText("");
1892 float minWidth
= 5.0;
1893 float minHeight
= 5.0;
1894 float m_regionProportionX
= -1.0;
1895 float m_regionProportionY
= -1.0;
1896 int formatMode
= FORMAT_NONE
;
1898 int fontFamily
= wxSWISS
;
1899 int fontStyle
= wxNORMAL
;
1900 int fontWeight
= wxNORMAL
;
1901 wxString
regionTextColour("");
1902 wxString
penColour("");
1903 int penStyle
= wxSOLID
;
1905 if (regionExpr
->Type() == PrologList
)
1907 wxExpr
*nameExpr
= regionExpr
->Nth(0);
1908 wxExpr
*textExpr
= regionExpr
->Nth(1);
1909 wxExpr
*xExpr
= regionExpr
->Nth(2);
1910 wxExpr
*yExpr
= regionExpr
->Nth(3);
1911 wxExpr
*widthExpr
= regionExpr
->Nth(4);
1912 wxExpr
*heightExpr
= regionExpr
->Nth(5);
1913 wxExpr
*minWidthExpr
= regionExpr
->Nth(6);
1914 wxExpr
*minHeightExpr
= regionExpr
->Nth(7);
1915 wxExpr
*propXExpr
= regionExpr
->Nth(8);
1916 wxExpr
*propYExpr
= regionExpr
->Nth(9);
1917 wxExpr
*formatExpr
= regionExpr
->Nth(10);
1918 wxExpr
*sizeExpr
= regionExpr
->Nth(11);
1919 wxExpr
*familyExpr
= regionExpr
->Nth(12);
1920 wxExpr
*styleExpr
= regionExpr
->Nth(13);
1921 wxExpr
*weightExpr
= regionExpr
->Nth(14);
1922 wxExpr
*colourExpr
= regionExpr
->Nth(15);
1923 wxExpr
*penColourExpr
= regionExpr
->Nth(16);
1924 wxExpr
*penStyleExpr
= regionExpr
->Nth(17);
1926 regionName
= nameExpr
->StringValue();
1927 regionText
= textExpr
->StringValue();
1929 x
= xExpr
->RealValue();
1930 y
= yExpr
->RealValue();
1932 width
= widthExpr
->RealValue();
1933 height
= heightExpr
->RealValue();
1935 minWidth
= minWidthExpr
->RealValue();
1936 minHeight
= minHeightExpr
->RealValue();
1938 m_regionProportionX
= propXExpr
->RealValue();
1939 m_regionProportionY
= propYExpr
->RealValue();
1941 formatMode
= (int) formatExpr
->IntegerValue();
1942 fontSize
= (int)sizeExpr
->IntegerValue();
1943 fontFamily
= (int)familyExpr
->IntegerValue();
1944 fontStyle
= (int)styleExpr
->IntegerValue();
1945 fontWeight
= (int)weightExpr
->IntegerValue();
1949 regionTextColour
= colourExpr
->StringValue();
1952 regionTextColour
= "BLACK";
1955 penColour
= penColourExpr
->StringValue();
1957 penStyle
= (int)penStyleExpr
->IntegerValue();
1959 wxFont
*font
= wxTheFontList
->FindOrCreateFont(fontSize
, fontFamily
, fontStyle
, fontWeight
);
1961 wxShapeRegion
*region
= new wxShapeRegion
;
1962 region
->SetProportions(m_regionProportionX
, m_regionProportionY
);
1963 region
->SetFont(font
);
1964 region
->SetSize(width
, height
);
1965 region
->SetPosition(x
, y
);
1966 region
->SetMinSize(minWidth
, minHeight
);
1967 region
->SetFormatMode(formatMode
);
1968 region
->SetPenStyle(penStyle
);
1969 if (penColour
!= "")
1970 region
->SetPenColour(penColour
);
1972 region
->m_textColour
= regionTextColour
;
1973 region
->m_regionText
= regionText
;
1974 region
->m_regionName
= regionName
;
1976 m_regions
.Append(region
);
1979 * Get the formatted text strings
1982 textExpr
= clause
->AttributeValue(textNameBuf
);
1983 if (textExpr
&& (textExpr
->Type() == PrologList
))
1985 wxExpr
*node
= textExpr
->value
.first
;
1988 wxExpr
*string_expr
= node
;
1991 wxString
the_string("");
1993 // string_expr can either be a string, or a list of
1994 // 3 elements: x, y, and string.
1995 if (string_expr
->Type() == PrologString
)
1997 the_string
= string_expr
->StringValue();
1998 m_formatted
= FALSE
;
2000 else if (string_expr
->Type() == PrologList
)
2002 wxExpr
*first
= string_expr
->value
.first
;
2003 wxExpr
*second
= first
? first
->next
: NULL
;
2004 wxExpr
*third
= second
? second
->next
: NULL
;
2006 if (first
&& second
&& third
&&
2007 (first
->Type() == PrologReal
|| first
->Type() == PrologInteger
) &&
2008 (second
->Type() == PrologReal
|| second
->Type() == PrologInteger
) &&
2009 third
->Type() == PrologString
)
2011 if (first
->Type() == PrologReal
)
2012 the_x
= first
->RealValue();
2013 else the_x
= (float)first
->IntegerValue();
2015 if (second
->Type() == PrologReal
)
2016 the_y
= second
->RealValue();
2017 else the_y
= (float)second
->IntegerValue();
2019 the_string
= third
->StringValue();
2024 wxShapeTextLine
*line
=
2025 new wxShapeTextLine(the_x
, the_y
, (char*) (const char*) the_string
);
2026 region
->m_formattedText
.Append(line
);
2033 sprintf(regionNameBuf
, "region%d", regionNo
);
2034 sprintf(textNameBuf
, "text%d", regionNo
);
2037 // Compatibility: check for no regions (old file).
2038 // Lines and divided rectangles must deal with this compatibility
2039 // theirselves. Composites _may_ not have any regions anyway.
2040 if ((m_regions
.Number() == 0) &&
2041 !this->IsKindOf(CLASSINFO(wxLineShape
)) && !this->IsKindOf(CLASSINFO(wxDividedShape
)) &&
2042 !this->IsKindOf(CLASSINFO(wxCompositeShape
)))
2044 wxShapeRegion
*newRegion
= new wxShapeRegion
;
2045 newRegion
->SetName("0");
2046 m_regions
.Append((wxObject
*)newRegion
);
2047 if (m_text
.Number() > 0)
2049 newRegion
->ClearText();
2050 wxNode
*node
= m_text
.First();
2053 wxShapeTextLine
*textLine
= (wxShapeTextLine
*)node
->Data();
2054 wxNode
*next
= node
->Next();
2055 newRegion
->GetFormattedText().Append((wxObject
*)textLine
);
2065 void wxShape::Copy(wxShape
& copy
)
2068 copy
.m_xpos
= m_xpos
;
2069 copy
.m_ypos
= m_ypos
;
2071 copy
.m_brush
= m_brush
;
2072 copy
.m_textColour
= m_textColour
;
2073 copy
.m_centreResize
= m_centreResize
;
2074 copy
.m_attachmentMode
= m_attachmentMode
;
2075 copy
.m_spaceAttachments
= m_spaceAttachments
;
2076 copy
.m_highlighted
= m_highlighted
;
2077 copy
.m_rotation
= m_rotation
;
2078 copy
.m_textColourName
= m_textColourName
;
2079 copy
.m_regionName
= m_regionName
;
2081 copy
.m_sensitivity
= m_sensitivity
;
2082 copy
.m_draggable
= m_draggable
;
2083 copy
.m_fixedWidth
= m_fixedWidth
;
2084 copy
.m_fixedHeight
= m_fixedHeight
;
2085 copy
.m_formatMode
= m_formatMode
;
2086 copy
.m_drawHandles
= m_drawHandles
;
2088 copy
.m_visible
= m_visible
;
2089 copy
.m_shadowMode
= m_shadowMode
;
2090 copy
.m_shadowOffsetX
= m_shadowOffsetX
;
2091 copy
.m_shadowOffsetY
= m_shadowOffsetY
;
2092 copy
.m_shadowBrush
= m_shadowBrush
;
2094 // Copy text regions
2095 copy
.ClearRegions();
2096 wxNode
*node
= m_regions
.First();
2099 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
2100 wxShapeRegion
*newRegion
= new wxShapeRegion(*region
);
2101 copy
.m_regions
.Append(newRegion
);
2102 node
= node
->Next();
2106 copy
.ClearAttachments();
2107 node
= m_attachmentPoints
.First();
2110 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2111 wxAttachmentPoint
*newPoint
= new wxAttachmentPoint
;
2112 newPoint
->m_id
= point
->m_id
;
2113 newPoint
->m_x
= point
->m_x
;
2114 newPoint
->m_y
= point
->m_y
;
2115 copy
.m_attachmentPoints
.Append((wxObject
*)newPoint
);
2116 node
= node
->Next();
2120 // Create and return a new, fully copied object.
2121 wxShape
*wxShape::CreateNewCopy(bool resetMapping
, bool recompute
)
2124 wxObjectCopyMapping
.Clear();
2126 wxShape
* newObject
= (wxShape
*) GetClassInfo()->CreateObject();
2128 wxASSERT( (newObject
!= NULL
) );
2129 wxASSERT( (newObject
->IsKindOf(CLASSINFO(wxShape
))) );
2133 if (GetEventHandler() != this)
2135 wxShapeEvtHandler
* newHandler
= GetEventHandler()->CreateNewCopy();
2136 newObject
->SetEventHandler(newHandler
);
2137 newObject
->SetPreviousHandler(NULL
);
2138 newHandler
->SetPreviousHandler(newObject
);
2139 newHandler
->SetShape(newObject
);
2143 newObject
->Recompute();
2147 // Does the copying for this object, including copying event
2148 // handler data if any. Calls the virtual Copy function.
2149 void wxShape::CopyWithHandler(wxShape
& copy
)
2153 if (GetEventHandler() != this)
2155 wxASSERT( copy
.GetEventHandler() != NULL
);
2156 wxASSERT( copy
.GetEventHandler() != (©
) );
2157 wxASSERT( GetEventHandler()->GetClassInfo() == copy
.GetEventHandler()->GetClassInfo() );
2158 GetEventHandler()->CopyData(* (copy
.GetEventHandler()));
2163 // Default - make 6 control points
2164 void wxShape::MakeControlPoints()
2166 float maxX
, maxY
, minX
, minY
;
2168 GetBoundingBoxMax(&maxX
, &maxY
);
2169 GetBoundingBoxMin(&minX
, &minY
);
2171 float widthMin
= (float)(minX
+ CONTROL_POINT_SIZE
+ 2);
2172 float heightMin
= (float)(minY
+ CONTROL_POINT_SIZE
+ 2);
2174 // Offsets from main object
2175 float top
= (float)(- (heightMin
/ 2.0));
2176 float bottom
= (float)(heightMin
/ 2.0 + (maxY
- minY
));
2177 float left
= (float)(- (widthMin
/ 2.0));
2178 float right
= (float)(widthMin
/ 2.0 + (maxX
- minX
));
2180 wxControlPoint
*control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, top
,
2181 CONTROL_POINT_DIAGONAL
);
2182 m_canvas
->AddShape(control
);
2183 m_controlPoints
.Append(control
);
2185 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, 0, top
,
2186 CONTROL_POINT_VERTICAL
);
2187 m_canvas
->AddShape(control
);
2188 m_controlPoints
.Append(control
);
2190 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, top
,
2191 CONTROL_POINT_DIAGONAL
);
2192 m_canvas
->AddShape(control
);
2193 m_controlPoints
.Append(control
);
2195 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, 0,
2196 CONTROL_POINT_HORIZONTAL
);
2197 m_canvas
->AddShape(control
);
2198 m_controlPoints
.Append(control
);
2200 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, bottom
,
2201 CONTROL_POINT_DIAGONAL
);
2202 m_canvas
->AddShape(control
);
2203 m_controlPoints
.Append(control
);
2205 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, 0, bottom
,
2206 CONTROL_POINT_VERTICAL
);
2207 m_canvas
->AddShape(control
);
2208 m_controlPoints
.Append(control
);
2210 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, bottom
,
2211 CONTROL_POINT_DIAGONAL
);
2212 m_canvas
->AddShape(control
);
2213 m_controlPoints
.Append(control
);
2215 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, 0,
2216 CONTROL_POINT_HORIZONTAL
);
2217 m_canvas
->AddShape(control
);
2218 m_controlPoints
.Append(control
);
2222 void wxShape::MakeMandatoryControlPoints()
2224 wxNode
*node
= m_children
.First();
2227 wxShape
*child
= (wxShape
*)node
->Data();
2228 child
->MakeMandatoryControlPoints();
2229 node
= node
->Next();
2233 void wxShape::ResetMandatoryControlPoints()
2235 wxNode
*node
= m_children
.First();
2238 wxShape
*child
= (wxShape
*)node
->Data();
2239 child
->ResetMandatoryControlPoints();
2240 node
= node
->Next();
2244 void wxShape::ResetControlPoints()
2246 ResetMandatoryControlPoints();
2248 if (m_controlPoints
.Number() < 1)
2251 float maxX
, maxY
, minX
, minY
;
2253 GetBoundingBoxMax(&maxX
, &maxY
);
2254 GetBoundingBoxMin(&minX
, &minY
);
2256 float widthMin
= (float)(minX
+ CONTROL_POINT_SIZE
+ 2);
2257 float heightMin
= (float)(minY
+ CONTROL_POINT_SIZE
+ 2);
2259 // Offsets from main object
2260 float top
= (float)(- (heightMin
/ 2.0));
2261 float bottom
= (float)(heightMin
/ 2.0 + (maxY
- minY
));
2262 float left
= (float)(- (widthMin
/ 2.0));
2263 float right
= (float)(widthMin
/ 2.0 + (maxX
- minX
));
2265 wxNode
*node
= m_controlPoints
.First();
2266 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2267 control
->m_xoffset
= left
; control
->m_yoffset
= top
;
2269 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2270 control
->m_xoffset
= 0; control
->m_yoffset
= top
;
2272 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2273 control
->m_xoffset
= right
; control
->m_yoffset
= top
;
2275 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2276 control
->m_xoffset
= right
; control
->m_yoffset
= 0;
2278 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2279 control
->m_xoffset
= right
; control
->m_yoffset
= bottom
;
2281 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2282 control
->m_xoffset
= 0; control
->m_yoffset
= bottom
;
2284 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2285 control
->m_xoffset
= left
; control
->m_yoffset
= bottom
;
2287 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2288 control
->m_xoffset
= left
; control
->m_yoffset
= 0;
2291 void wxShape::DeleteControlPoints(wxDC
*dc
)
2293 wxNode
*node
= m_controlPoints
.First();
2296 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2298 control
->GetEventHandler()->OnErase(*dc
);
2299 m_canvas
->RemoveShape(control
);
2302 node
= m_controlPoints
.First();
2304 // Children of divisions are contained objects,
2306 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2308 node
= m_children
.First();
2311 wxShape
*child
= (wxShape
*)node
->Data();
2312 child
->DeleteControlPoints(dc
);
2313 node
= node
->Next();
2318 void wxShape::OnDrawControlPoints(wxDC
& dc
)
2323 dc
.SetBrush(wxBLACK_BRUSH
);
2324 dc
.SetPen(wxBLACK_PEN
);
2326 wxNode
*node
= m_controlPoints
.First();
2329 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2331 node
= node
->Next();
2333 // Children of divisions are contained objects,
2335 // This test bypasses the type facility for speed
2336 // (critical when drawing)
2337 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2339 node
= m_children
.First();
2342 wxShape
*child
= (wxShape
*)node
->Data();
2343 child
->GetEventHandler()->OnDrawControlPoints(dc
);
2344 node
= node
->Next();
2349 void wxShape::OnEraseControlPoints(wxDC
& dc
)
2351 wxNode
*node
= m_controlPoints
.First();
2354 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2356 node
= node
->Next();
2358 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2360 node
= m_children
.First();
2363 wxShape
*child
= (wxShape
*)node
->Data();
2364 child
->GetEventHandler()->OnEraseControlPoints(dc
);
2365 node
= node
->Next();
2370 void wxShape::Select(bool select
, wxDC
* dc
)
2372 m_selected
= select
;
2375 MakeControlPoints();
2376 // Children of divisions are contained objects,
2378 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2380 wxNode
*node
= m_children
.First();
2383 wxShape
*child
= (wxShape
*)node
->Data();
2384 child
->MakeMandatoryControlPoints();
2385 node
= node
->Next();
2389 GetEventHandler()->OnDrawControlPoints(*dc
);
2393 DeleteControlPoints(dc
);
2394 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2396 wxNode
*node
= m_children
.First();
2399 wxShape
*child
= (wxShape
*)node
->Data();
2400 child
->DeleteControlPoints(dc
);
2401 node
= node
->Next();
2407 bool wxShape::Selected() const
2412 bool wxShape::AncestorSelected() const
2414 if (m_selected
) return TRUE
;
2418 return GetParent()->AncestorSelected();
2421 int wxShape::GetNumberOfAttachments()
2423 // Should return the MAXIMUM attachment point id here,
2424 // so higher-level functions can iterate through all attachments,
2425 // even if they're not contiguous.
2426 if (m_attachmentPoints
.Number() == 0)
2431 wxNode
*node
= m_attachmentPoints
.First();
2434 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2435 if (point
->m_id
> maxN
)
2437 node
= node
->Next();
2443 bool wxShape::AttachmentIsValid(int attachment
)
2445 if ((attachment
>= 0) && (attachment
< 4))
2448 wxNode
*node
= m_attachmentPoints
.First();
2451 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2452 if (point
->m_id
== attachment
)
2454 node
= node
->Next();
2459 bool wxShape::GetAttachmentPosition(int attachment
, float *x
, float *y
,
2460 int nth
, int no_arcs
, wxLineShape
*line
)
2462 if (!m_attachmentMode
)
2464 *x
= m_xpos
; *y
= m_ypos
;
2469 wxNode
*node
= m_attachmentPoints
.First();
2472 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2473 if (point
->m_id
== attachment
)
2475 *x
= (float)(m_xpos
+ point
->m_x
);
2476 *y
= (float)(m_ypos
+ point
->m_y
);
2479 node
= node
->Next();
2481 *x
= m_xpos
; *y
= m_ypos
;
2486 void wxShape::GetBoundingBoxMax(float *w
, float *h
)
2489 GetBoundingBoxMin(&ww
, &hh
);
2490 if (m_shadowMode
!= SHADOW_NONE
)
2492 ww
+= m_shadowOffsetX
;
2493 hh
+= m_shadowOffsetY
;
2499 // Returns TRUE if image is a descendant of this composite
2500 bool wxShape::HasDescendant(wxShape
*image
)
2504 wxNode
*node
= m_children
.First();
2507 wxShape
*child
= (wxShape
*)node
->Data();
2508 bool ans
= child
->HasDescendant(image
);
2511 node
= node
->Next();
2516 // Clears points from a list of wxRealPoints, and clears list
2517 void wxShape::ClearPointList(wxList
& list
)
2519 wxNode
* node
= list
.First();
2522 wxRealPoint
* pt
= (wxRealPoint
*) node
->Data();
2525 node
= node
->Next();