Power System Platform  2026w23a-beta
Loading...
Searching...
No Matches
Gain.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 "Gain.h"
19#include "../../forms/GainForm.h"
20
21Gain::Gain(int id) : ControlElement(id)
22{
23 m_triPts.resize(3);
24 SetValue(m_value);
25 Node* nodeIn = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NodeType::NODE_IN, m_borderSize);
26 nodeIn->StartMove(m_position);
27 Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NodeType::NODE_OUT, m_borderSize);
28 nodeOut->SetAngle(180.0);
29 nodeOut->StartMove(m_position);
30 m_nodeList.push_back(nodeIn);
31 m_nodeList.push_back(nodeOut);
32}
33
34Gain::~Gain()
35{
36 //if(m_glText) delete m_glText;
37 if (m_gcText) delete m_gcText;
38 for (auto& node : m_nodeList) if (node) delete node;
39 m_nodeList.clear();
40}
41
42void Gain::DrawDC(GUIColour* guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
43{
44 if (m_selected) {
45 gc->SetPen(*wxTRANSPARENT_PEN);
46 gc->SetBrush(wxBrush(guiColour->selection));
47 double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
48 std::vector<wxPoint2DDouble> m_triSelectedPts;
49 if (m_angle == 0.0) {
50 m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize / 2, borderSize / 1.5));
51 m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(borderSize / 2, -borderSize / 1.5));
52 m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(-borderSize, 0));
53 }
54 else if (m_angle == 90.0) {
55 m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize / 1.5, borderSize / 2));
56 m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 1.5, borderSize / 2));
57 m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(0, -borderSize));
58 }
59 else if (m_angle == 180.0) {
60 m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize, 0));
61 m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 2, borderSize / 1.5));
62 m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(-borderSize / 2, -borderSize / 1.5));
63 }
64 else if (m_angle == 270.0) {
65 m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(0, borderSize));
66 m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 1.5, -borderSize / 2));
67 m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(borderSize / 1.5, -borderSize / 2));
68 }
69 DrawDCTriangle(m_triSelectedPts, gc);
70 }
71
72 gc->SetPen(wxPen(guiColour->enabled, 1));
73 gc->SetBrush(guiColour->background);
74 DrawDCTriangle(m_triPts, gc);
75
76 // Plot number.
77 if (m_angle == 0.0)
78 m_gcText->Draw(m_position + wxPoint2DDouble(-m_width / 2 + 2 + m_borderSize, -m_gcText->GetHeight() / 2), gc, 0, guiColour->text);
79 else if (m_angle == 90.0)
80 m_gcText->Draw(m_position + wxPoint2DDouble(-m_gcText->GetWidth() / 2, -m_height / 2 + 2 + m_borderSize), gc, 0, guiColour->text);
81 else if (m_angle == 180.0)
82 m_gcText->Draw(m_position + wxPoint2DDouble(m_width / 2 - m_gcText->GetWidth() - 2 - m_borderSize, -m_gcText->GetHeight() / 2), gc, 0, guiColour->text);
83 else if (m_angle == 270.0)
84 m_gcText->Draw(m_position + wxPoint2DDouble(-m_gcText->GetWidth() / 2, m_height / 2 - m_gcText->GetHeight() - 2 - m_borderSize), gc, 0, guiColour->text);
85
86 gc->SetPen(*wxTRANSPARENT_PEN);
87 gc->SetBrush(guiColour->enabled);
88 DrawDCNodes(gc);
89}
90
91bool Gain::ShowForm(wxWindow* parent, Element* element, wxWindow* workspace)
92{
93 GainForm form(parent, this);
94 form.CenterOnParent();
95 if (form.ShowModal() == wxID_OK) {
96 return true;
97 }
98 return false;
99}
100
101void Gain::Rotate(bool clockwise)
102{
103 if (clockwise)
104 m_angle += 90.0;
105 else
106 m_angle -= 90.0;
107 if (m_angle >= 360.0)
108 m_angle = 0.0;
109 else if (m_angle < 0)
110 m_angle = 270.0;
111
112 UpdatePoints();
113
114 for (auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
115 Node* node = *it;
116 node->Rotate(clockwise);
117 }
118}
119
120void Gain::SetValue(double value)
121{
122 m_value = value;
123 wxString text = "";
124 if (std::abs(m_value) > 1e3 || std::abs(m_value) < 1e-3)
125 text = wxString::Format("%g", m_value);
126 else
127 text = StringFromDouble(m_value);
128
129 if (m_gcText)
130 m_gcText->SetText(text);
131 else
132 m_gcText = new GCText(text);
133
134 m_width = m_gcText->GetWidth() + 18 + 2 * m_borderSize;
135 m_height = m_gcText->GetHeight() + 18 + 2 * m_borderSize;
136
137 if (m_width > m_height)
138 m_height = m_width;
139 else
140 m_width = m_height;
141
142 SetPosition(m_position); // Update rectangle.
143
144 UpdatePoints();
145}
146
147void Gain::UpdatePoints()
148{
149 if (m_nodeList.size() != 0) {
150 if (m_angle == 0.0) {
151 m_triPts[0] = m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize);
152 m_triPts[1] = m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize);
153 m_triPts[2] = m_position + wxPoint2DDouble(m_width / 2 - m_borderSize, 0);
154 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
155 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2 - 2, 0));
156 }
157 else if (m_angle == 90.0) {
158 m_triPts[0] = m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize);
159 m_triPts[1] = m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize);
160 m_triPts[2] = m_position + wxPoint2DDouble(0, m_height / 2 - m_borderSize);
161 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
162 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2 - 2));
163 }
164 else if (m_angle == 180.0) {
165 m_triPts[0] = m_position + wxPoint2DDouble(-m_width / 2 + m_borderSize, 0);
166 m_triPts[1] = m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize);
167 m_triPts[2] = m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize);
168 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
169 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2 + 2, 0));
170 }
171 else if (m_angle == 270.0) {
172 m_triPts[0] = m_position + wxPoint2DDouble(0, -m_height / 2 + m_borderSize);
173 m_triPts[1] = m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize);
174 m_triPts[2] = m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize);
175 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
176 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2 + 2));
177 }
178 }
179}
180
181void Gain::Move(wxPoint2DDouble position)
182{
183 SetPosition(m_movePos + position - m_moveStartPt);
184 UpdatePoints();
185}
186
187void Gain::SetFont(wxFont& font)
188{
189 if (m_gcText) m_gcText->SetFont(font);
190 UpdateText();
191}
192
193bool Gain::Solve(double* input, double timeStep)
194{
195 if (!input) {
196 m_output = 0.0;
197 return true;
198 }
199 m_output = input[0] * m_value;
200 return true;
201}
202
204{
205 Gain* copy = new Gain(*this);
206 copy->m_gcText = m_gcText ? m_gcText->GetCopy() : nullptr;
207 return copy;
208}
209
211{
212 SetValue(m_value);
213 //if (!m_glText->IsTextureOK()) return false;
214 return true;
215}
216
217rapidxml::xml_node<>* Gain::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
218{
219 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Gain");
220 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
221
222 SaveCADProperties(doc, elementNode);
223 SaveControlNodes(doc, elementNode);
224
225 // Element properties
226 auto value = XMLParser::AppendNode(doc, elementNode, "Value");
227 XMLParser::SetNodeValue(doc, value, m_value);
228
229 return elementNode;
230}
231
232bool Gain::OpenElement(rapidxml::xml_node<>* elementNode)
233{
234 if (!OpenCADProperties(elementNode)) return false;
235 if (!OpenControlNodes(elementNode)) return false;
236
237 // Element properties
238 double value = XMLParser::GetNodeValueDouble(elementNode, "Value");
239 SetValue(value);
240 return true;
241}
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:114
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
Definition Element.cpp:33
virtual void DrawDCTriangle(std::vector< wxPoint2DDouble > points, wxGraphicsContext *gc) const
Draw rectangle.
Definition Element.cpp:209
static wxString StringFromDouble(double value, int minDecimal=1, int maxDecimals=13)
Convert a double value to string.
Definition Element.cpp:466
Class to draw text on Graphics Context using wxWidgets.
Definition GCText.h:32
virtual GCText * GetCopy()
Get a deep text copy.
Definition GCText.cpp:99
virtual void Draw(wxPoint2DDouble position, wxGraphicsContext *gc, double angle=0.0, wxColour colour= *wxBLACK) const
Draw the text in wxGraphicsContext.
Definition GCText.cpp:35
virtual void SetText(wxString text)
Set correctly a new text string.
Definition GCText.cpp:68
Form to edit the gain control data.
Definition GainForm.h:32
Provide an output multiplying the input by a constant.
Definition Gain.h:37
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
Definition Gain.cpp:91
virtual Element * GetCopy()
Get a the element copy.
Definition Gain.cpp:203
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition Gain.cpp:210
virtual bool Solve(double *input, double timeStep)
Multiply the input by a constant.
Definition Gain.cpp:193
virtual void DrawDC(GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
Definition Gain.cpp:42
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition Gain.cpp:181
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition Gain.cpp:101
Node of a control element. This class manages the user interaction with the connection and control el...