Power System Platform  2026w23a-beta
Loading...
Searching...
No Matches
ControlEditor Class Reference
Inheritance diagram for ControlEditor:
Collaboration diagram for ControlEditor:

Public Types

enum class  ControlEditorMode : int {
  MODE_EDIT = 0 , MODE_MOVE_ELEMENT , MODE_MOVE_LINE , MODE_DRAG ,
  MODE_DRAG_INSERT , MODE_INSERT , MODE_INSERT_LINE , MODE_SELECTION_RECT ,
  MODE_PASTE , MODE_DRAG_PASTE
}
 

Public Member Functions

 ControlEditor (wxWindow *parent, PropertiesData *properties)
 
 ControlEditor (wxWindow *parent, PropertiesData *properties, int ioflags=IOControl::IN_TERMINAL_VOLTAGE|IOControl::IN_VELOCITY|IOControl::OUT_FIELD_VOLTAGE|IOControl::OUT_MEC_POWER)
 
virtual void AddElement (ControlElementButtonID id)
 
virtual void Redraw ()
 
virtual void SetJustOpened (bool justOpened)
 
virtual void RotateSelectedElements (bool clockwise)
 
virtual void DeleteSelectedElements ()
 
virtual void CheckConnections ()
 
virtual std::vector< std::shared_ptr< ConnectionLine > > GetConnectionLineList () const
 
virtual std::vector< std::shared_ptr< ControlElement > > GetControlElementList () const
 
virtual void SetElementsList (const std::vector< std::shared_ptr< ControlElement > > &elementList)
 
virtual void SetConnectionsList (const std::vector< std::shared_ptr< ConnectionLine > > &connectionList)
 
virtual void SetControlContainer (ControlElementContainer *ctrlContainer)
 
virtual ControlElementContainerGetControlContainer ()
 
virtual void SetPlotLib (int plotLib)
 
virtual void SetManager (ControlEditorManager *manager)
 
virtual std::vector< Element * > GetElementList () const
 
virtual void Fit ()
 
virtual void OnClose (wxCloseEvent &event)
 
virtual void OnTestClick (wxCommandEvent &event)
 
virtual void OnButtonOKClick (wxCommandEvent &event)
 
virtual void OnImportClick (wxCommandEvent &event)
 
virtual void OnExportClick (wxCommandEvent &event)
 
virtual void OnKeyDown (wxKeyEvent &event)
 
virtual void OnIdle (wxIdleEvent &event)
 
virtual void OnScroll (wxMouseEvent &event)
 
virtual void OnDoubleClick (wxMouseEvent &event)
 
virtual void OnLeftClickDown (wxMouseEvent &event)
 
virtual void OnLeftClickUp (wxMouseEvent &event)
 
virtual void OnMiddleDown (wxMouseEvent &event)
 
virtual void OnMiddleUp (wxMouseEvent &event)
 
virtual void OnMouseMotion (wxMouseEvent &event)
 
virtual void OnPaint (wxPaintEvent &event)
 
virtual void LeftClickDown (wxMouseEvent &event)
 
virtual void BuildColourList ()
 
virtual wxColour GetNextColour ()
 
void BuildControlElementPanel ()
 

Protected Member Functions

virtual void OnMiddleDoubleClick (wxMouseEvent &event)
 
virtual void OnFitClick (wxCommandEvent &event)
 
virtual void OnCopyClick (wxCommandEvent &event)
 
virtual void OnDeleteClick (wxCommandEvent &event)
 
virtual void OnDragClick (wxCommandEvent &event)
 
virtual void OnMoveClick (wxCommandEvent &event)
 
virtual void OnNewClick (wxCommandEvent &event)
 
virtual void OnPasteClick (wxCommandEvent &event)
 
virtual void OnRedoClick (wxCommandEvent &event)
 
virtual void OnUndoClick (wxCommandEvent &event)
 
int GetNextID ()
 
std::vector< std::shared_ptr< ConnectionLine > >::iterator DeleteLineFromList (std::vector< std::shared_ptr< ConnectionLine > >::iterator &it)
 
void UnselectAll ()
 
void CopySelectionToClipboard ()
 
bool PasteFromClipboard ()
 
void SaveCurrentState ()
 
void SetPreviousState ()
 
void SetNextState ()
 
void ClearStates ()
 
bool GetElementsCorners (wxPoint2DDouble &leftUpCorner, wxPoint2DDouble &rightDownCorner, const std::vector< Element * > &elementList) const
 
void ApplyFontToElements ()
 
wxPoint GetEditorMouseClientPoint () const
 
wxPoint2DDouble GetEditorMouseWorldPoint () const
 

Protected Attributes

Cameram_camera = nullptr
 
PropertiesDatam_properties = nullptr
 
wxFont m_font
 
ControlEditorMode m_mode = ControlEditorMode::MODE_EDIT
 
wxRect2DDouble m_selectionRect
 
wxPoint2DDouble m_startSelRect
 
std::vector< std::shared_ptr< ControlElement > > m_elementList
 
std::vector< std::shared_ptr< ConnectionLine > > m_connectionList
 
ControlElementContainerm_ctrlContainer = nullptr
 
ControlEditorManagerm_ctrlManager = nullptr
 
bool m_justOpened = false
 
int m_ioFlags = 0
 
int m_inputType = 0
 
double m_startTime = 1.0
 
double m_slope = 1.0
 
double m_timeStep = 1e-4
 
double m_simTime = 10.0
 
int m_plotLib = 0
 
std::vector< wxColour > m_colourList
 
std::vector< wxColour >::iterator m_itColourList
 
std::vector< std::vector< std::shared_ptr< ControlElement > > > m_elementListState
 
std::vector< std::vector< std::shared_ptr< ConnectionLine > > > m_connectionListState
 
int m_currentState = -1
 
int m_maxStates = 100
 

Detailed Description

Definition at line 121 of file ControlEditor.h.

Member Enumeration Documentation

◆ ControlEditorMode

enum class ControlEditor::ControlEditorMode : int
strong

Definition at line 124 of file ControlEditor.h.

124 : int {
125 MODE_EDIT = 0,
126 MODE_MOVE_ELEMENT,
127 MODE_MOVE_LINE,
128 MODE_DRAG,
129 MODE_DRAG_INSERT,
130 MODE_INSERT,
131 MODE_INSERT_LINE,
132 MODE_SELECTION_RECT,
133 MODE_PASTE,
134 MODE_DRAG_PASTE
135 };

Constructor & Destructor Documentation

◆ ControlEditor() [1/2]

ControlEditor::ControlEditor ( wxWindow *  parent,
PropertiesData properties 
)
inline

Definition at line 136 of file ControlEditor.h.

136: ControlEditorBase(parent), m_properties(properties) {}

◆ ControlEditor() [2/2]

ControlEditor::ControlEditor ( wxWindow *  parent,
PropertiesData properties,
int  ioflags = IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_VELOCITY | IOControl::OUT_FIELD_VOLTAGE | IOControl::OUT_MEC_POWER 
)

Definition at line 244 of file ControlEditor.cpp.

244 : ControlEditorBase(parent), m_properties(properties)
245{
246 BuildControlElementPanel();
247 m_camera = new Camera();
248 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);;
249 m_cePanel->SetBackgroundColour(properties->GetGUIColour()->background);
250 m_cePanel->SetBackgroundStyle(wxBG_STYLE_PAINT); // To allow wxBufferedPaintDC works properly.
251 m_ioFlags = ioflags;
252 m_font = wxFont(m_properties->GetGeneralPropertiesData().labelFontSize,
253 wxFONTFAMILY_DEFAULT,
254 wxFONTSTYLE_NORMAL,
255 wxFONTWEIGHT_NORMAL,
256 false,
257 m_properties->GetGeneralPropertiesData().labelFont);
258
259 BuildColourList();
260}
Class responsible for the correct visualization of the elements on screen.
Definition Camera.h:31

◆ ~ControlEditor()

ControlEditor::~ControlEditor ( )
virtual

Definition at line 261 of file ControlEditor.cpp.

262{
263 ClearStates();
264 delete m_camera;
265 m_camera = nullptr;
266 // m_tfButton->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(ControlEditor::LeftClickDown), m_tfButton, this);
267}

Member Function Documentation

◆ AddElement()

void ControlEditor::AddElement ( ControlElementButtonID  id)
virtual

Definition at line 417 of file ControlEditor.cpp.

