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
!= "") && (penColour
!= "BLACK"))
1539 clause
->AddAttributeValueString("pen_colour", penColour
);
1544 wxString brushColour
= wxTheColourDatabase
->FindName(m_brush
->GetColour());
1546 if ((brushColour
!= "") && (brushColour
!= "WHITE"))
1547 clause
->AddAttributeValueString("brush_colour", brushColour
);
1549 if (m_brush
->GetStyle() != wxSOLID
)
1550 clause
->AddAttributeValue("brush_style", (long)m_brush
->GetStyle());
1555 int n_lines
= m_lines
.Number();
1558 wxExpr
*list
= new wxExpr(PrologList
);
1559 wxNode
*node
= m_lines
.First();
1562 wxShape
*line
= (wxShape
*)node
->Data();
1563 wxExpr
*id_expr
= new wxExpr(line
->GetId());
1564 list
->Append(id_expr
);
1565 node
= node
->Next();
1567 clause
->AddAttributeValue("arcs", list
);
1570 // Miscellaneous members
1571 if (m_attachmentMode
!= 0)
1572 clause
->AddAttributeValue("use_attachments", (long)m_attachmentMode
);
1573 if (m_sensitivity
!= OP_ALL
)
1574 clause
->AddAttributeValue("sensitivity", (long)m_sensitivity
);
1575 if (!m_spaceAttachments
)
1576 clause
->AddAttributeValue("space_attachments", (long)m_spaceAttachments
);
1578 clause
->AddAttributeValue("fixed_width", (long)m_fixedWidth
);
1580 clause
->AddAttributeValue("fixed_height", (long)m_fixedHeight
);
1581 if (m_shadowMode
!= SHADOW_NONE
)
1582 clause
->AddAttributeValue("shadow_mode", (long)m_shadowMode
);
1583 if (m_centreResize
!= TRUE
)
1584 clause
->AddAttributeValue("centre_resize", (long)0);
1585 if (m_highlighted
!= FALSE
)
1586 clause
->AddAttributeValue("hilite", (long)m_highlighted
);
1588 if (m_parent
) // For composite objects
1589 clause
->AddAttributeValue("parent", (long)m_parent
->GetId());
1591 if (m_rotation
!= 0.0)
1592 clause
->AddAttributeValue("rotation", m_rotation
);
1594 // Write user-defined attachment points, if any
1595 if (m_attachmentPoints
.Number() > 0)
1597 wxExpr
*attachmentList
= new wxExpr(PrologList
);
1598 wxNode
*node
= m_attachmentPoints
.First();
1601 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
1602 wxExpr
*pointExpr
= new wxExpr(PrologList
);
1603 pointExpr
->Append(new wxExpr((long)point
->m_id
));
1604 pointExpr
->Append(new wxExpr(point
->m_x
));
1605 pointExpr
->Append(new wxExpr(point
->m_y
));
1606 attachmentList
->Append(pointExpr
);
1607 node
= node
->Next();
1609 clause
->AddAttributeValue("user_attachments", attachmentList
);
1612 // Write text regions
1613 WriteRegions(clause
);
1616 void wxShape::WriteRegions(wxExpr
*clause
)
1618 // Output regions as region1 = (...), region2 = (...), etc
1619 // and formatted text as text1 = (...), text2 = (...) etc.
1621 char regionNameBuf
[20];
1622 char textNameBuf
[20];
1623 wxNode
*node
= m_regions
.First();
1626 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
1627 sprintf(regionNameBuf
, "region%d", regionNo
);
1628 sprintf(textNameBuf
, "text%d", regionNo
);
1630 // Original text and region attributes:
1631 // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
1632 // formatMode fontSize fontFamily fontStyle fontWeight textColour)
1633 wxExpr
*regionExpr
= new wxExpr(PrologList
);
1634 regionExpr
->Append(new wxExpr(PrologString
, (region
->m_regionName
? region
->m_regionName
: "")));
1635 regionExpr
->Append(new wxExpr(PrologString
, (region
->m_regionText
? region
->m_regionText
: "")));
1637 regionExpr
->Append(new wxExpr(region
->m_x
));
1638 regionExpr
->Append(new wxExpr(region
->m_y
));
1639 regionExpr
->Append(new wxExpr(region
->GetWidth()));
1640 regionExpr
->Append(new wxExpr(region
->GetHeight()));
1642 regionExpr
->Append(new wxExpr(region
->m_minWidth
));
1643 regionExpr
->Append(new wxExpr(region
->m_minHeight
));
1644 regionExpr
->Append(new wxExpr(region
->m_regionProportionX
));
1645 regionExpr
->Append(new wxExpr(region
->m_regionProportionY
));
1647 regionExpr
->Append(new wxExpr((long)region
->m_formatMode
));
1649 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetPointSize() : 10)));
1650 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetFamily() : wxDEFAULT
)));
1651 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetStyle() : wxDEFAULT
)));
1652 regionExpr
->Append(new wxExpr((long)(region
->m_font
? region
->m_font
->GetWeight() : wxNORMAL
)));
1653 regionExpr
->Append(new wxExpr(PrologString
, region
->m_textColour
? region
->m_textColour
: "BLACK"));
1655 // New members for pen colour/style
1656 regionExpr
->Append(new wxExpr(PrologString
, region
->m_penColour
? region
->m_penColour
: "BLACK"));
1657 regionExpr
->Append(new wxExpr((long)region
->m_penStyle
));
1660 // text1 = ((x y string) (x y string) ...)
1661 wxExpr
*textExpr
= new wxExpr(PrologList
);
1663 wxNode
*textNode
= region
->m_formattedText
.First();
1666 wxShapeTextLine
*line
= (wxShapeTextLine
*)textNode
->Data();
1667 wxExpr
*list2
= new wxExpr(PrologList
);
1668 list2
->Append(new wxExpr(line
->GetX()));
1669 list2
->Append(new wxExpr(line
->GetY()));
1670 list2
->Append(new wxExpr(PrologString
, line
->GetText()));
1671 textExpr
->Append(list2
);
1672 textNode
= textNode
->Next();
1675 // Now add both attributes to the clause
1676 clause
->AddAttributeValue(regionNameBuf
, regionExpr
);
1677 clause
->AddAttributeValue(textNameBuf
, textExpr
);
1679 node
= node
->Next();
1684 void wxShape::ReadPrologAttributes(wxExpr
*clause
)
1686 clause
->GetAttributeValue("id", m_id
);
1689 clause
->GetAttributeValue("x", m_xpos
);
1690 clause
->GetAttributeValue("y", m_ypos
);
1692 // Input text strings (FOR COMPATIBILITY WITH OLD FILES ONLY. SEE REGION CODE BELOW.)
1694 wxExpr
*strings
= clause
->AttributeValue("text");
1695 if (strings
&& strings
->Type() == PrologList
)
1697 m_formatted
= TRUE
; // Assume text is formatted unless we prove otherwise
1698 wxExpr
*node
= strings
->value
.first
;
1701 wxExpr
*string_expr
= node
;
1704 wxString
the_string("");
1706 // string_expr can either be a string, or a list of
1707 // 3 elements: x, y, and string.
1708 if (string_expr
->Type() == PrologString
)
1710 the_string
= string_expr
->StringValue();
1711 m_formatted
= FALSE
;
1713 else if (string_expr
->Type() == PrologList
)
1715 wxExpr
*first
= string_expr
->value
.first
;
1716 wxExpr
*second
= first
? first
->next
: NULL
;
1717 wxExpr
*third
= second
? second
->next
: NULL
;
1719 if (first
&& second
&& third
&&
1720 (first
->Type() == PrologReal
|| first
->Type() == PrologInteger
) &&
1721 (second
->Type() == PrologReal
|| second
->Type() == PrologInteger
) &&
1722 third
->Type() == PrologString
)
1724 if (first
->Type() == PrologReal
)
1725 the_x
= first
->RealValue();
1726 else the_x
= (float)first
->IntegerValue();
1728 if (second
->Type() == PrologReal
)
1729 the_y
= second
->RealValue();
1730 else the_y
= (float)second
->IntegerValue();
1732 the_string
= third
->StringValue();
1735 wxShapeTextLine
*line
=
1736 new wxShapeTextLine(the_x
, the_y
, (char*) (const char*) the_string
);
1737 m_text
.Append(line
);
1743 wxString pen_string
= "";
1744 wxString brush_string
= "";
1746 int pen_style
= wxSOLID
;
1747 int brush_style
= wxSOLID
;
1748 m_attachmentMode
= FALSE
;
1750 clause
->GetAttributeValue("pen_colour", pen_string
);
1751 clause
->GetAttributeValue("text_colour", m_textColourName
);
1753 SetTextColour(m_textColourName
);
1755 clause
->GetAttributeValue("region_name", m_regionName
);
1757 clause
->GetAttributeValue("brush_colour", brush_string
);
1758 clause
->GetAttributeValue("pen_width", pen_width
);
1759 clause
->GetAttributeValue("pen_style", pen_style
);
1760 clause
->GetAttributeValue("brush_style", brush_style
);
1762 int iVal
= (int) m_attachmentMode
;
1763 clause
->GetAttributeValue("use_attachments", iVal
);
1764 m_attachmentMode
= (iVal
!= 0);
1766 clause
->GetAttributeValue("sensitivity", m_sensitivity
);
1768 iVal
= (int) m_spaceAttachments
;
1769 clause
->GetAttributeValue("space_attachments", iVal
);
1770 m_spaceAttachments
= (iVal
!= 0);
1772 iVal
= (int) m_fixedWidth
;
1773 clause
->GetAttributeValue("fixed_width", iVal
);
1774 m_fixedWidth
= (iVal
!= 0);
1776 iVal
= (int) m_fixedHeight
;
1777 clause
->GetAttributeValue("fixed_height", iVal
);
1778 m_fixedHeight
= (iVal
!= 0);
1780 clause
->GetAttributeValue("format_mode", m_formatMode
);
1781 clause
->GetAttributeValue("shadow_mode", m_shadowMode
);
1783 iVal
= (int) m_centreResize
;
1784 clause
->GetAttributeValue("centre_resize", iVal
);
1785 m_centreResize
= (iVal
!= 0);
1787 iVal
= (int) m_highlighted
;
1788 clause
->GetAttributeValue("hilite", iVal
);
1789 m_highlighted
= (iVal
!= 0);
1791 clause
->GetAttributeValue("rotation", m_rotation
);
1793 if (pen_string
== "")
1794 pen_string
= "BLACK";
1795 if (brush_string
== "")
1796 brush_string
= "WHITE";
1798 m_pen
= wxThePenList
->FindOrCreatePen(pen_string
, pen_width
, pen_style
);
1800 m_pen
= wxBLACK_PEN
;
1802 m_brush
= wxTheBrushList
->FindOrCreateBrush(brush_string
, brush_style
);
1804 m_brush
= wxWHITE_BRUSH
;
1806 int point_size
= 10;
1807 clause
->GetAttributeValue("point_size", point_size
);
1808 SetFont(MatchFont(point_size
));
1810 // Read user-defined attachment points, if any
1811 wxExpr
*attachmentList
= clause
->AttributeValue("user_attachments");
1814 wxExpr
*pointExpr
= attachmentList
->GetFirst();
1817 wxExpr
*idExpr
= pointExpr
->Nth(0);
1818 wxExpr
*xExpr
= pointExpr
->Nth(1);
1819 wxExpr
*yExpr
= pointExpr
->Nth(2);
1820 if (idExpr
&& xExpr
&& yExpr
)
1822 wxAttachmentPoint
*point
= new wxAttachmentPoint
;
1823 point
->m_id
= (int)idExpr
->IntegerValue();
1824 point
->m_x
= xExpr
->RealValue();
1825 point
->m_y
= yExpr
->RealValue();
1826 m_attachmentPoints
.Append((wxObject
*)point
);
1828 pointExpr
= pointExpr
->GetNext();
1832 // Read text regions
1833 ReadRegions(clause
);
1836 void wxShape::ReadRegions(wxExpr
*clause
)
1840 // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
1841 // formatMode fontSize fontFamily fontStyle fontWeight textColour)
1843 char regionNameBuf
[20];
1844 char textNameBuf
[20];
1846 wxExpr
*regionExpr
= NULL
;
1847 wxExpr
*textExpr
= NULL
;
1848 sprintf(regionNameBuf
, "region%d", regionNo
);
1849 sprintf(textNameBuf
, "text%d", regionNo
);
1851 m_formatted
= TRUE
; // Assume text is formatted unless we prove otherwise
1853 while (regionExpr
= clause
->AttributeValue(regionNameBuf
))
1856 * Get the region information
1860 wxString
regionName("");
1861 wxString
regionText("");
1866 float minWidth
= 5.0;
1867 float minHeight
= 5.0;
1868 float m_regionProportionX
= -1.0;
1869 float m_regionProportionY
= -1.0;
1870 int formatMode
= FORMAT_NONE
;
1872 int fontFamily
= wxSWISS
;
1873 int fontStyle
= wxNORMAL
;
1874 int fontWeight
= wxNORMAL
;
1875 wxString
regionTextColour("");
1876 wxString
penColour("");
1877 int penStyle
= wxSOLID
;
1879 if (regionExpr
->Type() == PrologList
)
1881 wxExpr
*nameExpr
= regionExpr
->Nth(0);
1882 wxExpr
*textExpr
= regionExpr
->Nth(1);
1883 wxExpr
*xExpr
= regionExpr
->Nth(2);
1884 wxExpr
*yExpr
= regionExpr
->Nth(3);
1885 wxExpr
*widthExpr
= regionExpr
->Nth(4);
1886 wxExpr
*heightExpr
= regionExpr
->Nth(5);
1887 wxExpr
*minWidthExpr
= regionExpr
->Nth(6);
1888 wxExpr
*minHeightExpr
= regionExpr
->Nth(7);
1889 wxExpr
*propXExpr
= regionExpr
->Nth(8);
1890 wxExpr
*propYExpr
= regionExpr
->Nth(9);
1891 wxExpr
*formatExpr
= regionExpr
->Nth(10);
1892 wxExpr
*sizeExpr
= regionExpr
->Nth(11);
1893 wxExpr
*familyExpr
= regionExpr
->Nth(12);
1894 wxExpr
*styleExpr
= regionExpr
->Nth(13);
1895 wxExpr
*weightExpr
= regionExpr
->Nth(14);
1896 wxExpr
*colourExpr
= regionExpr
->Nth(15);
1897 wxExpr
*penColourExpr
= regionExpr
->Nth(16);
1898 wxExpr
*penStyleExpr
= regionExpr
->Nth(17);
1900 regionName
= nameExpr
->StringValue();
1901 regionText
= textExpr
->StringValue();
1903 x
= xExpr
->RealValue();
1904 y
= yExpr
->RealValue();
1906 width
= widthExpr
->RealValue();
1907 height
= heightExpr
->RealValue();
1909 minWidth
= minWidthExpr
->RealValue();
1910 minHeight
= minHeightExpr
->RealValue();
1912 m_regionProportionX
= propXExpr
->RealValue();
1913 m_regionProportionY
= propYExpr
->RealValue();
1915 formatMode
= (int) formatExpr
->IntegerValue();
1916 fontSize
= (int)sizeExpr
->IntegerValue();
1917 fontFamily
= (int)familyExpr
->IntegerValue();
1918 fontStyle
= (int)styleExpr
->IntegerValue();
1919 fontWeight
= (int)weightExpr
->IntegerValue();
1923 regionTextColour
= colourExpr
->StringValue();
1926 regionTextColour
= "BLACK";
1929 penColour
= penColourExpr
->StringValue();
1931 penStyle
= (int)penStyleExpr
->IntegerValue();
1933 wxFont
*font
= wxTheFontList
->FindOrCreateFont(fontSize
, fontFamily
, fontStyle
, fontWeight
);
1935 wxShapeRegion
*region
= new wxShapeRegion
;
1936 region
->SetProportions(m_regionProportionX
, m_regionProportionY
);
1937 region
->SetFont(font
);
1938 region
->SetSize(width
, height
);
1939 region
->SetPosition(x
, y
);
1940 region
->SetMinSize(minWidth
, minHeight
);
1941 region
->SetFormatMode(formatMode
);
1942 region
->SetPenStyle(penStyle
);
1943 if (penColour
!= "")
1944 region
->SetPenColour(penColour
);
1946 region
->m_textColour
= regionTextColour
;
1947 region
->m_regionText
= regionText
;
1948 region
->m_regionName
= regionName
;
1950 m_regions
.Append(region
);
1953 * Get the formatted text strings
1956 textExpr
= clause
->AttributeValue(textNameBuf
);
1957 if (textExpr
&& (textExpr
->Type() == PrologList
))
1959 wxExpr
*node
= textExpr
->value
.first
;
1962 wxExpr
*string_expr
= node
;
1965 wxString
the_string("");
1967 // string_expr can either be a string, or a list of
1968 // 3 elements: x, y, and string.
1969 if (string_expr
->Type() == PrologString
)
1971 the_string
= string_expr
->StringValue();
1972 m_formatted
= FALSE
;
1974 else if (string_expr
->Type() == PrologList
)
1976 wxExpr
*first
= string_expr
->value
.first
;
1977 wxExpr
*second
= first
? first
->next
: NULL
;
1978 wxExpr
*third
= second
? second
->next
: NULL
;
1980 if (first
&& second
&& third
&&
1981 (first
->Type() == PrologReal
|| first
->Type() == PrologInteger
) &&
1982 (second
->Type() == PrologReal
|| second
->Type() == PrologInteger
) &&
1983 third
->Type() == PrologString
)
1985 if (first
->Type() == PrologReal
)
1986 the_x
= first
->RealValue();
1987 else the_x
= (float)first
->IntegerValue();
1989 if (second
->Type() == PrologReal
)
1990 the_y
= second
->RealValue();
1991 else the_y
= (float)second
->IntegerValue();
1993 the_string
= third
->StringValue();
1998 wxShapeTextLine
*line
=
1999 new wxShapeTextLine(the_x
, the_y
, (char*) (const char*) the_string
);
2000 region
->m_formattedText
.Append(line
);
2007 sprintf(regionNameBuf
, "region%d", regionNo
);
2008 sprintf(textNameBuf
, "text%d", regionNo
);
2011 // Compatibility: check for no regions (old file).
2012 // Lines and divided rectangles must deal with this compatibility
2013 // theirselves. Composites _may_ not have any regions anyway.
2014 if ((m_regions
.Number() == 0) &&
2015 !this->IsKindOf(CLASSINFO(wxLineShape
)) && !this->IsKindOf(CLASSINFO(wxDividedShape
)) &&
2016 !this->IsKindOf(CLASSINFO(wxCompositeShape
)))
2018 wxShapeRegion
*newRegion
= new wxShapeRegion
;
2019 newRegion
->SetName("0");
2020 m_regions
.Append((wxObject
*)newRegion
);
2021 if (m_text
.Number() > 0)
2023 newRegion
->ClearText();
2024 wxNode
*node
= m_text
.First();
2027 wxShapeTextLine
*textLine
= (wxShapeTextLine
*)node
->Data();
2028 wxNode
*next
= node
->Next();
2029 newRegion
->GetFormattedText().Append((wxObject
*)textLine
);
2039 void wxShape::Copy(wxShape
& copy
)
2042 copy
.m_xpos
= m_xpos
;
2043 copy
.m_ypos
= m_ypos
;
2045 copy
.m_brush
= m_brush
;
2046 copy
.m_textColour
= m_textColour
;
2047 copy
.m_centreResize
= m_centreResize
;
2048 copy
.m_attachmentMode
= m_attachmentMode
;
2049 copy
.m_spaceAttachments
= m_spaceAttachments
;
2050 copy
.m_highlighted
= m_highlighted
;
2051 copy
.m_rotation
= m_rotation
;
2052 copy
.m_textColourName
= m_textColourName
;
2053 copy
.m_regionName
= m_regionName
;
2055 copy
.m_sensitivity
= m_sensitivity
;
2056 copy
.m_draggable
= m_draggable
;
2057 copy
.m_fixedWidth
= m_fixedWidth
;
2058 copy
.m_fixedHeight
= m_fixedHeight
;
2059 copy
.m_formatMode
= m_formatMode
;
2060 copy
.m_drawHandles
= m_drawHandles
;
2062 copy
.m_visible
= m_visible
;
2063 copy
.m_shadowMode
= m_shadowMode
;
2064 copy
.m_shadowOffsetX
= m_shadowOffsetX
;
2065 copy
.m_shadowOffsetY
= m_shadowOffsetY
;
2066 copy
.m_shadowBrush
= m_shadowBrush
;
2068 // Copy text regions
2069 copy
.ClearRegions();
2070 wxNode
*node
= m_regions
.First();
2073 wxShapeRegion
*region
= (wxShapeRegion
*)node
->Data();
2074 wxShapeRegion
*newRegion
= new wxShapeRegion(*region
);
2075 copy
.m_regions
.Append(newRegion
);
2076 node
= node
->Next();
2080 copy
.ClearAttachments();
2081 node
= m_attachmentPoints
.First();
2084 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2085 wxAttachmentPoint
*newPoint
= new wxAttachmentPoint
;
2086 newPoint
->m_id
= point
->m_id
;
2087 newPoint
->m_x
= point
->m_x
;
2088 newPoint
->m_y
= point
->m_y
;
2089 copy
.m_attachmentPoints
.Append((wxObject
*)newPoint
);
2090 node
= node
->Next();
2094 // Create and return a new, fully copied object.
2095 wxShape
*wxShape::CreateNewCopy(bool resetMapping
, bool recompute
)
2098 wxObjectCopyMapping
.Clear();
2100 wxShape
* newObject
= (wxShape
*) GetClassInfo()->CreateObject();
2102 wxASSERT( (newObject
!= NULL
) );
2103 wxASSERT( (newObject
->IsKindOf(CLASSINFO(wxShape
))) );
2107 if (GetEventHandler() != this)
2109 wxShapeEvtHandler
* newHandler
= GetEventHandler()->CreateNewCopy();
2110 newObject
->SetEventHandler(newHandler
);
2111 newObject
->SetPreviousHandler(NULL
);
2112 newHandler
->SetPreviousHandler(newObject
);
2113 newHandler
->SetShape(newObject
);
2117 newObject
->Recompute();
2121 // Does the copying for this object, including copying event
2122 // handler data if any. Calls the virtual Copy function.
2123 void wxShape::CopyWithHandler(wxShape
& copy
)
2127 if (GetEventHandler() != this)
2129 wxASSERT( copy
.GetEventHandler() != NULL
);
2130 wxASSERT( copy
.GetEventHandler() != (©
) );
2131 wxASSERT( GetEventHandler()->GetClassInfo() == copy
.GetEventHandler()->GetClassInfo() );
2132 GetEventHandler()->CopyData(* (copy
.GetEventHandler()));
2137 // Default - make 6 control points
2138 void wxShape::MakeControlPoints()
2140 float maxX
, maxY
, minX
, minY
;
2142 GetBoundingBoxMax(&maxX
, &maxY
);
2143 GetBoundingBoxMin(&minX
, &minY
);
2145 float widthMin
= (float)(minX
+ CONTROL_POINT_SIZE
+ 2);
2146 float heightMin
= (float)(minY
+ CONTROL_POINT_SIZE
+ 2);
2148 // Offsets from main object
2149 float top
= (float)(- (heightMin
/ 2.0));
2150 float bottom
= (float)(heightMin
/ 2.0 + (maxY
- minY
));
2151 float left
= (float)(- (widthMin
/ 2.0));
2152 float right
= (float)(widthMin
/ 2.0 + (maxX
- minX
));
2154 wxControlPoint
*control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, top
,
2155 CONTROL_POINT_DIAGONAL
);
2156 m_canvas
->AddShape(control
);
2157 m_controlPoints
.Append(control
);
2159 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, 0, top
,
2160 CONTROL_POINT_VERTICAL
);
2161 m_canvas
->AddShape(control
);
2162 m_controlPoints
.Append(control
);
2164 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, top
,
2165 CONTROL_POINT_DIAGONAL
);
2166 m_canvas
->AddShape(control
);
2167 m_controlPoints
.Append(control
);
2169 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, 0,
2170 CONTROL_POINT_HORIZONTAL
);
2171 m_canvas
->AddShape(control
);
2172 m_controlPoints
.Append(control
);
2174 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, right
, bottom
,
2175 CONTROL_POINT_DIAGONAL
);
2176 m_canvas
->AddShape(control
);
2177 m_controlPoints
.Append(control
);
2179 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, 0, bottom
,
2180 CONTROL_POINT_VERTICAL
);
2181 m_canvas
->AddShape(control
);
2182 m_controlPoints
.Append(control
);
2184 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, bottom
,
2185 CONTROL_POINT_DIAGONAL
);
2186 m_canvas
->AddShape(control
);
2187 m_controlPoints
.Append(control
);
2189 control
= new wxControlPoint(m_canvas
, this, CONTROL_POINT_SIZE
, left
, 0,
2190 CONTROL_POINT_HORIZONTAL
);
2191 m_canvas
->AddShape(control
);
2192 m_controlPoints
.Append(control
);
2196 void wxShape::MakeMandatoryControlPoints()
2198 wxNode
*node
= m_children
.First();
2201 wxShape
*child
= (wxShape
*)node
->Data();
2202 child
->MakeMandatoryControlPoints();
2203 node
= node
->Next();
2207 void wxShape::ResetMandatoryControlPoints()
2209 wxNode
*node
= m_children
.First();
2212 wxShape
*child
= (wxShape
*)node
->Data();
2213 child
->ResetMandatoryControlPoints();
2214 node
= node
->Next();
2218 void wxShape::ResetControlPoints()
2220 ResetMandatoryControlPoints();
2222 if (m_controlPoints
.Number() < 1)
2225 float maxX
, maxY
, minX
, minY
;
2227 GetBoundingBoxMax(&maxX
, &maxY
);
2228 GetBoundingBoxMin(&minX
, &minY
);
2230 float widthMin
= (float)(minX
+ CONTROL_POINT_SIZE
+ 2);
2231 float heightMin
= (float)(minY
+ CONTROL_POINT_SIZE
+ 2);
2233 // Offsets from main object
2234 float top
= (float)(- (heightMin
/ 2.0));
2235 float bottom
= (float)(heightMin
/ 2.0 + (maxY
- minY
));
2236 float left
= (float)(- (widthMin
/ 2.0));
2237 float right
= (float)(widthMin
/ 2.0 + (maxX
- minX
));
2239 wxNode
*node
= m_controlPoints
.First();
2240 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2241 control
->m_xoffset
= left
; control
->m_yoffset
= top
;
2243 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2244 control
->m_xoffset
= 0; control
->m_yoffset
= top
;
2246 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2247 control
->m_xoffset
= right
; control
->m_yoffset
= top
;
2249 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2250 control
->m_xoffset
= right
; control
->m_yoffset
= 0;
2252 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2253 control
->m_xoffset
= right
; control
->m_yoffset
= bottom
;
2255 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2256 control
->m_xoffset
= 0; control
->m_yoffset
= bottom
;
2258 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2259 control
->m_xoffset
= left
; control
->m_yoffset
= bottom
;
2261 node
= node
->Next(); control
= (wxControlPoint
*)node
->Data();
2262 control
->m_xoffset
= left
; control
->m_yoffset
= 0;
2265 void wxShape::DeleteControlPoints(wxDC
*dc
)
2267 wxNode
*node
= m_controlPoints
.First();
2270 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2272 control
->GetEventHandler()->OnErase(*dc
);
2273 m_canvas
->RemoveShape(control
);
2276 node
= m_controlPoints
.First();
2278 // Children of divisions are contained objects,
2280 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2282 node
= m_children
.First();
2285 wxShape
*child
= (wxShape
*)node
->Data();
2286 child
->DeleteControlPoints(dc
);
2287 node
= node
->Next();
2292 void wxShape::OnDrawControlPoints(wxDC
& dc
)
2297 dc
.SetBrush(wxBLACK_BRUSH
);
2298 dc
.SetPen(wxBLACK_PEN
);
2300 wxNode
*node
= m_controlPoints
.First();
2303 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2305 node
= node
->Next();
2307 // Children of divisions are contained objects,
2309 // This test bypasses the type facility for speed
2310 // (critical when drawing)
2311 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2313 node
= m_children
.First();
2316 wxShape
*child
= (wxShape
*)node
->Data();
2317 child
->GetEventHandler()->OnDrawControlPoints(dc
);
2318 node
= node
->Next();
2323 void wxShape::OnEraseControlPoints(wxDC
& dc
)
2325 wxNode
*node
= m_controlPoints
.First();
2328 wxControlPoint
*control
= (wxControlPoint
*)node
->Data();
2330 node
= node
->Next();
2332 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2334 node
= m_children
.First();
2337 wxShape
*child
= (wxShape
*)node
->Data();
2338 child
->GetEventHandler()->OnEraseControlPoints(dc
);
2339 node
= node
->Next();
2344 void wxShape::Select(bool select
, wxDC
* dc
)
2346 m_selected
= select
;
2349 MakeControlPoints();
2350 // Children of divisions are contained objects,
2352 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2354 wxNode
*node
= m_children
.First();
2357 wxShape
*child
= (wxShape
*)node
->Data();
2358 child
->MakeMandatoryControlPoints();
2359 node
= node
->Next();
2363 GetEventHandler()->OnDrawControlPoints(*dc
);
2367 DeleteControlPoints(dc
);
2368 if (!IsKindOf(CLASSINFO(wxDivisionShape
)))
2370 wxNode
*node
= m_children
.First();
2373 wxShape
*child
= (wxShape
*)node
->Data();
2374 child
->DeleteControlPoints(dc
);
2375 node
= node
->Next();
2381 bool wxShape::Selected() const
2386 bool wxShape::AncestorSelected() const
2388 if (m_selected
) return TRUE
;
2392 return GetParent()->AncestorSelected();
2395 int wxShape::GetNumberOfAttachments()
2397 // Should return the MAXIMUM attachment point id here,
2398 // so higher-level functions can iterate through all attachments,
2399 // even if they're not contiguous.
2400 if (m_attachmentPoints
.Number() == 0)
2405 wxNode
*node
= m_attachmentPoints
.First();
2408 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2409 if (point
->m_id
> maxN
)
2411 node
= node
->Next();
2417 bool wxShape::AttachmentIsValid(int attachment
)
2419 if ((attachment
>= 0) && (attachment
< 4))
2422 wxNode
*node
= m_attachmentPoints
.First();
2425 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2426 if (point
->m_id
== attachment
)
2428 node
= node
->Next();
2433 bool wxShape::GetAttachmentPosition(int attachment
, float *x
, float *y
,
2434 int nth
, int no_arcs
, wxLineShape
*line
)
2436 if (!m_attachmentMode
)
2438 *x
= m_xpos
; *y
= m_ypos
;
2443 wxNode
*node
= m_attachmentPoints
.First();
2446 wxAttachmentPoint
*point
= (wxAttachmentPoint
*)node
->Data();
2447 if (point
->m_id
== attachment
)
2449 *x
= (float)(m_xpos
+ point
->m_x
);
2450 *y
= (float)(m_ypos
+ point
->m_y
);
2453 node
= node
->Next();
2455 *x
= m_xpos
; *y
= m_ypos
;
2460 void wxShape::GetBoundingBoxMax(float *w
, float *h
)
2463 GetBoundingBoxMin(&ww
, &hh
);
2464 if (m_shadowMode
!= SHADOW_NONE
)
2466 ww
+= m_shadowOffsetX
;
2467 hh
+= m_shadowOffsetY
;
2473 // Returns TRUE if image is a descendant of this composite
2474 bool wxShape::HasDescendant(wxShape
*image
)
2478 wxNode
*node
= m_children
.First();
2481 wxShape
*child
= (wxShape
*)node
->Data();
2482 bool ans
= child
->HasDescendant(image
);
2485 node
= node
->Next();
2490 // Clears points from a list of wxRealPoints, and clears list
2491 void wxShape::ClearPointList(wxList
& list
)
2493 wxNode
* node
= list
.First();
2496 wxRealPoint
* pt
= (wxRealPoint
*) node
->Data();
2499 node
= node
->Next();