Power System Platform  2026w10a-beta
Loading...
Searching...
No Matches
ConnectionLine.cpp
1/*
2 * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "ConnectionLine.h"
19#include <wx/pen.h>
20#include <wx/brush.h>
21
22ConnectionLine::ConnectionLine() : ControlElement(-1) {}
23ConnectionLine::ConnectionLine(Node* firstNode, int id) : ControlElement(id)
24{
25 wxPoint2DDouble pt = firstNode->GetPosition();
26 m_tmpSndPt = pt;
27 for (int i = 0; i < 6; i++) { m_pointList.push_back(pt); }
28 m_nodeList.push_back(firstNode);
29 firstNode->SetConnected();
30}
31
32ConnectionLine::~ConnectionLine()
33{
34}
35
36//void ConnectionLine::Draw(wxPoint2DDouble translation, double scale) const
37//{
38// // Line selected (Layer 1).
39// if (m_selected) {
40// glLineWidth(1.5 + m_borderSize * 2.0);
41// glColor4dv(m_selectionColour.GetRGBA());
42// DrawLine(m_pointList);
43// }
44//
45// // Draw line (Layer 2)
46// glLineWidth(1.5);
47// glColor4d(0.0, 0.0, 0.0, 1.0);
48// DrawLine(m_pointList);
49//
50// if (m_type == ConnectionLineType::ELEMENT_LINE) {
51// glColor4d(0.0, 0.0, 0.0, 1.0);
52// DrawCircle(m_pointList[5], 3, 10, GL_POLYGON);
53// }
54//}
55
56void ConnectionLine::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
57{
58 gc->SetBrush(*wxTRANSPARENT_BRUSH);
59 if (m_selected) {
60 gc->SetPen(wxPen(m_selectionColour, 1.5 + m_borderSize * 2.0));
61 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
62 }
63
64 // Draw line (Layer 2)
65 gc->SetPen(wxPen(wxColour(0, 0, 0, 255), 2.0));
66 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
67
68 if (m_type == ConnectionLineType::ELEMENT_LINE) {
69 gc->SetPen(*wxTRANSPARENT_PEN);
70 gc->SetBrush(wxBrush(wxColour(0, 0, 0, 255)));
71 DrawDCCircle(m_pointList[5], 3, 10, gc);
72 }
73}
74
75bool ConnectionLine::Contains(wxPoint2DDouble position) const
76{
77 if (PointToLineDistance(position) < 5.0) { return true; }
78 return false;
79}
80
81bool ConnectionLine::Intersects(wxRect2DDouble rect) const
82{
83 for (auto it = m_pointList.begin(); it != m_pointList.end(); ++it) {
84 if (rect.Contains(*it)) return true;
85 }
86 return false;
87}
88
89void ConnectionLine::UpdatePoints()
90{
91 if (m_type == ConnectionLineType::ELEMENT_ELEMENT) {
92 bool hasOneNode = true;
93 wxPoint2DDouble pt1 = m_nodeList[0]->GetPosition();
94 wxPoint2DDouble pt2;
95 if (m_nodeList.size() == 1)
96 pt2 = m_tmpSndPt;
97 else {
98 pt2 = m_nodeList[1]->GetPosition();
99 hasOneNode = false;
100 }
101 wxPoint2DDouble midPt = (pt1 + pt2) / 2.0 + wxPoint2DDouble(0.0, m_lineOffset);
102
103 m_pointList[0] = pt1;
104 if (m_nodeList[0]->GetAngle() == 0.0)
105 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(-10, 0);
106 else if (m_nodeList[0]->GetAngle() == 90.0)
107 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(0, -10);
108 else if (m_nodeList[0]->GetAngle() == 180.0)
109 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(10, 0);
110 else if (m_nodeList[0]->GetAngle() == 270.0)
111 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(0, 10);
112
113 m_pointList[2] = m_pointList[1] + wxPoint2DDouble(0.0, midPt.m_y - m_pointList[1].m_y);
114
115 m_pointList[5] = pt2;
116 if (hasOneNode)
117 m_pointList[4] = pt2;
118 else {
119 if (m_nodeList[1]->GetAngle() == 0.0)
120 m_pointList[4] = m_pointList[5] + wxPoint2DDouble(-10, 0);
121 else if (m_nodeList[1]->GetAngle() == 90.0)
122 m_pointList[4] = m_pointList[5] + wxPoint2DDouble(0, -10);
123 else if (m_nodeList[1]->GetAngle() == 180.0)
124 m_pointList[4] = m_pointList[5] + wxPoint2DDouble(10, 0);
125 else if (m_nodeList[1]->GetAngle() == 270.0)
126 m_pointList[4] = m_pointList[5] + wxPoint2DDouble(0, 10);
127 }
128
129 m_pointList[3] = m_pointList[4] + wxPoint2DDouble(0.0, midPt.m_y - m_pointList[4].m_y);
130 }
131 else if (m_type == ConnectionLineType::ELEMENT_LINE) {
132 wxPoint2DDouble pt1 = m_nodeList[0]->GetPosition();
133 wxPoint2DDouble pt2 = m_parentLine->GetMidPoint();
134 wxPoint2DDouble midPt = (pt1 + pt2) / 2.0 + wxPoint2DDouble(0.0, m_lineOffset);
135
136 m_pointList[0] = pt1;
137 if (m_nodeList[0]->GetAngle() == 0.0)
138 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(-10, 0);
139 else if (m_nodeList[0]->GetAngle() == 90.0)
140 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(0, -10);
141 else if (m_nodeList[0]->GetAngle() == 180.0)
142 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(10, 0);
143 else if (m_nodeList[0]->GetAngle() == 270.0)
144 m_pointList[1] = m_pointList[0] + wxPoint2DDouble(0, 10);
145
146 m_pointList[2] = m_pointList[1] + wxPoint2DDouble(0.0, midPt.m_y - m_pointList[1].m_y);
147
148 m_pointList[5] = pt2;
149 if (m_pointList[2].m_y > pt2.m_y) {
150 m_pointList[4] = m_pointList[5] + wxPoint2DDouble(0, 10);
151 }
152 else {
153 m_pointList[4] = m_pointList[5] + wxPoint2DDouble(0, -10);
154 }
155
156 m_pointList[3] = m_pointList[4] + wxPoint2DDouble(0.0, midPt.m_y - m_pointList[4].m_y);
157 }
158 for (auto it = m_childList.begin(), itEnd = m_childList.end(); it != itEnd; ++it) {
159 ConnectionLine* child = static_cast<ConnectionLine*>(*it);
160 child->UpdatePoints();
161 }
162}
163
164bool ConnectionLine::AppendNode(Node* node, ControlElement* parent)
165{
166 if (m_nodeList.size() != 1) return false;
167 if (m_nodeList[0] == node) return false;
168 if (m_nodeList[0]->GetNodeType() == node->GetNodeType()) return false;
169 auto nodeList = parent->GetNodeList();
170 for (auto it = nodeList.begin(), itEnd = nodeList.end(); it != itEnd; ++it) {
171 Node* parentNode = *it;
172 if (parentNode == m_nodeList[0]) return false;
173 }
174
175 m_nodeList.push_back(node);
176 node->SetConnected();
177 return true;
178}
179
180void ConnectionLine::Move(wxPoint2DDouble position)
181{
182 m_lineOffset = m_moveStartOffset + position.m_y - m_moveStartPtY;
183 UpdatePoints();
184}
185
186void ConnectionLine::StartMove(wxPoint2DDouble position)
187{
188 m_moveStartPtY = position.m_y;
189 m_moveStartOffset = m_lineOffset;
190}
191
192wxPoint2DDouble ConnectionLine::GetMidPoint() const { return ((m_pointList[2] + m_pointList[3]) / 2.0); }
193bool ConnectionLine::SetParentLine(ConnectionLine* parent)
194{
195 if (m_nodeList[0]->GetNodeType() != Node::NodeType::NODE_IN) return false;
196 if (!parent) return false;
197
198 m_type = ConnectionLineType::ELEMENT_LINE;
199 m_parentLine = parent;
200 return true;
201}
202
203std::vector<ConnectionLine*> ConnectionLine::GetLineChildList() const
204{
205 std::vector<ConnectionLine*> childList;
206 for (auto it = m_childList.begin(), itEnd = m_childList.end(); it != itEnd; ++it) {
207 ConnectionLine* child = static_cast<ConnectionLine*>(*it);
208 childList.push_back(child);
209 }
210 return childList;
211}
212
214{
215 for (auto it = m_parentList.begin(); it != m_parentList.end(); ++it) {
216 Element* element = *it;
217 if (element == parent) m_parentList.erase(it--);
218 }
219}
220
222{
223 ConnectionLine* copy = new ConnectionLine();
224 *copy = *this;
225 return copy;
226}
227
228bool ConnectionLine::Initialize()
229{
230 m_solved = false;
231 m_output = 0.0;
232 m_value = 0.0;
233 return true;
234}
Connection between two control elements or other connection line and an element.
Element * GetCopy()
Get a the element copy.
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
virtual void RemoveParent(Element *parent)
Remove a parent.
virtual void Move(wxPoint2DDouble position)
Move the element other position.
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:112
virtual double PointToLineDistance(wxPoint2DDouble point, int *segmentNumber=nullptr) const
Calculate the distance between a line (formed by point list) and a point.
Definition Element.cpp:601
double GetAngle() const
Get the element angle.
Definition Element.h:211
virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
Draw a circle using device context.
Definition Element.cpp:177
Node of a control element. This class manages the user interaction with the connection and control el...