418{
419 switch (id) {
420 case ControlElementButtonID::ID_IO: {
421 m_mode = ControlEditorMode::MODE_INSERT;
422 auto io = std::make_shared<IOControl>(m_ioFlags, GetNextID());
423 m_elementList.push_back(io);
424 } break;
425 case ControlElementButtonID::ID_TF: {
426 m_mode = ControlEditorMode::MODE_INSERT;
427 auto tf = std::make_shared<TransferFunction>(GetNextID());
428 m_elementList.push_back(tf);
429 } break;
430 case ControlElementButtonID::ID_SUM: {
431 m_mode = ControlEditorMode::MODE_INSERT;
432 auto sum = std::make_shared<Sum>(GetNextID());
433 m_elementList.push_back(sum);
434 } break;
435 case ControlElementButtonID::ID_CONST: {
436 m_mode = ControlEditorMode::MODE_INSERT;
437 auto constant = std::make_shared<Constant>(GetNextID());
438 m_elementList.push_back(constant);
439 } break;
440 case ControlElementButtonID::ID_LIMITER: {
441 m_mode = ControlEditorMode::MODE_INSERT;
442 auto limiter = std::make_shared<Limiter>(GetNextID());
443 m_elementList.push_back(limiter);
444 } break;
445 case ControlElementButtonID::ID_GAIN: {
446 m_mode = ControlEditorMode::MODE_INSERT;
447 auto gain = std::make_shared<Gain>(GetNextID());
448 m_elementList.push_back(gain);
449 } break;
450 case ControlElementButtonID::ID_MULT: {
451 m_mode = ControlEditorMode::MODE_INSERT;
452 auto mult = std::make_shared<Multiplier>(GetNextID());
453 m_elementList.push_back(mult);
454 } break;
455 case ControlElementButtonID::ID_EXP: {
456 m_mode = ControlEditorMode::MODE_INSERT;
457 auto exp = std::make_shared<Exponential>(GetNextID());
458 m_elementList.push_back(exp);
459 } break;
460 case ControlElementButtonID::ID_RATELIM: {
461 m_mode = ControlEditorMode::MODE_INSERT;
462 auto rateLim = std::make_shared<RateLimiter>(GetNextID());
463 m_elementList.push_back(rateLim);
464 } break;
465 case ControlElementButtonID::ID_MATH_DIV: {
466 m_mode = ControlEditorMode::MODE_INSERT;
467 auto divider = std::make_shared<Divider>(GetNextID());
468 m_elementList.push_back(divider);
469 } break;
470 case ControlElementButtonID::ID_MATH_EXPR: {
471 m_mode = ControlEditorMode::MODE_INSERT;
472 auto mathExpr = std::make_shared<MathExpression>(GetNextID());
473 m_elementList.push_back(mathExpr);
474 } break;
475 }
476 for (auto& cElement : m_elementList)
477 {
478 cElement->SetFont(m_font);
479 cElement->StartMove(wxPoint2DDouble(0, 0));
480 cElement->Move(wxPoint2DDouble(0, 0));
481
482 }
483}

◆ ApplyFontToElements()

void ControlEditor::ApplyFontToElements ( )
protected

Definition at line 1278 of file ControlEditor.cpp.

1279{
1280 for (auto& element : m_elementList) {
1281 element->SetFont(m_font);
1282 }
1283}

◆ BuildColourList()

void ControlEditor::BuildColourList ( )
virtual

Definition at line 1519 of file ControlEditor.cpp.

1520{
1521 m_colourList.push_back(wxColour(255, 30, 0));
1522 m_colourList.push_back(wxColour(0, 30, 255));
1523 m_colourList.push_back(wxColour(0, 128, 0));
1524 m_colourList.push_back(wxColour(100, 100, 100));
1525 m_colourList.push_back(wxColour(255, 128, 0));
1526 m_colourList.push_back(wxColour(128, 0, 255));
1527 m_colourList.push_back(wxColour(0, 255, 128));
1528 m_colourList.push_back(wxColour(255, 255, 0));
1529 m_colourList.push_back(wxColour(255, 0, 255));
1530 m_colourList.push_back(wxColour(0, 255, 255));
1531 m_colourList.push_back(wxColour(128, 255, 0));
1532 m_colourList.push_back(wxColour(255, 0, 128));
1533 m_colourList.push_back(wxColour(0, 128, 255));
1534 m_colourList.push_back(wxColour(128, 128, 128));
1535 m_colourList.push_back(*wxBLACK);
1536 m_itColourList = --m_colourList.end();
1537}

◆ BuildControlElementPanel()

void ControlEditor::BuildControlElementPanel ( )

Definition at line 284 of file ControlEditor.cpp.

285{
286 m_panelControlElements->SetDoubleBuffered(true);
287
288 wxWrapSizer* wrapSizer = new wxWrapSizer();
289 m_panelControlElements->SetSizer(wrapSizer);
290
291 auto* guiColour = m_properties->GetGUIColour();
292
293 m_panelControlElements->SetBackgroundColour(guiColour->background);
294
295 wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
296
297 auto iconIOControl = std::make_unique<IOControl>(IOControl::IOFlags::IN_IO, -1);
298 iconIOControl->SetValue(IOControl::IOFlags::IN_IO);
299
301 m_panelControlElements, _("In/Out"),
302 std::move(iconIOControl),
303 static_cast<int>(ControlElementButtonID::ID_IO),
304 guiColour, 0.8);
305 wrapSizer->Add(ioButton, 0, wxALL, 5);
306 ioButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
307
308 auto iconTF = std::make_unique<TransferFunction>(-1);
309
311 m_panelControlElements, _("Transfer fcn"),
312 std::move(iconTF),
313 static_cast<int>(ControlElementButtonID::ID_TF),
314 guiColour, 0.8);
315 wrapSizer->Add(tfButton, 0, wxALL, 5);
316 tfButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
317
318 auto iconSum = std::make_unique<Sum>(-1);
319
321 m_panelControlElements, _("Sum"),
322 std::move(iconSum),
323 static_cast<int>(ControlElementButtonID::ID_SUM),
324 guiColour, 0.8);
325 wrapSizer->Add(sumButton, 0, wxALL, 5);
326 sumButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
327
328 auto iconConstant = std::make_unique<Constant>(-1);
329 iconConstant->SetValue(3.14);
330
332 m_panelControlElements, _("Constant"),
333 std::move(iconConstant),
334 static_cast<int>(ControlElementButtonID::ID_CONST),
335 guiColour);
336 wrapSizer->Add(constButton, 0, wxALL, 5);
337 constButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
338
339 auto iconGain = std::make_unique<Gain>(-1);
340 iconGain->SetValue(0.5);
341
343 m_panelControlElements, _("Gain"),
344 std::move(iconGain),
345 static_cast<int>(ControlElementButtonID::ID_GAIN),
346 guiColour, 0.8);
347 wrapSizer->Add(gainButton, 0, wxALL, 5);
348 gainButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
349
350 auto iconLimiter = std::make_unique<Limiter>(-1);
351
353 m_panelControlElements, _("Limiter"),
354 std::move(iconLimiter),
355 static_cast<int>(ControlElementButtonID::ID_LIMITER),
356 guiColour, 0.8);
357 wrapSizer->Add(limButton, 0, wxALL, 5);
358 limButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
359
360 auto iconRateLim = std::make_unique<RateLimiter>(-1);
361
362 ControlElementButton* rateLimButton = new ControlElementButton(
363 m_panelControlElements, _("Rate limiter"),
364 std::move(iconRateLim),
365 static_cast<int>(ControlElementButtonID::ID_RATELIM),
366 guiColour, 0.8);
367 wrapSizer->Add(rateLimButton, 0, wxALL, 5);
368 rateLimButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
369
370 auto iconMult = std::make_unique<Multiplier>(-1);
371
373 m_panelControlElements, _("Multiplier"),
374 std::move(iconMult),
375 static_cast<int>(ControlElementButtonID::ID_MULT),
376 guiColour, 0.8);
377 wrapSizer->Add(multButton, 0, wxALL, 5);
378 multButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
379
380 auto iconDiv = std::make_unique<Divider>(-1);
381
383 m_panelControlElements, _("Divider"),
384 std::move(iconDiv),
385 static_cast<int>(ControlElementButtonID::ID_MATH_DIV),
386 guiColour, 0.8);
387 wrapSizer->Add(divButton, 0, wxALL, 5);
388 divButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
389
390 auto iconMathExpr = std::make_unique<MathExpression>(-1);
391
392 ControlElementButton* mathExprButton = new ControlElementButton(
393 m_panelControlElements, _("Math Expression"),
394 std::move(iconMathExpr),
395 static_cast<int>(ControlElementButtonID::ID_MATH_EXPR),
396 guiColour, 0.8);
397 wrapSizer->Add(mathExprButton, 0, wxALL, 5);
398 mathExprButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
399
400 auto iconExp = std::make_unique<Exponential>(-1);
401
403 m_panelControlElements, _("Exponential"),
404 std::move(iconExp),
405 static_cast<int>(ControlElementButtonID::ID_EXP),
406 guiColour, 0.8);
407 wrapSizer->Add(satButton, 0, wxALL, 5);
408 satButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
409}
This class is responsible to handle the user interaction with control elements.

