#include <wx/wx.h>
#endif
-#ifdef PROLOGIO
#include <wx/wxexpr.h>
-#endif
-#if USE_IOSTREAMH
+#if wxUSE_IOSTREAMH
#include <iostream.h>
#else
#include <iostream>
m_previousHandler->OnDrawContents(dc);
}
+void wxShapeEvtHandler::OnDrawBranches(wxDC& dc, bool erase)
+{
+ if (m_previousHandler)
+ m_previousHandler->OnDrawBranches(dc, erase);
+}
+
void wxShapeEvtHandler::OnSize(double x, double y)
{
if (m_previousHandler)
m_previousHandler->OnLeftClick(x, y, keys, attachment);
}
+void wxShapeEvtHandler::OnLeftDoubleClick(double x, double y, int keys, int attachment)
+{
+ if (m_previousHandler)
+ m_previousHandler->OnLeftDoubleClick(x, y, keys, attachment);
+}
+
void wxShapeEvtHandler::OnRightClick(double x, double y, int keys, int attachment)
{
if (m_previousHandler)
m_visible = FALSE;
m_clientData = NULL;
m_selected = FALSE;
- m_attachmentMode = FALSE;
+ m_attachmentMode = ATTACHMENT_MODE_NONE;
m_spaceAttachments = TRUE;
m_disableLabel = FALSE;
m_fixedWidth = FALSE;
m_parent = NULL;
m_formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT;
m_shadowMode = SHADOW_NONE;
- m_shadowOffsetX = 6.0;
- m_shadowOffsetY = 6.0;
+ m_shadowOffsetX = 6;
+ m_shadowOffsetY = 6;
m_shadowBrush = wxBLACK_BRUSH;
- m_textMarginX = 5.0;
- m_textMarginY = 5.0;
+ m_textMarginX = 5;
+ m_textMarginY = 5;
m_regionName = "0";
m_centreResize = TRUE;
+ m_maintainAspectRatio = FALSE;
m_highlighted = FALSE;
m_rotation = 0.0;
+ m_branchNeckLength = 10;
+ m_branchStemLength = 10;
+ m_branchSpacing = 10;
+ m_branchStyle = BRANCHING_ATTACHMENT_NORMAL;
// Set up a default region. Much of the above will be put into
// the region eventually (the duplication is for compatibility)
int nearest_attachment = 0;
-
// If within the bounding box, check the attachment points
// within the object.
int n = GetNumberOfAttachments();
double nearest = 999999.0;
+ // GetAttachmentPosition[Edge] takes a logical attachment position,
+ // i.e. if it's rotated through 90%, position 0 is East-facing.
+
for (int i = 0; i < n; i++)
{
double xp, yp;
- if (GetAttachmentPosition(i, &xp, &yp))
+ if (GetAttachmentPositionEdge(i, &xp, &yp))
{
double l = (double)sqrt(((xp - x) * (xp - x)) +
((yp - y) * (yp - y)));
wxNode *node = m_regions.Nth(i);
if (!node)
return;
-
+
wxShapeRegion *region = (wxShapeRegion *)node->Data();
region->SetText(s);
- dc.SetFont(region->GetFont());
+ dc.SetFont(* region->GetFont());
region->GetSize(&w, &h);
{
if (!GetParent())
return this;
-
+
if (GetParent()->IsKindOf(CLASSINFO(wxDivisionShape)))
return this;
else return GetParent()->GetTopAncestor();
void wxShape::AssignNewIds()
{
// if (m_id == 0)
- m_id = NewId();
+ m_id = wxNewId();
wxNode *node = m_children.First();
while (node)
{
GetBoundingBoxMin(&bound_x, &bound_y);
if (m_regions.Number() < 1) return;
- if (m_pen) dc.SetPen(m_pen);
+ if (m_pen) dc.SetPen(* m_pen);
wxShapeRegion *region = (wxShapeRegion *)m_regions.First()->Data();
- if (region->GetFont()) dc.SetFont(region->GetFont());
+ if (region->GetFont()) dc.SetFont(* region->GetFont());
dc.SetTextForeground(* (region->GetActualColourObject()));
dc.SetBackgroundMode(wxTRANSPARENT);
if (m_pen)
penWidth = m_pen->GetWidth();
- dc.SetPen(g_oglWhiteBackgroundPen);
- dc.SetBrush(g_oglWhiteBackgroundBrush);
+ dc.SetPen(* g_oglWhiteBackgroundPen);
+ dc.SetBrush(* g_oglWhiteBackgroundBrush);
dc.DrawRectangle(WXROUND(topLeftX - penWidth), WXROUND(topLeftY - penWidth),
WXROUND(maxX + penWidth*2.0 + 4.0), WXROUND(maxY + penWidth*2.0 + 4.0));
}
// This is the default, rectangular implementation.
bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint& pt1, const wxRealPoint& pt2)
{
- switch (attachmentPoint)
+ int physicalAttachment = LogicalToPhysicalAttachment(attachmentPoint);
+ switch (physicalAttachment)
{
case 0:
case 2:
bool wxShape::MoveLineToNewAttachment(wxDC& dc, wxLineShape *to_move,
double x, double y)
{
- if (!GetAttachmentMode())
+ if (GetAttachmentMode() == ATTACHMENT_MODE_NONE)
return FALSE;
int newAttachment, oldAttachment;
{
// This is a temporary store of all the lines.
wxList linesStore;
-
+
wxNode *node = m_lines.First();
while (node)
{
// This is a temporary store of all the lines at this attachment
// point. We'll tick them off as we've processed them.
wxList linesAtThisAttachment;
-
+
wxNode *node = m_lines.First();
while (node)
{
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
- dc.SetLogicalFunction(wxXOR);
+ dc.SetLogicalFunction(OGLRBLF);
wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
dc.SetPen(dottedPen);
yy = y + DragOffsetY;
m_canvas->Snap(&xx, &yy);
// m_xpos = xx; m_ypos = yy;
- dc.SetLogicalFunction(wxXOR);
+ dc.SetLogicalFunction(OGLRBLF);
wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
dc.SetPen(dottedPen);
GetEventHandler()->OnDraw(dc);
GetEventHandler()->OnDrawContents(dc);
GetEventHandler()->OnDrawControlPoints(dc);
+ GetEventHandler()->OnDrawBranches(dc);
}
}
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
- dc.SetLogicalFunction(wxXOR);
+ dc.SetLogicalFunction(OGLRBLF);
Draw(dc);
dc.SetLogicalFunction(wxCOPY);
Draw(dc);
{
GetEventHandler()->OnErase(dc);
GetEventHandler()->OnEraseControlPoints(dc);
+ GetEventHandler()->OnDrawBranches(dc, TRUE);
}
void wxShape::EraseContents(wxDC& dc)
// The line ordering
int positionFrom, int positionTo)
{
+ if (positionFrom == -1)
+ {
+ if (!m_lines.Member(line))
+ m_lines.Append(line);
+ }
+ else
+ {
+ // Don't preserve old ordering if we have new ordering instructions
+ m_lines.DeleteObject(line);
+ if (positionFrom < m_lines.Number())
+ {
+ wxNode* node = m_lines.Nth(positionFrom);
+ m_lines.Insert(node, line);
+ }
+ else
+ m_lines.Append(line);
+ }
+
+ if (positionTo == -1)
+ {
+ if (!other->m_lines.Member(line))
+ other->m_lines.Append(line);
+ }
+ else
+ {
+ // Don't preserve old ordering if we have new ordering instructions
+ other->m_lines.DeleteObject(line);
+ if (positionTo < other->m_lines.Number())
+ {
+ wxNode* node = other->m_lines.Nth(positionTo);
+ other->m_lines.Insert(node, line);
+ }
+ else
+ other->m_lines.Append(line);
+ }
+#if 0
+ // Wrong: doesn't preserve ordering of shape already linked
m_lines.DeleteObject(line);
other->m_lines.DeleteObject(line);
else
other->m_lines.Append(line);
}
+#endif
line->SetFrom(this);
line->SetTo(other);
}
else if (brushColour != "WHITE")
clause->AddAttributeValueString("brush_colour", brushColour);
-
+
if (m_brush->GetStyle() != wxSOLID)
clause->AddAttributeValue("brush_style", (long)m_brush->GetStyle());
}
int n_lines = m_lines.Number();
if (n_lines > 0)
{
- wxExpr *list = new wxExpr(PrologList);
+ wxExpr *list = new wxExpr(wxExprList);
wxNode *node = m_lines.First();
while (node)
{
clause->AddAttributeValue("shadow_mode", (long)m_shadowMode);
if (m_centreResize != TRUE)
clause->AddAttributeValue("centre_resize", (long)0);
+ clause->AddAttributeValue("maintain_aspect_ratio", (long) m_maintainAspectRatio);
if (m_highlighted != FALSE)
clause->AddAttributeValue("hilite", (long)m_highlighted);
if (m_rotation != 0.0)
clause->AddAttributeValue("rotation", m_rotation);
+ if (!this->IsKindOf(CLASSINFO(wxLineShape)))
+ {
+ clause->AddAttributeValue("neck_length", (long) m_branchNeckLength);
+ clause->AddAttributeValue("stem_length", (long) m_branchStemLength);
+ clause->AddAttributeValue("branch_spacing", (long) m_branchSpacing);
+ clause->AddAttributeValue("branch_style", (long) m_branchStyle);
+ }
+
// Write user-defined attachment points, if any
if (m_attachmentPoints.Number() > 0)
{
- wxExpr *attachmentList = new wxExpr(PrologList);
+ wxExpr *attachmentList = new wxExpr(wxExprList);
wxNode *node = m_attachmentPoints.First();
while (node)
{
wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
- wxExpr *pointExpr = new wxExpr(PrologList);
+ wxExpr *pointExpr = new wxExpr(wxExprList);
pointExpr->Append(new wxExpr((long)point->m_id));
pointExpr->Append(new wxExpr(point->m_x));
pointExpr->Append(new wxExpr(point->m_y));
// Original text and region attributes:
// region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY
// formatMode fontSize fontFamily fontStyle fontWeight textColour)
- wxExpr *regionExpr = new wxExpr(PrologList);
- regionExpr->Append(new wxExpr(PrologString, (region->m_regionName ? region->m_regionName : "")));
- regionExpr->Append(new wxExpr(PrologString, (region->m_regionText ? region->m_regionText : "")));
+ wxExpr *regionExpr = new wxExpr(wxExprList);
+ regionExpr->Append(new wxExpr(wxExprString, region->m_regionName));
+ regionExpr->Append(new wxExpr(wxExprString, region->m_regionText));
regionExpr->Append(new wxExpr(region->m_x));
regionExpr->Append(new wxExpr(region->m_y));
regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetFamily() : wxDEFAULT)));
regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetStyle() : wxDEFAULT)));
regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetWeight() : wxNORMAL)));
- regionExpr->Append(new wxExpr(PrologString, region->m_textColour ? region->m_textColour : "BLACK"));
+ regionExpr->Append(new wxExpr(wxExprString, region->m_textColour));
// New members for pen colour/style
- regionExpr->Append(new wxExpr(PrologString, region->m_penColour ? region->m_penColour : "BLACK"));
+ regionExpr->Append(new wxExpr(wxExprString, region->m_penColour));
regionExpr->Append(new wxExpr((long)region->m_penStyle));
// Formatted text:
// text1 = ((x y string) (x y string) ...)
- wxExpr *textExpr = new wxExpr(PrologList);
+ wxExpr *textExpr = new wxExpr(wxExprList);
wxNode *textNode = region->m_formattedText.First();
while (textNode)
{
wxShapeTextLine *line = (wxShapeTextLine *)textNode->Data();
- wxExpr *list2 = new wxExpr(PrologList);
+ wxExpr *list2 = new wxExpr(wxExprList);
list2->Append(new wxExpr(line->GetX()));
list2->Append(new wxExpr(line->GetY()));
- list2->Append(new wxExpr(PrologString, line->GetText()));
+ list2->Append(new wxExpr(wxExprString, line->GetText()));
textExpr->Append(list2);
textNode = textNode->Next();
}
void wxShape::ReadAttributes(wxExpr *clause)
{
clause->GetAttributeValue("id", m_id);
- RegisterId(m_id);
+ wxRegisterId(m_id);
clause->GetAttributeValue("x", m_xpos);
clause->GetAttributeValue("y", m_ypos);
// Input text strings (FOR COMPATIBILITY WITH OLD FILES ONLY. SEE REGION CODE BELOW.)
ClearText();
wxExpr *strings = clause->AttributeValue("text");
- if (strings && strings->Type() == PrologList)
+ if (strings && strings->Type() == wxExprList)
{
m_formatted = TRUE; // Assume text is formatted unless we prove otherwise
wxExpr *node = strings->value.first;
// string_expr can either be a string, or a list of
// 3 elements: x, y, and string.
- if (string_expr->Type() == PrologString)
+ if (string_expr->Type() == wxExprString)
{
the_string = string_expr->StringValue();
m_formatted = FALSE;
}
- else if (string_expr->Type() == PrologList)
+ else if (string_expr->Type() == wxExprList)
{
wxExpr *first = string_expr->value.first;
- wxExpr *second = first ? first->next : NULL;
- wxExpr *third = second ? second->next : NULL;
+ wxExpr *second = first ? first->next : (wxExpr*) NULL;
+ wxExpr *third = second ? second->next : (wxExpr*) NULL;
if (first && second && third &&
- (first->Type() == PrologReal || first->Type() == PrologInteger) &&
- (second->Type() == PrologReal || second->Type() == PrologInteger) &&
- third->Type() == PrologString)
+ (first->Type() == wxExprReal || first->Type() == wxExprInteger) &&
+ (second->Type() == wxExprReal || second->Type() == wxExprInteger) &&
+ third->Type() == wxExprString)
{
- if (first->Type() == PrologReal)
+ if (first->Type() == wxExprReal)
the_x = first->RealValue();
else the_x = (double)first->IntegerValue();
- if (second->Type() == PrologReal)
+ if (second->Type() == wxExprReal)
the_y = second->RealValue();
else the_y = (double)second->IntegerValue();
int pen_width = 1;
int pen_style = wxSOLID;
int brush_style = wxSOLID;
- m_attachmentMode = FALSE;
+ m_attachmentMode = ATTACHMENT_MODE_NONE;
clause->GetAttributeValue("pen_colour", pen_string);
clause->GetAttributeValue("text_colour", m_textColourName);
int iVal = (int) m_attachmentMode;
clause->GetAttributeValue("use_attachments", iVal);
- m_attachmentMode = (iVal != 0);
+ m_attachmentMode = iVal;
clause->GetAttributeValue("sensitivity", m_sensitivity);
clause->GetAttributeValue("format_mode", m_formatMode);
clause->GetAttributeValue("shadow_mode", m_shadowMode);
+ iVal = m_branchNeckLength;
+ clause->GetAttributeValue("neck_length", iVal);
+ m_branchNeckLength = iVal;
+
+ iVal = m_branchStemLength;
+ clause->GetAttributeValue("stem_length", iVal);
+ m_branchStemLength = iVal;
+
+ iVal = m_branchSpacing;
+ clause->GetAttributeValue("branch_spacing", iVal);
+ m_branchSpacing = iVal;
+
+ clause->GetAttributeValue("branch_style", m_branchStyle);
+
iVal = (int) m_centreResize;
clause->GetAttributeValue("centre_resize", iVal);
m_centreResize = (iVal != 0);
+ iVal = (int) m_maintainAspectRatio;
+ clause->GetAttributeValue("maintain_aspect_ratio", iVal);
+ m_maintainAspectRatio = (iVal != 0);
+
iVal = (int) m_highlighted;
clause->GetAttributeValue("hilite", iVal);
m_highlighted = (iVal != 0);
if (brush_string == "")
brush_string = "WHITE";
- if (pen_string[0] == '#')
+ if (pen_string.GetChar(0) == '#')
{
wxColour col(oglHexToColour(pen_string.After('#')));
m_pen = wxThePenList->FindOrCreatePen(col, pen_width, pen_style);
if (!m_pen)
m_pen = wxBLACK_PEN;
- if (brush_string[0] == '#')
+ if (brush_string.GetChar(0) == '#')
{
wxColour col(oglHexToColour(brush_string.After('#')));
m_brush = wxTheBrushList->FindOrCreateBrush(col, brush_style);
m_formatted = TRUE; // Assume text is formatted unless we prove otherwise
- while (regionExpr = clause->AttributeValue(regionNameBuf))
+ while ((regionExpr = clause->AttributeValue(regionNameBuf)))
{
/*
* Get the region information
wxString penColour("");
int penStyle = wxSOLID;
- if (regionExpr->Type() == PrologList)
+ if (regionExpr->Type() == wxExprList)
{
wxExpr *nameExpr = regionExpr->Nth(0);
wxExpr *textExpr = regionExpr->Nth(1);
width = widthExpr->RealValue();
height = heightExpr->RealValue();
-
+
minWidth = minWidthExpr->RealValue();
minHeight = minHeightExpr->RealValue();
*
*/
textExpr = clause->AttributeValue(textNameBuf);
- if (textExpr && (textExpr->Type() == PrologList))
+ if (textExpr && (textExpr->Type() == wxExprList))
{
wxExpr *node = textExpr->value.first;
while (node)
// string_expr can either be a string, or a list of
// 3 elements: x, y, and string.
- if (string_expr->Type() == PrologString)
+ if (string_expr->Type() == wxExprString)
{
the_string = string_expr->StringValue();
m_formatted = FALSE;
}
- else if (string_expr->Type() == PrologList)
+ else if (string_expr->Type() == wxExprList)
{
wxExpr *first = string_expr->value.first;
- wxExpr *second = first ? first->next : NULL;
- wxExpr *third = second ? second->next : NULL;
+ wxExpr *second = first ? first->next : (wxExpr*) NULL;
+ wxExpr *third = second ? second->next : (wxExpr*) NULL;
if (first && second && third &&
- (first->Type() == PrologReal || first->Type() == PrologInteger) &&
- (second->Type() == PrologReal || second->Type() == PrologInteger) &&
- third->Type() == PrologString)
+ (first->Type() == wxExprReal || first->Type() == wxExprInteger) &&
+ (second->Type() == wxExprReal || second->Type() == wxExprInteger) &&
+ third->Type() == wxExprString)
{
- if (first->Type() == PrologReal)
+ if (first->Type() == wxExprReal)
the_x = first->RealValue();
else the_x = (double)first->IntegerValue();
- if (second->Type() == PrologReal)
+ if (second->Type() == wxExprReal)
the_y = second->RealValue();
else the_y = (double)second->IntegerValue();
copy.m_brush = m_brush;
copy.m_textColour = m_textColour;
copy.m_centreResize = m_centreResize;
+ copy.m_maintainAspectRatio = m_maintainAspectRatio;
copy.m_attachmentMode = m_attachmentMode;
copy.m_spaceAttachments = m_spaceAttachments;
copy.m_highlighted = m_highlighted;
copy.m_shadowOffsetY = m_shadowOffsetY;
copy.m_shadowBrush = m_shadowBrush;
+ copy.m_branchNeckLength = m_branchNeckLength;
+ copy.m_branchStemLength = m_branchStemLength;
+ copy.m_branchSpacing = m_branchSpacing;
+
// Copy text regions
copy.ClearRegions();
wxNode *node = m_regions.First();
double left = (double)(- (widthMin / 2.0));
double right = (double)(widthMin / 2.0 + (maxX - minX));
- wxControlPoint *control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, top,
+ wxControlPoint *control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, top,
CONTROL_POINT_DIAGONAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, top,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, top,
CONTROL_POINT_VERTICAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, top,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, top,
CONTROL_POINT_DIAGONAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, 0,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, 0,
CONTROL_POINT_HORIZONTAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, bottom,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, bottom,
CONTROL_POINT_DIAGONAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, bottom,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, bottom,
CONTROL_POINT_VERTICAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, bottom,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, bottom,
CONTROL_POINT_DIAGONAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
- control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, 0,
+ control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, 0,
CONTROL_POINT_HORIZONTAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
{
if (!m_drawHandles)
return;
-
- dc.SetBrush(wxBLACK_BRUSH);
- dc.SetPen(wxBLACK_PEN);
+
+ dc.SetBrush(* wxBLACK_BRUSH);
+ dc.SetPen(* wxBLACK_PEN);
wxNode *node = m_controlPoints.First();
while (node)
bool wxShape::AttachmentIsValid(int attachment) const
{
- if ((attachment >= 0) && (attachment < 4))
- return TRUE;
+ if (m_attachmentPoints.Number() == 0)
+ {
+ return ((attachment >= 0) && (attachment < 4)) ;
+ }
wxNode *node = m_attachmentPoints.First();
while (node)
return FALSE;
}
-bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y,
+bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y,
int nth, int no_arcs, wxLineShape *line)
{
- if (!m_attachmentMode)
- {
- *x = m_xpos; *y = m_ypos;
- return TRUE;
- }
- else
- {
- wxNode *node = m_attachmentPoints.First();
- while (node)
+ if (m_attachmentMode == ATTACHMENT_MODE_NONE)
{
- wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
- if (point->m_id == attachment)
- {
- *x = (double)(m_xpos + point->m_x);
- *y = (double)(m_ypos + point->m_y);
+ *x = m_xpos; *y = m_ypos;
return TRUE;
- }
- node = node->Next();
}
- *x = m_xpos; *y = m_ypos;
+ else if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING)
+ {
+ wxRealPoint pt, stemPt;
+ GetBranchingAttachmentPoint(attachment, nth, pt, stemPt);
+ *x = pt.x;
+ *y = pt.y;
+ return TRUE;
+ }
+ else if (m_attachmentMode == ATTACHMENT_MODE_EDGE)
+ {
+ if (m_attachmentPoints.Number() > 0)
+ {
+ wxNode *node = m_attachmentPoints.First();
+ while (node)
+ {
+ wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
+ if (point->m_id == attachment)
+ {
+ *x = (double)(m_xpos + point->m_x);
+ *y = (double)(m_ypos + point->m_y);
+ return TRUE;
+ }
+ node = node->Next();
+ }
+ *x = m_xpos; *y = m_ypos;
+ return FALSE;
+ }
+ else
+ {
+ // Assume is rectangular
+ double w, h;
+ GetBoundingBoxMax(&w, &h);
+ double top = (double)(m_ypos + h/2.0);
+ double bottom = (double)(m_ypos - h/2.0);
+ double left = (double)(m_xpos - w/2.0);
+ double right = (double)(m_xpos + w/2.0);
+
+ bool isEnd = (line && line->IsEnd(this));
+
+ int physicalAttachment = LogicalToPhysicalAttachment(attachment);
+
+ // Simplified code
+ switch (physicalAttachment)
+ {
+ case 0:
+ {
+ wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(right, bottom),
+ nth, no_arcs, line);
+
+ *x = pt.x; *y = pt.y;
+ break;
+ }
+ case 1:
+ {
+ wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(right, bottom), wxRealPoint(right, top),
+ nth, no_arcs, line);
+
+ *x = pt.x; *y = pt.y;
+ break;
+ }
+ case 2:
+ {
+ wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, top), wxRealPoint(right, top),
+ nth, no_arcs, line);
+
+ *x = pt.x; *y = pt.y;
+ break;
+ }
+ case 3:
+ {
+ wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(left, top),
+ nth, no_arcs, line);
+
+ *x = pt.x; *y = pt.y;
+ break;
+ }
+ default:
+ {
+ return FALSE;
+ break;
+ }
+ }
+ return TRUE;
+ }
+ }
return FALSE;
- }
}
void wxShape::GetBoundingBoxMax(double *w, double *h)
return 0;
}
+//
+// |________|
+// | <- root
+// | <- neck
+// shoulder1 ->---------<- shoulder2
+// | | | | |
+// <- branching attachment point N-1
+
+// This function gets information about where branching connections go.
+// Returns FALSE if there are no lines at this attachment.
+bool wxShape::GetBranchingAttachmentInfo(int attachment, wxRealPoint& root, wxRealPoint& neck,
+ wxRealPoint& shoulder1, wxRealPoint& shoulder2)
+{
+ int physicalAttachment = LogicalToPhysicalAttachment(attachment);
+
+ // Number of lines at this attachment.
+ int lineCount = GetAttachmentLineCount(attachment);
+
+ if (lineCount == 0)
+ return FALSE;
+
+ int totalBranchLength = m_branchSpacing * (lineCount - 1);
+
+ root = GetBranchingAttachmentRoot(attachment);
+
+ // Assume that we have attachment points 0 to 3: top, right, bottom, left.
+ switch (physicalAttachment)
+ {
+ case 0:
+ {
+ neck.x = GetX();
+ neck.y = root.y - m_branchNeckLength;
+
+ shoulder1.x = root.x - (totalBranchLength/2.0) ;
+ shoulder2.x = root.x + (totalBranchLength/2.0) ;
+
+ shoulder1.y = neck.y;
+ shoulder2.y = neck.y;
+ break;
+ }
+ case 1:
+ {
+ neck.x = root.x + m_branchNeckLength;
+ neck.y = root.y;
+
+ shoulder1.x = neck.x ;
+ shoulder2.x = neck.x ;
+
+ shoulder1.y = neck.y - (totalBranchLength/2.0) ;
+ shoulder2.y = neck.y + (totalBranchLength/2.0) ;
+ break;
+ }
+ case 2:
+ {
+ neck.x = GetX();
+ neck.y = root.y + m_branchNeckLength;
+
+ shoulder1.x = root.x - (totalBranchLength/2.0) ;
+ shoulder2.x = root.x + (totalBranchLength/2.0) ;
+
+ shoulder1.y = neck.y;
+ shoulder2.y = neck.y;
+ break;
+ }
+ case 3:
+ {
+ neck.x = root.x - m_branchNeckLength;
+ neck.y = root.y ;
+
+ shoulder1.x = neck.x ;
+ shoulder2.x = neck.x ;
+
+ shoulder1.y = neck.y - (totalBranchLength/2.0) ;
+ shoulder2.y = neck.y + (totalBranchLength/2.0) ;
+ break;
+ }
+ default:
+ {
+ wxFAIL_MSG( "Unrecognised attachment point in GetBranchingAttachmentInfo." );
+ break;
+ }
+ }
+ return TRUE;
+}
+
+// n is the number of the adjoining line, from 0 to N-1 where N is the number of lines
+// at this attachment point.
+// Get the attachment point where the arc joins the stem, and also the point where the
+// the stem meets the shoulder.
+bool wxShape::GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint& pt, wxRealPoint& stemPt)
+{
+ int physicalAttachment = LogicalToPhysicalAttachment(attachment);
+
+ wxRealPoint root, neck, shoulder1, shoulder2;
+ GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2);
+
+ // Assume that we have attachment points 0 to 3: top, right, bottom, left.
+ switch (physicalAttachment)
+ {
+ case 0:
+ {
+ pt.y = neck.y - m_branchStemLength;
+ pt.x = shoulder1.x + n*m_branchSpacing;
+
+ stemPt.x = pt.x;
+ stemPt.y = neck.y;
+ break;
+ }
+ case 2:
+ {
+ pt.y = neck.y + m_branchStemLength;
+ pt.x = shoulder1.x + n*m_branchSpacing;
+
+ stemPt.x = pt.x;
+ stemPt.y = neck.y;
+ break;
+ }
+ case 1:
+ {
+ pt.x = neck.x + m_branchStemLength;
+ pt.y = shoulder1.y + n*m_branchSpacing;
+
+ stemPt.x = neck.x;
+ stemPt.y = pt.y;
+ break;
+ }
+ case 3:
+ {
+ pt.x = neck.x - m_branchStemLength;
+ pt.y = shoulder1.y + n*m_branchSpacing;
+
+ stemPt.x = neck.x;
+ stemPt.y = pt.y;
+ break;
+ }
+ default:
+ {
+ wxFAIL_MSG( "Unrecognised attachment point in GetBranchingAttachmentPoint." );
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+// Get the number of lines at this attachment position.
+int wxShape::GetAttachmentLineCount(int attachment) const
+{
+ int count = 0;
+ wxNode* node = m_lines.First();
+ while (node)
+ {
+ wxLineShape* lineShape = (wxLineShape*) node->Data();
+ if ((lineShape->GetFrom() == this) && (lineShape->GetAttachmentFrom() == attachment))
+ count ++;
+ else if ((lineShape->GetTo() == this) && (lineShape->GetAttachmentTo() == attachment))
+ count ++;
+
+ node = node->Next();
+ }
+ return count;
+}
+
+// This function gets the root point at the given attachment.
+wxRealPoint wxShape::GetBranchingAttachmentRoot(int attachment)
+{
+ int physicalAttachment = LogicalToPhysicalAttachment(attachment);
+
+ wxRealPoint root;
+
+ double width, height;
+ GetBoundingBoxMax(& width, & height);
+
+ // Assume that we have attachment points 0 to 3: top, right, bottom, left.
+ switch (physicalAttachment)
+ {
+ case 0:
+ {
+ root.x = GetX() ;
+ root.y = GetY() - height/2.0;
+ break;
+ }
+ case 1:
+ {
+ root.x = GetX() + width/2.0;
+ root.y = GetY() ;
+ break;
+ }
+ case 2:
+ {
+ root.x = GetX() ;
+ root.y = GetY() + height/2.0;
+ break;
+ }
+ case 3:
+ {
+ root.x = GetX() - width/2.0;
+ root.y = GetY() ;
+ break;
+ }
+ default:
+ {
+ wxFAIL_MSG( "Unrecognised attachment point in GetBranchingAttachmentRoot." );
+ break;
+ }
+ }
+ return root;
+}
+
+// Draw or erase the branches (not the actual arcs though)
+void wxShape::OnDrawBranches(wxDC& dc, int attachment, bool erase)
+{
+ int count = GetAttachmentLineCount(attachment);
+ if (count == 0)
+ return;
+
+ wxRealPoint root, neck, shoulder1, shoulder2;
+ GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2);
+
+ if (erase)
+ {
+ dc.SetPen(*wxWHITE_PEN);
+ dc.SetBrush(*wxWHITE_BRUSH);
+ }
+ else
+ {
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxBLACK_BRUSH);
+ }
+
+ // Draw neck
+ dc.DrawLine((long) root.x, (long) root.y, (long) neck.x, (long) neck.y);
+
+ if (count > 1)
+ {
+ // Draw shoulder-to-shoulder line
+ dc.DrawLine((long) shoulder1.x, (long) shoulder1.y, (long) shoulder2.x, (long) shoulder2.y);
+ }
+ // Draw all the little branches
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ wxRealPoint pt, stemPt;
+ GetBranchingAttachmentPoint(attachment, i, pt, stemPt);
+ dc.DrawLine((long) stemPt.x, (long) stemPt.y, (long) pt.x, (long) pt.y);
+
+ if ((GetBranchStyle() & BRANCHING_ATTACHMENT_BLOB) && (count > 1))
+ {
+ long blobSize=6;
+// dc.DrawEllipse((long) (stemPt.x + 0.5 - (blobSize/2.0)), (long) (stemPt.y + 0.5 - (blobSize/2.0)), blobSize, blobSize);
+ dc.DrawEllipse((long) (stemPt.x - (blobSize/2.0)), (long) (stemPt.y - (blobSize/2.0)), blobSize, blobSize);
+ }
+ }
+}
+
+// Draw or erase the branches (not the actual arcs though)
+void wxShape::OnDrawBranches(wxDC& dc, bool erase)
+{
+ if (m_attachmentMode != ATTACHMENT_MODE_BRANCHING)
+ return;
+
+ int count = GetNumberOfAttachments();
+ int i;
+ for (i = 0; i < count; i++)
+ OnDrawBranches(dc, i, erase);
+}
+
+// Only get the attachment position at the _edge_ of the shape, ignoring
+// branching mode. This is used e.g. to indicate the edge of interest, not the point
+// on the attachment branch.
+bool wxShape::GetAttachmentPositionEdge(int attachment, double *x, double *y,
+ int nth, int no_arcs, wxLineShape *line)
+{
+ int oldMode = m_attachmentMode;
+
+ // Calculate as if to edge, not branch
+ if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING)
+ m_attachmentMode = ATTACHMENT_MODE_EDGE;
+ bool success = GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
+ m_attachmentMode = oldMode;
+
+ return success;
+}
+
+// Rotate the standard attachment point from physical (0 is always North)
+// to logical (0 -> 1 if rotated by 90 degrees)
+int wxShape::PhysicalToLogicalAttachment(int physicalAttachment) const
+{
+ const double pi = 3.1415926535897932384626433832795 ;
+ int i;
+ if (oglRoughlyEqual(GetRotation(), 0.0))
+ {
+ i = physicalAttachment;
+ }
+ else if (oglRoughlyEqual(GetRotation(), (pi/2.0)))
+ {
+ i = physicalAttachment - 1;
+ }
+ else if (oglRoughlyEqual(GetRotation(), pi))
+ {
+ i = physicalAttachment - 2;
+ }
+ else if (oglRoughlyEqual(GetRotation(), (3.0*pi/2.0)))
+ {
+ i = physicalAttachment - 3;
+ }
+ else
+ // Can't handle -- assume the same.
+ return physicalAttachment;
+
+ if (i < 0)
+ i += 4;
+
+ return i;
+}
+
+// Rotate the standard attachment point from logical
+// to physical (0 is always North)
+int wxShape::LogicalToPhysicalAttachment(int logicalAttachment) const
+{
+ const double pi = 3.1415926535897932384626433832795 ;
+ int i;
+ if (oglRoughlyEqual(GetRotation(), 0.0))
+ {
+ i = logicalAttachment;
+ }
+ else if (oglRoughlyEqual(GetRotation(), (pi/2.0)))
+ {
+ i = logicalAttachment + 1;
+ }
+ else if (oglRoughlyEqual(GetRotation(), pi))
+ {
+ i = logicalAttachment + 2;
+ }
+ else if (oglRoughlyEqual(GetRotation(), (3.0*pi/2.0)))
+ {
+ i = logicalAttachment + 3;
+ }
+ else
+ // Can't handle -- assume the same.
+ return logicalAttachment;
+
+ if (i > 3)
+ i -= 4;
+
+ return i;
+}
+
+void wxShape::Rotate(double WXUNUSED(x), double WXUNUSED(y), double theta)
+{
+ const double pi = 3.1415926535897932384626433832795 ;
+ m_rotation = theta;
+ if (m_rotation < 0.0)
+ {
+ m_rotation += 2*pi;
+ }
+ else if (m_rotation > 2*pi)
+ {
+ m_rotation -= 2*pi;
+ }
+}
+