◆ CheckConnections()

void ControlEditor::CheckConnections ( )
virtual

Definition at line 1013 of file ControlEditor.cpp.

1014{
1015 for (auto it = m_connectionList.begin(); it != m_connectionList.end(); ++it) {
1016 ConnectionLine* cLine = it->get();
1017 if (cLine->GetType() == ConnectionLine::ConnectionLineType::ELEMENT_ELEMENT) {
1018 if (cLine->GetParentList().size() < 2) { it = DeleteLineFromList(it); }
1019 }
1020 else if (cLine->GetParentList().size() < 1) {
1021 it = DeleteLineFromList(it);
1022 }
1023 }
1024}
Connection between two control elements or other connection line and an element.
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition Element.h:562

◆ ClearStates()

void ControlEditor::ClearStates ( )
protected

Definition at line 1302 of file ControlEditor.cpp.

1303{
1304 m_elementListState.clear();
1305 m_connectionListState.clear();
1306 m_currentState = -1;
1307}

◆ CopySelectionToClipboard()

void ControlEditor::CopySelectionToClipboard ( )
protected

Definition at line 1380 of file ControlEditor.cpp.

1381{
1382 std::vector<std::shared_ptr<ControlElement>> selectedElements;
1383 std::vector<std::shared_ptr<ConnectionLine>> selectedLines;
1384
1385 for (auto& el : m_elementList) {
1386 if (el->IsSelected()) selectedElements.push_back(el);
1387 }
1388 for (auto& ln : m_connectionList) {
1389 if (ln->IsSelected()) selectedLines.push_back(ln);
1390 }
1391
1392 // If user selected only elements, include the connection lines between them (and children) to keep the
1393 // copied system consistent.
1394 if (!selectedElements.empty() && selectedLines.empty()) {
1395 std::unordered_set<Element*> selectedSet;
1396 selectedSet.reserve(selectedElements.size());
1397 for (auto& el : selectedElements) selectedSet.insert(el.get());
1398
1399 for (auto& ln : m_connectionList) {
1400 auto parents = ln->GetParentList();
1401 if (parents.size() >= 2 &&
1402 selectedSet.contains(parents[0]) &&
1403 selectedSet.contains(parents[1])) {
1404 selectedLines.push_back(ln);
1405 }
1406 }
1407 }
1408
1409 // Deep copy into clipboard payload
1410 ControlElementContainer container;
1411 container.FillContainer(selectedElements, selectedLines);
1412 std::vector<std::shared_ptr<ControlElement>> copyElements;
1413 std::vector<std::shared_ptr<ConnectionLine>> copyLines;
1414 container.GetContainerCopy(copyElements, copyLines);
1415 SanitizeControlGraph(copyElements, copyLines);
1416
1417 auto* dataObject = new ControlElementDataObject(copyElements, copyLines);
1418 if (wxTheClipboard->Open()) {
1419 wxTheClipboard->SetData(dataObject);
1420 wxTheClipboard->Close();
1421 }
1422}
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Clipboard payload for ControlEditor copy/paste (control elements + connection lines).

◆ DeleteLineFromList()

std::vector< std::shared_ptr< ConnectionLine > >::iterator ControlEditor::DeleteLineFromList ( std::vector< std::shared_ptr< ConnectionLine > >::iterator &  it)
protected

Definition at line 984 of file ControlEditor.cpp.

985{
986 ConnectionLine* cLine = it->get();
987
988 // Delete children recursively
989 auto childList = cLine->GetLineChildList();
990 for (auto child : childList) {
991 for (auto itL = m_connectionList.begin(); itL != m_connectionList.end(); ) {
992 if (itL->get() == child)
993 itL = DeleteLineFromList(itL);
994 else
995 ++itL;
996 }
997 }
998 // Remove parents
999 auto parentList = cLine->GetParentList();
1000 for (auto parent : parentList) {
1001 if (parent) parent->RemoveChild(cLine);
1002 }
1003 if (cLine->GetParentLine()) cLine->GetParentLine()->RemoveChild(cLine);
1004
1005 // Free nodes
1006 auto nodeList = cLine->GetNodeList();
1007 for (auto node : nodeList)
1008 node->SetConnected(false);
1009
1010 return m_connectionList.erase(it);
1011}
virtual void RemoveChild(Element *child)
Remove a child from the list.
Definition Element.cpp:500

◆ DeleteSelectedElements()

void ControlEditor::DeleteSelectedElements ( )
virtual

Definition at line 945 of file ControlEditor.cpp.

946{
947 for (auto it = m_elementList.begin(); it != m_elementList.end();) {
948 Element* element = it->get();
949 if (element->IsSelected()) {
950 // Remove child/parent.
951 auto childList = element->GetChildList();
952 for (auto child : childList) {
953 // The child is always a connection line, but check it.
954 //ConnectionLine* child = static_cast<ConnectionLine*>(*itC);
955 if (auto childLine = dynamic_cast<ConnectionLine*>(child)) {
956 // Delete the connection line.
957 for (auto itCo = m_connectionList.begin(); itCo != m_connectionList.end(); ) {
958 if (itCo->get() == childLine)
959 itCo = DeleteLineFromList(itCo);
960 else
961 ++itCo;
962 }
963 }
964
965 }
966 m_elementList.erase(it);
967 //if (element) delete element;
968 }
969 else {
970 ++it;
971 }
972 }
973
974 for (auto it = m_connectionList.begin(); it != m_connectionList.end(); ) {
975 ConnectionLine* line = it->get();
976 if (line->IsSelected())
977 it = DeleteLineFromList(it);
978 else
979 ++it;
980 }
981 Redraw();
982}
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:114
virtual std::vector< Element * > GetChildList() const
Get the Child list.
Definition Element.h:567
bool IsSelected() const
Checks if the element is selected.
Definition Element.h:203

◆ Fit()

void ControlEditor::Fit ( )
virtual

Definition at line 1234 of file ControlEditor.cpp.

1235{
1236 wxPoint2DDouble leftUpCorner(0, 0);
1237 wxPoint2DDouble rightDownCorner(0, 0);
1238 std::vector<Element*> elementList = GetElementList();
1239
1240 if (!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
1241 wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0;
1242
1243 int width = 0.0;
1244 int height = 0.0;
1245 m_cePanel->GetSize(&width, &height);
1246
1247 const double scaleX = static_cast<double>(width) / (rightDownCorner.m_x - leftUpCorner.m_x);
1248 const double scaleY = static_cast<double>(height) / (rightDownCorner.m_y - leftUpCorner.m_y);
1249
1250 double scale = scaleX < scaleY ? scaleX : scaleY;
1251 scale = std::min(scale, m_camera->GetZoomMax());
1252 scale = std::max(scale, m_camera->GetZoomMin());
1253
1254 m_camera->SetScale(scale);
1255
1256 m_camera->StartTranslation(middleCoords);
1257 m_camera->SetTranslation(wxPoint2DDouble(width / 2.0, height / 2.0));
1258
1259 Redraw();
1260}

◆ GetConnectionLineList()

virtual std::vector< std::shared_ptr< ConnectionLine > > ControlEditor::GetConnectionLineList ( ) const
inlinevirtual

Definition at line 149 of file ControlEditor.h.

149{ return m_connectionList; }

◆ GetControlContainer()

virtual ControlElementContainer * ControlEditor::GetControlContainer ( )
inlinevirtual

Definition at line 154 of file ControlEditor.h.

154{ return m_ctrlContainer; }

◆ GetControlElementList()

virtual std::vector< std::shared_ptr< ControlElement > > ControlEditor::GetControlElementList ( ) const
inlinevirtual

Definition at line 150 of file ControlEditor.h.

150{ return m_elementList; }

◆ GetEditorMouseClientPoint()

wxPoint ControlEditor::GetEditorMouseClientPoint ( ) const
protected

Definition at line 269 of file ControlEditor.cpp.

270{
271 if (!m_cePanel) return wxPoint(0, 0);
272 return m_cePanel->ScreenToClient(wxGetMousePosition());
273}

◆ GetEditorMouseWorldPoint()

wxPoint2DDouble ControlEditor::GetEditorMouseWorldPoint ( ) const
protected

Definition at line 275 of file ControlEditor.cpp.

276{
277 if (!m_camera) return wxPoint2DDouble(0, 0);
278 wxPoint clientMouse = GetEditorMouseClientPoint();
279 if (m_cePanel && m_cePanel->GetClientRect().Contains(clientMouse))
280 return m_camera->ScreenToWorld(clientMouse);
281 return m_camera->GetMousePosition();
282}

◆ GetElementList()

std::vector< Element * > ControlEditor::GetElementList ( ) const
virtual

Definition at line 1225 of file ControlEditor.cpp.

1226{
1227 std::vector<Element*> elementList;
1228 for (auto& element : m_elementList) {
1229 elementList.push_back(element.get());
1230 }
1231 return elementList;
1232}

◆ GetElementsCorners()

bool ControlEditor::GetElementsCorners ( wxPoint2DDouble &  leftUpCorner,
wxPoint2DDouble &  rightDownCorner,
const std::vector< Element * > &  elementList 
) const
protected

Definition at line 1285 of file ControlEditor.cpp.

1288{
1289 if (elementList.empty()) return false;
1290 elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner);
1291 for (size_t i = 1; i < elementList.size(); i++) {
1292 wxPoint2DDouble lu, rd;
1293 elementList[i]->CalculateBoundaries(lu, rd);
1294 if (lu.m_x < leftUpCorner.m_x) leftUpCorner.m_x = lu.m_x;
1295 if (lu.m_y < leftUpCorner.m_y) leftUpCorner.m_y = lu.m_y;
1296 if (rd.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rd.m_x;
1297 if (rd.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rd.m_y;
1298 }
1299 return true;
1300}

◆ GetNextColour()

wxColour ControlEditor::GetNextColour ( )
virtual

Definition at line 1539 of file ControlEditor.cpp.

1540{
1541 if (*m_itColourList == *wxBLACK)
1542 m_itColourList = m_colourList.begin();
1543 else
1544 ++m_itColourList;
1545
1546 return *m_itColourList;
1547}

◆ GetNextID()

int ControlEditor::GetNextID ( )
protected

Definition at line 1506 of file ControlEditor.cpp.

1507{
1508 int id = 0;
1509 for (auto& element : m_elementList) {
1510 if (element->GetID() > id) id = element->GetID();
1511 }
1512 for (auto& line : m_connectionList) {
1513 if (line->GetID() > id) id = line->GetID();
1514 }
1515 id++;
1516 return id;
1517}

◆ LeftClickDown()

void ControlEditor::LeftClickDown ( wxMouseEvent &  event)
virtual

Definition at line 411 of file ControlEditor.cpp.

412{
413 AddElement(static_cast<ControlElementButtonID>(event.GetId()));
414 event.Skip();
415}

◆ OnButtonOKClick()

virtual void ControlEditor::OnButtonOKClick ( wxCommandEvent &  event)
inlinevirtual

Definition at line 162 of file ControlEditor.h.

162{ Close(); }

◆ OnClose()

void ControlEditor::OnClose ( wxCloseEvent &  event)
virtual

Definition at line 1262 of file ControlEditor.cpp.

1263{
1264 if (m_ctrlContainer) { m_ctrlContainer->FillContainer(this); }
1265 ClearStates();
1266 if (m_ctrlManager)
1267 m_ctrlManager->Remove(this);
1268 Destroy();
1269 //event.Skip();
1270}

◆ OnCopyClick()

void ControlEditor::OnCopyClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1548 of file ControlEditor.cpp.

1549{
1550 CopySelectionToClipboard();
1551}

◆ OnDeleteClick()

void ControlEditor::OnDeleteClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1552 of file ControlEditor.cpp.

1553{
1554 DeleteSelectedElements();
1555 SaveCurrentState();
1556}

◆ OnDoubleClick()

void ControlEditor::OnDoubleClick ( wxMouseEvent &  event)
virtual

Definition at line 517 of file ControlEditor.cpp.

518{
519 wxPoint2DDouble clickPoint = event.GetPosition();
520 bool redraw = false;
521
522 if (m_mode == ControlEditor::ControlEditorMode::MODE_EDIT) {
523 for (auto& element : m_elementList) {
524 if (element->Contains(m_camera->ScreenToWorld(clickPoint))) {
525 element->ShowForm(this, element.get());
526 CheckConnections();
527 auto childList = element->GetChildList();
528 for (auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
529 ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
530 line->UpdatePoints();
531 }
532 redraw = true;
533 SaveCurrentState();
534 break;
535 }
536 }
537 }
538
539 if (redraw) Redraw();
540}

◆ OnDragClick()

void ControlEditor::OnDragClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1557 of file ControlEditor.cpp.

1558{
1559 // Same behavior as middle mouse drag: anchor at current mouse, pan only on motion (no jump).
1560 m_mode = ControlEditorMode::MODE_DRAG;
1561 m_camera->StartTranslation(GetEditorMouseWorldPoint());
1562 if (m_cePanel) m_cePanel->SetFocus();
1563}

◆ OnExportClick()

void ControlEditor::OnExportClick ( wxCommandEvent &  event)
virtual

Definition at line 1035 of file ControlEditor.cpp.

1036{
1037 FileHanding fileHandling(this);
1038
1039 wxFileDialog saveFileDialog(this, _("Save CTL file"), "", "", "CTL files (*.ctl)|*.ctl",
1040 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1041 if (saveFileDialog.ShowModal() == wxID_CANCEL) return;
1042
1043 fileHandling.SaveControl(saveFileDialog.GetPath());
1044 wxFileName fileName(saveFileDialog.GetPath());
1045 event.Skip();
1046}
Save and opens the projects created on disk.
Definition FileHanding.h:43

◆ OnFitClick()

void ControlEditor::OnFitClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1642 of file ControlEditor.cpp.

1643{
1644 Fit();
1645}

◆ OnIdle()

void ControlEditor::OnIdle ( wxIdleEvent &  event)
virtual

Definition at line 856 of file ControlEditor.cpp.

857{
858 //if(m_justOpened) {
859 // this->Raise();
860 //
861 // // Update all text elements
862 // m_justOpened = false;
863 // for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
864 // ControlElement* element = *it;
865 // if(!element->UpdateText()) m_justOpened = true;
866 // }
867 // Redraw();
868 //}
869}

◆ OnImportClick()

void ControlEditor::OnImportClick ( wxCommandEvent &  event)
virtual

Definition at line 1048 of file ControlEditor.cpp.

1049{
1050 wxFileDialog openFileDialog(this, _("Open CTL file"), "", "", "CTL files (*.ctl)|*.ctl",
1051 wxFD_OPEN | wxFD_FILE_MUST_EXIST);
1052 if (openFileDialog.ShowModal() == wxID_CANCEL) return;
1053
1054 wxFileName fileName(openFileDialog.GetPath());
1055
1056 FileHanding fileHandling(this);
1057 if (!fileHandling.OpenControl(fileName, m_elementList, m_connectionList)) {
1058 wxMessageDialog msgDialog(this, _("It was not possible to open the selected file."), _("Error"),
1059 wxOK | wxCENTRE | wxICON_ERROR);
1060 msgDialog.ShowModal();
1061 }
1062 for (auto cElement : m_elementList)
1063 {
1064 cElement->SetFont(m_font);
1065 }
1066 Redraw();
1067 event.Skip();
1068}

◆ OnKeyDown()

void ControlEditor::OnKeyDown ( wxKeyEvent &  event)
virtual

Definition at line 870 of file ControlEditor.cpp.

871{
872 bool hasInsertInProgress = (m_mode == ControlEditorMode::MODE_INSERT ||
873 m_mode == ControlEditorMode::MODE_INSERT_LINE);
874 char key = event.GetUnicodeKey();
875 if (key != WXK_NONE) {
876 switch (key) {
877 case WXK_DELETE: // Delete selected elements.
878 {
879 if (!hasInsertInProgress) {
880 wxCommandEvent dummyEvent;
881 OnDeleteClick(dummyEvent);
882 }
883 } break;
884 case 'R': // Rotate the selected elements.
885 {
886 RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
887 SaveCurrentState();
888 } break;
889 case 'C': {
890 if (!hasInsertInProgress && event.GetModifiers() == wxMOD_CONTROL) {
891 wxCommandEvent dummyEvent;
892 OnCopyClick(dummyEvent);
893 }
894 } break;
895 case 'V': {
896 if (!hasInsertInProgress && event.GetModifiers() == wxMOD_CONTROL) {
897 wxCommandEvent dummyEvent;
898 OnPasteClick(dummyEvent);
899 }
900 } break;
901 case 'Z': {
902 if (!hasInsertInProgress && event.ControlDown() && !event.ShiftDown()) {
903 wxCommandEvent dummyEvent;
904 OnUndoClick(dummyEvent);
905 }
906 if (!hasInsertInProgress && event.ControlDown() && event.ShiftDown()) {
907 wxCommandEvent dummyEvent;
908 OnRedoClick(dummyEvent);
909 }
910 } break;
911 case 'Y': {
912 if (!hasInsertInProgress && event.GetModifiers() == wxMOD_CONTROL) {
913 wxCommandEvent dummyEvent;
914 OnRedoClick(dummyEvent);
915 }
916 } break;
917 case 'N': {
918 if (!hasInsertInProgress && event.GetModifiers() == wxMOD_CONTROL) {
919 wxCommandEvent dummyEvent;
920 OnNewClick(dummyEvent);
921 }
922 } break;
923 case 'L': {
924 // tests
925 } break;
926 }
927 }
928}

◆ OnLeftClickDown()

void ControlEditor::OnLeftClickDown ( wxMouseEvent &  event)
virtual

Definition at line 542 of file ControlEditor.cpp.

543{
544 wxPoint2DDouble clickPoint = event.GetPosition();
545 bool foundElement = false;
546
547 if (m_mode == ControlEditorMode::MODE_PASTE || m_mode == ControlEditorMode::MODE_DRAG_PASTE) {
548 m_mode = ControlEditorMode::MODE_EDIT;
549 SaveCurrentState();
550 }
551 else if (m_mode == ControlEditorMode::MODE_INSERT) {
552 // Update the font of the last element in the list.
553 //auto cElement = m_elementList.back();
554 //cElement->SetFont(m_font);
555 m_mode = ControlEditor::ControlEditorMode::MODE_EDIT;
556 }
557 else {
558 for (auto& element : m_elementList) {
559 bool foundNode = false;
560 auto nodeList = element->GetNodeList();
561 for (auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
562 Node* node = *itN;
563 if (node->Contains(m_camera->ScreenToWorld(clickPoint))) {
564 m_mode = ControlEditorMode::MODE_INSERT_LINE;
565 auto line = std::make_shared<ConnectionLine>(node, GetNextID());
566 m_connectionList.push_back(line);
567 element->AddChild(line.get());
568 line->AddParent(element.get());
569 foundElement = true;
570 foundNode = true;
571 }
572 }
573
574 if (!foundNode) {
575 // Set movement initial position (not necessarily will be moved).
576 element->StartMove(m_camera->ScreenToWorld(clickPoint));
577
578 // Click in an element.
579 if (element->Contains(m_camera->ScreenToWorld(clickPoint))) {
580 if (!foundElement) {
581 element->SetSelected();
582 foundElement = true;
583 }
584 m_mode = ControlEditor::ControlEditorMode::MODE_MOVE_ELEMENT;
585 }
586 }
587 }
588 if (m_mode != ControlEditorMode::MODE_INSERT_LINE) {
589 for (auto& line : m_connectionList) {
590 line->StartMove(m_camera->ScreenToWorld(clickPoint));
591 if (line->Contains(m_camera->ScreenToWorld(clickPoint))) {
592 line->SetSelected();
593 foundElement = true;
594 m_mode = ControlEditorMode::MODE_MOVE_LINE;
595 }
596 }
597 }
598 }
599
600 if (!foundElement) {
601 m_mode = ControlEditorMode::MODE_SELECTION_RECT;
602 m_startSelRect = m_camera->ScreenToWorld(clickPoint);
603 }
604
605 Redraw();
606 event.Skip();
607}
Node of a control element. This class manages the user interaction with the connection and control el...

◆ OnLeftClickUp()

void ControlEditor::OnLeftClickUp ( wxMouseEvent &  event)
virtual

Definition at line 609 of file ControlEditor.cpp.

610{
611 bool foundNode = false;
612 bool saveCurrentState = false;
613
614 for (auto& element : m_elementList) {
615 if (m_mode == ControlEditorMode::MODE_INSERT_LINE) {
616 auto nodeList = element->GetNodeList();
617 for (auto node : nodeList) {
618 if (node->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
619 //ConnectionLine* line = *(m_connectionList.end() - 1);
620 auto line = m_connectionList.back();
621 if (line->AppendNode(node, element.get())) {
622 line->AddParent(element.get());
623 element->AddChild(line.get());
624 line->UpdatePoints();
625 m_mode = ControlEditor::ControlEditorMode::MODE_EDIT;
626 foundNode = true;
627 saveCurrentState = true;
628 }
629 }
630 }
631 }
632 else if (m_mode == ControlEditorMode::MODE_SELECTION_RECT) {
633 if (element->Intersects(m_selectionRect)) {
634 element->SetSelected();
635 }
636 else if (!event.ControlDown()) {
637 element->SetSelected(false);
638 }
639 }
640 else if (!event.ControlDown()) {
641 if (!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { element->SetSelected(false); }
642 }
643 }
644
645 if (!m_connectionList.empty()) {
646 auto& lastLine = m_connectionList.back();
647 for (auto& cLine : m_connectionList) {
648 if (m_mode == ControlEditorMode::MODE_INSERT_LINE && !foundNode && cLine.get() != lastLine.get()) {
649 if (cLine->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
650 //ConnectionLine* iLine = *(m_connectionList.end() - 1);
651 auto iLine = m_connectionList.back();
652 if (iLine->SetParentLine(cLine.get())) {
653 cLine->AddChild(iLine.get());
654 iLine->UpdatePoints();
655 m_mode = ControlEditor::ControlEditorMode::MODE_EDIT;
656 foundNode = true;
657 }
658 }
659 }
660 else if (m_mode == ControlEditorMode::MODE_SELECTION_RECT) {
661 if (cLine->Intersects(m_selectionRect)) {
662 cLine->SetSelected();
663 }
664 else if (!event.ControlDown()) {
665 cLine->SetSelected(false);
666 }
667 }
668 else if (!event.ControlDown()) {
669 if (!cLine->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { cLine->SetSelected(false); }
670 }
671 }
672 }
673
674 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
675
676 if (m_mode == ControlEditorMode::MODE_INSERT_LINE && !foundNode) {
677 //ConnectionLine* cLine = *(m_connectionList.end() - 1);
678 auto cLine = m_connectionList.back();
679 // Free nodes
680 auto nodeList = cLine->GetNodeList();
681 for (auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
682 Node* node = *itN;
683 node->SetConnected(false);
684 }
685 // Remove the associated child from parents.
686 auto parentList = cLine->GetParentList();
687 for (auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
688 Element* element = *it;
689 element->RemoveChild(cLine.get());
690 }
691 m_connectionList.pop_back();
692 //if (cLine) delete cLine;
693 m_mode = ControlEditor::ControlEditorMode::MODE_EDIT;
694 }
695 else if (m_mode != ControlEditorMode::MODE_INSERT) {
696 if (m_mode == ControlEditorMode::MODE_MOVE_ELEMENT || m_mode == ControlEditorMode::MODE_MOVE_LINE) {
697 saveCurrentState = true;
698 }
699 m_mode = ControlEditor::ControlEditorMode::MODE_EDIT;
700 }
701
702 if (saveCurrentState) SaveCurrentState();
703
704 Redraw();
705 event.Skip();
706}

◆ OnMiddleDoubleClick()

void ControlEditor::OnMiddleDoubleClick ( wxMouseEvent &  event)
protectedvirtual

Definition at line 1646 of file ControlEditor.cpp.

1647{
1648 Fit();
1649 event.Skip();
1650}

◆ OnMiddleDown()

void ControlEditor::OnMiddleDown ( wxMouseEvent &  event)
virtual

Definition at line 708 of file ControlEditor.cpp.

709{
710 // Set to drag mode.
711 switch (m_mode) {
712 case ControlEditorMode::MODE_INSERT: {
713 m_mode = ControlEditorMode::MODE_DRAG_INSERT;
714 } break;
715 case ControlEditorMode::MODE_PASTE: {
716 m_mode = ControlEditorMode::MODE_DRAG_PASTE;
717 } break;
718 default: {
719 m_mode = ControlEditorMode::MODE_DRAG;
720 } break;
721 }
722 m_camera->StartTranslation(GetEditorMouseWorldPoint());
723}

◆ OnMiddleUp()

void ControlEditor::OnMiddleUp ( wxMouseEvent &  event)
virtual

Definition at line 725 of file ControlEditor.cpp.

726{
727 switch (m_mode) {
728 case ControlEditorMode::MODE_DRAG_INSERT: {
729 m_mode = ControlEditorMode::MODE_INSERT;
730 } break;
731 case ControlEditorMode::MODE_DRAG_PASTE: {
732 m_mode = ControlEditorMode::MODE_PASTE;
733 } break;
734 case ControlEditorMode::MODE_INSERT:
735 case ControlEditorMode::MODE_PASTE: {
736 // Does nothing.
737 } break;
738 default: {
739 m_mode = ControlEditor::ControlEditorMode::MODE_EDIT;
740 } break;
741 }
742}

◆ OnMouseMotion()

void ControlEditor::OnMouseMotion ( wxMouseEvent &  event)
virtual

Definition at line 744 of file ControlEditor.cpp.

745{
746 wxPoint2DDouble clickPoint = event.GetPosition();
747 bool redraw = false;
748
749 switch (m_mode) {
750 case ControlEditorMode::MODE_INSERT: {
751 //Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
752 auto newElement = m_elementList.back();
753 newElement->Move(m_camera->ScreenToWorld(clickPoint));
754 redraw = true;
755 } break;
756 case ControlEditorMode::MODE_INSERT_LINE: {
757 //ConnectionLine* line = *(m_connectionList.end() - 1);
758 auto line = m_connectionList.back();
759 line->SetTemporarySecondPoint(m_camera->ScreenToWorld(clickPoint));
760 line->UpdatePoints();
761 redraw = true;
762 } break;
763 case ControlEditorMode::MODE_DRAG:
764 case ControlEditorMode::MODE_DRAG_INSERT:
765 case ControlEditorMode::MODE_DRAG_PASTE: {
766 m_camera->SetTranslation(clickPoint);
767 redraw = true;
768 } break;
769 case ControlEditorMode::MODE_PASTE: {
770 bool movedSelectedElement = false;
771 for (auto& element : m_elementList) {
772 if (element->IsSelected()) {
773 movedSelectedElement = true;
774 element->Move(m_camera->ScreenToWorld(clickPoint));
775 auto childList = element->GetChildList();
776 for (Element* child : childList) {
777 if (auto line = dynamic_cast<ConnectionLine*>(child)) line->UpdatePoints();
778 }
779 redraw = true;
780 }
781 }
782 // Only move lines directly when no element is selected; otherwise line movement would
783 // be applied twice and corrupt offsets.
784 if (!movedSelectedElement) {
785 for (auto& line : m_connectionList) {
786 if (line->IsSelected()) {
787 line->Move(m_camera->ScreenToWorld(clickPoint));
788 redraw = true;
789 }
790 }
791 }
792 } break;
793 case ControlEditor::ControlEditorMode::MODE_MOVE_ELEMENT: {
794 for (auto& element : m_elementList) {
795 if (element->IsSelected()) {
796 element->Move(m_camera->ScreenToWorld(clickPoint));
797 auto childList = element->GetChildList();
798 for (auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) {
799 ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
800 line->UpdatePoints();
801 }
802 redraw = true;
803 }
804 }
805 } break;
806 case ControlEditorMode::MODE_MOVE_LINE: {
807 for (auto& line : m_connectionList) {
808 if (line->IsSelected()) {
809 line->Move(m_camera->ScreenToWorld(clickPoint));
810 redraw = true;
811 }
812 }
813 } break;
814 case ControlEditorMode::MODE_SELECTION_RECT: {
815 wxPoint2DDouble currentPos = m_camera->ScreenToWorld(clickPoint);
816 double x, y, w, h;
817 if (currentPos.m_x < m_startSelRect.m_x) {
818 x = currentPos.m_x;
819 w = m_startSelRect.m_x - currentPos.m_x;
820 }
821 else {
822 x = m_startSelRect.m_x;
823 w = currentPos.m_x - m_startSelRect.m_x;
824 }
825 if (currentPos.m_y < m_startSelRect.m_y) {
826 y = currentPos.m_y;
827 h = m_startSelRect.m_y - currentPos.m_y;
828 }
829 else {
830 y = m_startSelRect.m_y;
831 h = currentPos.m_y - m_startSelRect.m_y;
832 }
833
834 m_selectionRect = wxRect2DDouble(x, y, w, h);
835 redraw = true;
836 } break;
837 default:
838 break;
839 }
840
841 m_camera->UpdateMousePosition(clickPoint);
842 if (redraw) Redraw();
843 event.Skip();
844}

◆ OnMoveClick()

void ControlEditor::OnMoveClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1564 of file ControlEditor.cpp.

1565{
1566 bool hasSelectedElement = false;
1567 bool hasSelectedLine = false;
1568 std::vector<Element*> selectedObjects;
1569
1570 for (auto& element : m_elementList) {
1571 if (element->IsSelected()) {
1572 hasSelectedElement = true;
1573 selectedObjects.push_back(element.get());
1574 }
1575 }
1576 for (auto& line : m_connectionList) {
1577 if (line->IsSelected()) {
1578 hasSelectedLine = true;
1579 selectedObjects.push_back(line.get());
1580 }
1581 }
1582 if (!hasSelectedElement && !hasSelectedLine) return;
1583
1584 m_mode = hasSelectedElement ? ControlEditorMode::MODE_MOVE_ELEMENT : ControlEditorMode::MODE_MOVE_LINE;
1585
1586 wxPoint2DDouble mouseWorld = GetEditorMouseWorldPoint();
1587
1588 wxPoint2DDouble leftUp, rightDown;
1589 if (!GetElementsCorners(leftUp, rightDown, selectedObjects)) return;
1590 wxPoint2DDouble startWorld = (leftUp + rightDown) / 2.0;
1591
1592 if (hasSelectedElement) {
1593 for (auto& element : m_elementList) {
1594 if (element->IsSelected()) {
1595 element->StartMove(startWorld);
1596 element->Move(mouseWorld);
1597 auto childList = element->GetChildList();
1598 for (Element* child : childList) {
1599 if (auto line = dynamic_cast<ConnectionLine*>(child)) line->UpdatePoints();
1600 }
1601 }
1602 }
1603 }
1604 else {
1605 for (auto& line : m_connectionList) {
1606 if (line->IsSelected()) {
1607 line->StartMove(startWorld);
1608 line->Move(mouseWorld);
1609 }
1610 }
1611 }
1612 Redraw();
1613}

◆ OnNewClick()

void ControlEditor::OnNewClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1614 of file ControlEditor.cpp.

1615{
1616 wxMessageDialog msgDialog(this,
1617 _("Do you want to create a new control system?\n\nAll elements will be removed."),
1618 _("Warning"),
1619 wxYES_NO | wxCENTRE | wxICON_WARNING);
1620 if (msgDialog.ShowModal() != wxID_YES) return;
1621
1622 m_elementList.clear();
1623 m_connectionList.clear();
1624 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
1625 m_mode = ControlEditorMode::MODE_EDIT;
1626 ClearStates();
1627 SaveCurrentState();
1628 Redraw();
1629}

◆ OnPaint()

void ControlEditor::OnPaint ( wxPaintEvent &  event)
virtual

Definition at line 485 of file ControlEditor.cpp.

486{
487 wxBufferedPaintDC dc(m_cePanel);
488 dc.Clear();
489 wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
490
491 // Draw
492 if (gc) {
493
494 gc->Scale(m_camera->GetScale(), m_camera->GetScale());
495 gc->Translate(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y);
496
497 for (auto line : m_connectionList) {
498 //ConnectionLine* line = *it;
499 line->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), gc);
500 }
501
502 for (auto element : m_elementList) {
503
504 element->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), gc);
505 }
506
507 // Selection rectangle
508 gc->SetPen(wxPen(m_properties->GetGUIColour()->selection));
509 gc->SetBrush(wxBrush(m_properties->GetGUIColour()->selection));
510 gc->DrawRectangle(m_selectionRect.m_x, m_selectionRect.m_y, m_selectionRect.m_width, m_selectionRect.m_height);
511
512 delete gc;
513 }
514 event.Skip();
515}

◆ OnPasteClick()

void ControlEditor::OnPasteClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1630 of file ControlEditor.cpp.

1631{
1632 PasteFromClipboard();
1633}

◆ OnRedoClick()

void ControlEditor::OnRedoClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1634 of file ControlEditor.cpp.

1635{
1636 SetNextState();
1637}

◆ OnScroll()

void ControlEditor::OnScroll ( wxMouseEvent &  event)
virtual

Definition at line 846 of file ControlEditor.cpp.

847{
848 if (event.GetWheelRotation() > 0)
849 m_camera->SetScale(event.GetPosition(), +0.05);
850 else
851 m_camera->SetScale(event.GetPosition(), -0.05);
852
853 Redraw();
854}

◆ OnTestClick()

void ControlEditor::OnTestClick ( wxCommandEvent &  event)
virtual

Definition at line 1070 of file ControlEditor.cpp.

1071{
1072 // Reset colour list position for the test plot.
1073 m_itColourList = --m_colourList.end();
1074
1075 std::vector<IOControl*> ioList;
1076
1077 for (auto& element : m_elementList) {
1078 if (auto io = dynamic_cast<IOControl*>(element.get())) {
1079 ioList.push_back(io);
1080 }
1081 }
1082
1083 ControlSystemTest csTest(this, ioList, &m_inputType, &m_startTime, &m_slope, &m_timeStep, &m_simTime);
1084 if (csTest.ShowModal() == wxID_OK) {
1085 double printStep = 1e-3;
1086 double pdbStep = 1e-1;
1087
1088 struct InputData {
1089 wxString name;
1090 std::vector<double> values;
1091 };
1092
1093 std::vector<InputData> inputList;
1094
1095 // Store real flags for restoring after the test and set initial value.
1096 std::vector<IOControl::IOFlags> realFlagValue;
1097 for (auto* io : ioList) {
1098 realFlagValue.push_back(io->GetValue());
1099 if (io->GetType() == Node::NodeType::NODE_OUT) {
1100 SimTestData testData = io->GetSimTestData();
1101 io->SetValue(IOControl::IN_TEST);
1102 io->SetTestValue(testData.initialValue);
1103 inputList.push_back({ io->GetName(), {} });
1104 }
1105 }
1106
1107 wxProgressDialog pbd(_("Test"), _("Initializing..."), 100, this,
1108 wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH);
1109 ControlElementSolver solver(this, m_timeStep, 1e-5);
1110 solver.InitializeValues(false);
1111 if (solver.IsOK()) {
1112 bool simStopped = false;
1113 double currentTime = 0.0;
1114 double printTime = 0.0;
1115 double pdbTime = 0.0;
1116 std::vector<double> time;
1117 std::vector<double> solution;
1118
1119 while (currentTime <= m_simTime) {
1120 for (auto* io : ioList) {
1121 SimTestData testData = io->GetSimTestData();
1122 if (currentTime >= testData.startTime) {
1123 switch (testData.type) {
1124 case 0: {
1125 io->SetTestValue(testData.slope);
1126 } break;
1127 case 1: {
1128 io->SetTestValue(testData.slope * (currentTime - testData.startTime));
1129 } break;
1130 case 2: {
1131 io->SetTestValue(testData.slope * std::pow(currentTime - testData.startTime, 2));
1132 } break;
1133 default: {
1134 io->SetTestValue(0.0);
1135 break;
1136 }
1137 }
1138 }
1139 }
1140
1141 solver.SetCurrentTime(currentTime);
1142 solver.SolveNextStep();
1143 if (!solver.IsOK()) {
1144 wxString msg = wxString::Format(_("Failed to solve the control system.\n%s"), solver.GetErrorMessage());
1145 wxMessageDialog msgDialog(this, msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1146 msgDialog.ShowModal();
1147 simStopped = true;
1148 currentTime = m_simTime;
1149 }
1150
1151 if (printTime >= printStep) {
1152 time.push_back(currentTime);
1153 solution.push_back(solver.GetLastSolution());
1154 //inputV.push_back(input);
1155 int i = 0;
1156 for (auto* io : ioList) {
1157 if (io->GetType() == Node::NodeType::NODE_OUT) {
1158 inputList[i].values.push_back(io->GetTestValue());
1159 i++;
1160 }
1161 }
1162 printTime = 0.0;
1163 }
1164
1165 if (pdbTime > pdbStep) {
1166 if (!pbd.Update((currentTime / m_simTime) * 100, wxString::Format("Time = %.2fs", currentTime))) {
1167 pbd.Update(100);
1168 simStopped = true;
1169 currentTime = m_simTime;
1170 }
1171 pdbTime = 0.0;
1172 }
1173
1174 printTime += m_timeStep;
1175 currentTime += m_timeStep;
1176 pdbTime += m_timeStep;
1177 }
1178
1179 if (!simStopped) {
1180 std::vector<ElementPlotData> epdList;
1181 ElementPlotData curveData(_("I/O"), ElementPlotData::CurveType::CT_TEST);
1182 int i = 0;
1183 for (const auto& input : inputList) {
1184 curveData.AddData(input.values, input.name);
1185 curveData.SetPlot(i);
1186 curveData.SetColour(i, GetNextColour());
1187 i++;
1188 }
1189 //curveData.AddData(inputV, _("Input"));
1190 curveData.AddData(solution, _("Output"));
1191 curveData.SetPlot(i);
1192 curveData.SetColour(i, GetNextColour());
1193
1194 //curveData.SetPlot(0);
1195 //curveData.SetColour(0, *wxRED);
1196 //curveData.SetPlot(1);
1197 //curveData.SetColour(1, *wxBLUE);
1198
1199 epdList.push_back(curveData);
1200
1201 ChartView* cView = new ChartView(this, epdList, time, static_cast<PlotLib>(m_plotLib));
1202 cView->Show();
1203 cView->UpdatePlot();
1204 }
1205 }
1206 else {
1207 wxMessageDialog msgDialog(
1208 this,
1209 wxString::Format(_("Failed to solve the control system.\n%s"), solver.GetErrorMessage()),
1210 _("Error"),
1211 wxOK | wxCENTRE | wxICON_ERROR
1212 );
1213
1214 msgDialog.ShowModal();
1215 }
1216
1217 // Restore real flags.
1218 for (size_t i = 0; i < ioList.size(); i++) {
1219 if (ioList[i]->GetType() == Node::NodeType::NODE_OUT)
1220 ioList[i]->SetValue(realFlagValue[i]);
1221 }
1222 }
1223}
This class is responsible to manage the charts generated in the transient electromechanical studies.
Definition ChartView.h:49
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
Form to edit properties to test the control system created.
Provides the communication with the power element.
Definition IOControl.h:43

◆ OnUndoClick()

void ControlEditor::OnUndoClick ( wxCommandEvent &  event)
protectedvirtual

Definition at line 1638 of file ControlEditor.cpp.

1639{
1640 SetPreviousState();
1641}

◆ PasteFromClipboard()

bool ControlEditor::PasteFromClipboard ( )
protected

Definition at line 1424 of file ControlEditor.cpp.

1425{
1426 if (!wxTheClipboard->Open()) {
1427 wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
1428 wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
1429 dialog.ShowModal();
1430 return false;
1431 }
1432
1433 ControlElementDataObject dataObject;
1434 if (!wxTheClipboard->IsSupported(dataObject.GetFormat())) {
1435 wxTheClipboard->Close();
1436 return false;
1437 }
1438 if (!wxTheClipboard->GetData(dataObject)) {
1439 wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
1440 wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
1441 dialog.ShowModal();
1442 wxTheClipboard->Close();
1443 return false;
1444 }
1445 wxTheClipboard->Close();
1446
1447 auto* lists = dataObject.GetElementsLists();
1448 if (!lists) return false;
1449
1450 // Deep copy again (clipboard payload must remain immutable)
1451 std::vector<std::shared_ptr<ControlElement>> pastedElements;
1452 std::vector<std::shared_ptr<ConnectionLine>> pastedLines;
1453 ControlElementContainer container;
1454 container.FillContainer(lists->elementList, lists->connectionList);
1455 container.GetContainerCopy(pastedElements, pastedLines);
1456 SanitizeControlGraph(pastedElements, pastedLines);
1457
1458 if (pastedElements.empty() && pastedLines.empty()) return false;
1459
1460 UnselectAll();
1461
1462 // Assign new unique IDs
1463 for (auto& el : pastedElements) {
1464 el->SetID(GetNextID());
1465 el->SetSelected(true);
1466 }
1467 for (auto& ln : pastedLines) {
1468 ln->SetID(GetNextID());
1469 ln->SetSelected(true);
1470 }
1471
1472 // Insert
1473 for (auto& el : pastedElements) {
1474 el->SetFont(m_font);
1475 m_elementList.push_back(el);
1476 }
1477 for (auto& ln : pastedLines) {
1478 m_connectionList.push_back(ln);
1479 ln->UpdatePoints();
1480 }
1481
1482 // Move the pasted objects to the mouse position (center them at mouse, like Workspace).
1483 wxPoint2DDouble mouseWorld = GetEditorMouseWorldPoint();
1484
1485 std::vector<Element*> pastedAsElements;
1486 pastedAsElements.reserve(pastedElements.size() + pastedLines.size());
1487 for (auto& el : pastedElements) pastedAsElements.push_back(el.get());
1488 for (auto& ln : pastedLines) pastedAsElements.push_back(ln.get());
1489
1490 wxPoint2DDouble leftUpCorner, rightDownCorner;
1491 if (GetElementsCorners(leftUpCorner, rightDownCorner, pastedAsElements)) {
1492 wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0;
1493 for (auto& e : pastedElements) {
1494 e->StartMove(startPosition);
1495 e->Move(mouseWorld);
1496 }
1497 // Ensure lines follow moved elements; do not move lines directly to avoid offset corruption.
1498 for (auto& ln : pastedLines) ln->UpdatePoints();
1499 }
1500
1501 m_mode = ControlEditorMode::MODE_PASTE;
1502 Redraw();
1503 return true;
1504}

◆ Redraw()

virtual void ControlEditor::Redraw ( )
inlinevirtual

Definition at line 144 of file ControlEditor.h.

144{ m_cePanel->Refresh(); }

◆ RotateSelectedElements()

void ControlEditor::RotateSelectedElements ( bool  clockwise)
virtual

Definition at line 930 of file ControlEditor.cpp.

931{
932 for (auto& element : m_elementList) {
933 if (element->IsSelected()) {
934 element->Rotate(clockwise);
935 auto childList = element->GetChildList();
936 for (auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) {
937 ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
938 line->UpdatePoints();
939 }
940 }
941 }
942 Redraw();
943}

◆ SaveCurrentState()

void ControlEditor::SaveCurrentState ( )
protected

Definition at line 1309 of file ControlEditor.cpp.

1310{
1311 std::vector<std::shared_ptr<ControlElement>> stateElements;
1312 std::vector<std::shared_ptr<ConnectionLine>> stateLines;
1313
1314 // Deep copy via ControlElementContainer (same remapping logic used by generators).
1315 ControlElementContainer container;
1316 container.FillContainer(m_elementList, m_connectionList);
1317 container.GetContainerCopy(stateElements, stateLines);
1318
1319 // Drop redo states
1320 m_elementListState.resize(m_currentState + 1);
1321 m_connectionListState.resize(m_currentState + 1);
1322
1323 m_currentState++;
1324 if (m_currentState >= m_maxStates) {
1325 m_currentState = m_maxStates - 1;
1326 m_elementListState.erase(m_elementListState.begin());
1327 m_connectionListState.erase(m_connectionListState.begin());
1328 }
1329
1330 m_elementListState.emplace_back(std::move(stateElements));
1331 m_connectionListState.emplace_back(std::move(stateLines));
1332}

◆ SetConnectionsList()

virtual void ControlEditor::SetConnectionsList ( const std::vector< std::shared_ptr< ConnectionLine > > &  connectionList)
inlinevirtual

Definition at line 152 of file ControlEditor.h.

152{ m_connectionList = connectionList; }

◆ SetControlContainer()

virtual void ControlEditor::SetControlContainer ( ControlElementContainer ctrlContainer)
inlinevirtual

Definition at line 153 of file ControlEditor.h.

153{ m_ctrlContainer = ctrlContainer; }

◆ SetElementsList()

void ControlEditor::SetElementsList ( const std::vector< std::shared_ptr< ControlElement > > &  elementList)
virtual

Definition at line 1026 of file ControlEditor.cpp.

1027{
1028 m_elementList = elementList;
1029 for (auto& cElement : m_elementList)
1030 {
1031 cElement->SetFont(m_font);
1032 }
1033}

◆ SetJustOpened()

virtual void ControlEditor::SetJustOpened ( bool  justOpened)
inlinevirtual

Definition at line 145 of file ControlEditor.h.

145{ m_justOpened = justOpened; }

◆ SetManager()

virtual void ControlEditor::SetManager ( ControlEditorManager manager)
inlinevirtual

Definition at line 156 of file ControlEditor.h.

156{ m_ctrlManager = manager; }

◆ SetNextState()

void ControlEditor::SetNextState ( )
protected

Definition at line 1358 of file ControlEditor.cpp.

1359{
1360 m_currentState++;
1361 if (m_currentState < 0) m_currentState = 0;
1362 if (static_cast<size_t>(m_currentState) >= m_elementListState.size() ||
1363 static_cast<size_t>(m_currentState) >= m_connectionListState.size()) {
1364 m_currentState--;
1365 return;
1366 }
1367
1368 std::vector<std::shared_ptr<ControlElement>> newElements;
1369 std::vector<std::shared_ptr<ConnectionLine>> newLines;
1370 ControlElementContainer container;
1371 container.FillContainer(m_elementListState[m_currentState], m_connectionListState[m_currentState]);
1372 container.GetContainerCopy(newElements, newLines);
1373
1374 m_elementList = std::move(newElements);
1375 m_connectionList = std::move(newLines);
1376 ApplyFontToElements();
1377 Redraw();
1378}

◆ SetPlotLib()

virtual void ControlEditor::SetPlotLib ( int  plotLib)
inlinevirtual

Definition at line 155 of file ControlEditor.h.

155{ m_plotLib = plotLib; }

◆ SetPreviousState()

void ControlEditor::SetPreviousState ( )
protected

Definition at line 1334 of file ControlEditor.cpp.

1335{
1336 m_currentState--;
1337 if (m_currentState < 0) {
1338 m_currentState = 0;
1339 return;
1340 }
1341 if (static_cast<size_t>(m_currentState) >= m_elementListState.size() ||
1342 static_cast<size_t>(m_currentState) >= m_connectionListState.size()) {
1343 return;
1344 }
1345
1346 std::vector<std::shared_ptr<ControlElement>> newElements;
1347 std::vector<std::shared_ptr<ConnectionLine>> newLines;
1348 ControlElementContainer container;
1349 container.FillContainer(m_elementListState[m_currentState], m_connectionListState[m_currentState]);
1350 container.GetContainerCopy(newElements, newLines);
1351
1352 m_elementList = std::move(newElements);
1353 m_connectionList = std::move(newLines);
1354 ApplyFontToElements();
1355 Redraw();
1356}

◆ UnselectAll()

void ControlEditor::UnselectAll ( )
protected

Definition at line 1272 of file ControlEditor.cpp.

1273{
1274 for (auto& element : m_elementList) element->SetSelected(false);
1275 for (auto& line : m_connectionList) line->SetSelected(false);
1276}

Member Data Documentation

◆ m_camera

Camera* ControlEditor::m_camera = nullptr
protected

Definition at line 218 of file ControlEditor.h.

◆ m_colourList

std::vector<wxColour> ControlEditor::m_colourList
protected

Definition at line 246 of file ControlEditor.h.

◆ m_connectionList

std::vector< std::shared_ptr<ConnectionLine> > ControlEditor::m_connectionList
protected

Definition at line 231 of file ControlEditor.h.

◆ m_connectionListState

std::vector<std::vector<std::shared_ptr<ConnectionLine> > > ControlEditor::m_connectionListState
protected

Definition at line 251 of file ControlEditor.h.

◆ m_ctrlContainer

ControlElementContainer* ControlEditor::m_ctrlContainer = nullptr
protected

Definition at line 233 of file ControlEditor.h.

◆ m_ctrlManager

ControlEditorManager* ControlEditor::m_ctrlManager = nullptr
protected

Definition at line 234 of file ControlEditor.h.

◆ m_currentState

int ControlEditor::m_currentState = -1
protected

Definition at line 252 of file ControlEditor.h.

◆ m_elementList

std::vector< std::shared_ptr<ControlElement> > ControlEditor::m_elementList
protected

Definition at line 229 of file ControlEditor.h.

◆ m_elementListState

std::vector<std::vector<std::shared_ptr<ControlElement> > > ControlEditor::m_elementListState
protected

Definition at line 250 of file ControlEditor.h.

◆ m_font

wxFont ControlEditor::m_font
protected

Definition at line 221 of file ControlEditor.h.

◆ m_inputType

int ControlEditor::m_inputType = 0
protected

Definition at line 239 of file ControlEditor.h.

◆ m_ioFlags

int ControlEditor::m_ioFlags = 0
protected

Definition at line 237 of file ControlEditor.h.

◆ m_itColourList

std::vector<wxColour>::iterator ControlEditor::m_itColourList
protected

Definition at line 247 of file ControlEditor.h.

◆ m_justOpened

bool ControlEditor::m_justOpened = false
protected

Definition at line 236 of file ControlEditor.h.

◆ m_maxStates

int ControlEditor::m_maxStates = 100
protected

Definition at line 253 of file ControlEditor.h.

◆ m_mode

ControlEditorMode ControlEditor::m_mode = ControlEditorMode::MODE_EDIT
protected

Definition at line 223 of file ControlEditor.h.

◆ m_plotLib

int ControlEditor::m_plotLib = 0
protected

Definition at line 244 of file ControlEditor.h.

◆ m_properties

PropertiesData* ControlEditor::m_properties = nullptr
protected

Definition at line 220 of file ControlEditor.h.

◆ m_selectionRect

wxRect2DDouble ControlEditor::m_selectionRect
protected

Definition at line 225 of file ControlEditor.h.

◆ m_simTime

double ControlEditor::m_simTime = 10.0
protected

Definition at line 243 of file ControlEditor.h.

◆ m_slope

double ControlEditor::m_slope = 1.0
protected

Definition at line 241 of file ControlEditor.h.

◆ m_startSelRect

wxPoint2DDouble ControlEditor::m_startSelRect
protected

Definition at line 226 of file ControlEditor.h.

◆ m_startTime

double ControlEditor::m_startTime = 1.0
protected

Definition at line 240 of file ControlEditor.h.

◆ m_timeStep

double ControlEditor::m_timeStep = 1e-4
protected

Definition at line 242 of file ControlEditor.h.


The documentation for this class was generated from the following files: