summaryrefslogtreecommitdiffstats
path: root/Project/Workspace.cpp
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2017-01-05 19:37:42 -0200
committerGitHub <noreply@github.com>2017-01-05 19:37:42 -0200
commit9df133274802731220546d1f9383c213193c8413 (patch)
tree9c6e2fa2a45d6c6c4c14d8711b2b89066bfb37d7 /Project/Workspace.cpp
parentc5343c718cf80620c2fc7452a4315f7ddb9e5826 (diff)
parentb6f96ca48bc156898df79deba63d270b393fb150 (diff)
downloadPSP.git-9df133274802731220546d1f9383c213193c8413.tar.gz
PSP.git-9df133274802731220546d1f9383c213193c8413.tar.xz
PSP.git-9df133274802731220546d1f9383c213193c8413.zip
Merge pull request #5 from Thales1330/opt/element-parent-search
Opt element parent search
Diffstat (limited to 'Project/Workspace.cpp')
-rw-r--r--Project/Workspace.cpp291
1 files changed, 213 insertions, 78 deletions
diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp
index 2894ed2..ef0a911 100644
--- a/Project/Workspace.cpp
+++ b/Project/Workspace.cpp
@@ -62,6 +62,7 @@ Workspace::Workspace()
Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar)
: WorkspaceBase(parent)
{
+ m_timer->Start();
m_name = name;
m_statusBar = statusBar;
m_glContext = new wxGLContext(m_glCanvas);
@@ -78,11 +79,15 @@ Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar)
Workspace::~Workspace()
{
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ if(*it) delete *it;
+ }
+ for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
if(*it) delete *it;
}
- m_elementList.clear();
if(m_camera) delete m_camera;
+ if(m_glContext) delete m_glContext;
+ if(m_tipWindow) delete m_tipWindow;
}
void Workspace::OnPaint(wxPaintEvent& event)
@@ -136,7 +141,7 @@ void Workspace::SetViewport()
glClearColor(1.0, 1.0, 1.0, 1.0); // White background.
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_2D);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -267,21 +272,23 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
bool elementIsBus = false;
Bus oldBus;
- if(typeid(*element) == typeid(Bus)) {
+ if(Bus* bus = dynamic_cast<Bus*>(element)) {
elementIsBus = true;
- oldBus = *(Bus*)element;
+ oldBus = *bus;
}
+ m_timer->Stop();
element->ShowForm(this, element);
elementEdited = true;
redraw = true;
- // If the edited element is a bus and was changed the nominal voltage, this voltage must be
+ // If the edited element is a bus and was changed the rated voltage, this voltage must be
// propagated through the lines
if(elementIsBus) {
// The voltage was changed
- if(oldBus.GetEletricalData().nominalVoltage != ((Bus*)element)->GetEletricalData().nominalVoltage ||
+ if(oldBus.GetEletricalData().nominalVoltage !=
+ static_cast<Bus*>(element)->GetEletricalData().nominalVoltage ||
oldBus.GetEletricalData().nominalVoltageUnit !=
- ((Bus*)element)->GetEletricalData().nominalVoltageUnit) {
+ static_cast<Bus*>(element)->GetEletricalData().nominalVoltageUnit) {
// Check if the lines has this bus as parent
for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
Element* child = *it;
@@ -321,13 +328,14 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
}
if(elementEdited) UpdateTextElements();
if(redraw) Redraw();
+ m_timer->Start();
}
void Workspace::OnRightClickDown(wxMouseEvent& event)
{
bool redraw = false;
if(m_mode == MODE_EDIT) {
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
if(element->IsSelected()) {
// Show context menu.
@@ -335,25 +343,27 @@ void Workspace::OnRightClickDown(wxMouseEvent& event)
element->ShowPickbox(false);
wxMenu menu;
if(element->GetContextMenu(menu)) {
+ m_timer->Stop();
menu.SetClientData(element);
menu.Connect(
wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(Workspace::OnPopupClick), NULL, this);
PopupMenu(&menu);
redraw = true;
+
+ if(!menu.GetClientData()) break;
}
element->ResetPickboxes();
- if(redraw) {
+ /*if(redraw) {
Redraw();
redraw = false;
- }
- // If the last element was removed using the menu, we must leave the "search for" to
- // prevent error.
- break;
+ }*/
}
}
}
}
+ if(redraw) Redraw();
+ m_timer->Start();
}
void Workspace::OnLeftClickUp(wxMouseEvent& event)
@@ -401,6 +411,7 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event)
Element* parent = m_elementList[i];
if(typeid(*parent) == typeid(Bus)) {
if(element->SetNodeParent(parent)) {
+ parent->AddChild(element);
findNewParent = true;
itnp = it;
element->ResetNodes();
@@ -537,24 +548,20 @@ void Workspace::OnMouseMotion(wxMouseEvent& event)
case MODE_MOVE_ELEMENT:
case MODE_PASTE: {
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
- // Parent's element moving...
- for(int i = 0; i < (int)element->GetParentList().size(); i++) {
- Element* parent = element->GetParentList()[i];
- if(parent) {
- if(parent->IsSelected()) {
- element->MoveNode(parent, m_camera->ScreenToWorld(event.GetPosition()));
- }
- }
- }
if(element->IsSelected()) {
element->Move(m_camera->ScreenToWorld(event.GetPosition()));
+ // Move child nodes
+ std::vector<Element*> childList = element->GetChildList();
+ for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
+ (*it)->MoveNode(element, m_camera->ScreenToWorld(event.GetPosition()));
+ }
redraw = true;
}
}
// Text element motion
- for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
+ for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
Text* text = *it;
if(text->IsSelected()) {
text->Move(m_camera->ScreenToWorld(event.GetPosition()));
@@ -589,6 +596,7 @@ void Workspace::OnMouseMotion(wxMouseEvent& event)
if(redraw) Redraw();
m_camera->UpdateMousePosition(event.GetPosition());
UpdateStatusBar();
+ m_timer->Start(); // Restart the timer.
event.Skip();
}
@@ -688,13 +696,13 @@ void Workspace::OnKeyDown(wxKeyEvent& event)
} break;
case 'L': {
if(!insertingElement) {
- if(event.GetModifiers() == wxMOD_SHIFT) { // Insert a load.
+ if(!event.ControlDown() && event.ShiftDown()) { // Insert a load.
Load* newLoad = new Load(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
IncrementElementNumber(ID_LOAD);
m_elementList.push_back(newLoad);
m_mode = MODE_INSERT;
m_statusBar->SetStatusText(_("Insert Load: Click on a buses, ESC to cancel."));
- } else { // Insert a power line.
+ } else if(!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
Line* newLine = new Line(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
IncrementElementNumber(ID_LINE);
m_elementList.push_back(newLine);
@@ -703,6 +711,21 @@ void Workspace::OnKeyDown(wxKeyEvent& event)
}
Redraw();
}
+ // Tests - Ctrl + Shift + L
+ if(event.ControlDown() && event.ShiftDown()) {
+ int numChild = 0;
+ int numParent = 0;
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ Element* element = *it;
+ if(element->Contains(m_camera->GetMousePosition())) {
+ for(int i = 0; i < (int)element->GetParentList().size(); i++) {
+ if(element->GetParentList()[i]) numParent++;
+ }
+ numChild = element->GetChildList().size();
+ }
+ }
+ wxMessageBox(wxString::Format("%d parents\n%d childs", numParent, numChild));
+ }
} break;
case 'T': // Insert a transformer.
{
@@ -828,25 +851,19 @@ void Workspace::UpdateStatusBar()
void Workspace::OnPopupClick(wxCommandEvent& event)
{
- wxMenu* menu = (wxMenu*)event.GetEventObject();
- Element* element = (Element*)menu->GetClientData();
+ wxMenu* menu = static_cast<wxMenu*>(event.GetEventObject());
+ Element* element = static_cast<Element*>(menu->GetClientData());
switch(event.GetId()) {
- case ID_EDIT_BUS: {
- wxMessageBox("Edit bus!");
- } break;
- case ID_EDIT_LINE: {
- wxMessageBox("Edit line!");
- } break;
- case ID_EDIT_TRANSFORMER: {
- wxMessageBox("Edit transformer!");
+ case ID_EDIT_ELEMENT: {
+ if(element->ShowForm(this, element)) UpdateTextElements();
} break;
case ID_LINE_ADD_NODE: {
- Line* line = (Line*)element;
+ Line* line = static_cast<Line*>(element);
line->AddNode(m_camera->GetMousePosition());
Redraw();
} break;
case ID_LINE_REMOVE_NODE: {
- Line* line = (Line*)element;
+ Line* line = static_cast<Line*>(element);
line->RemoveNode(m_camera->GetMousePosition());
Redraw();
} break;
@@ -879,21 +896,39 @@ void Workspace::OnPopupClick(wxCommandEvent& event)
Redraw();
} break;
case ID_DELETE: {
- for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* iElement = *it;
if(element == iElement) {
- for(auto itp = m_elementList.begin(); itp != m_elementList.end(); ++itp) {
- Element* child = *itp;
- // Parent's element being deleted...
- for(int i = 0; i < (int)child->GetParentList().size(); i++) {
- Element* parent = child->GetParentList()[i];
- if(parent == element) {
- child->RemoveParent(parent);
- }
+ // Remove child/parent.
+ std::vector<Element*> childList = element->GetChildList();
+ for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
+ Element* child = *itc;
+ if(child) {
+ child->RemoveParent(element);
+ element->RemoveChild(child);
+ }
+ }
+ std::vector<Element*> parentList = element->GetParentList();
+ for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
+ Element* parent = *itp;
+ if(parent) {
+ parent->RemoveChild(element);
}
}
- m_elementList.erase(it--);
+
+ for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
+ Text* text = *itt;
+ if(text->GetElement() == element) {
+ m_textList.erase(itt--);
+ if(text) delete text;
+ }
+ }
+
+ m_elementList.erase(it);
+ if(element) delete element;
+ menu->SetClientData(NULL);
+ break;
}
}
} break;
@@ -940,29 +975,43 @@ void Workspace::DeleteSelectedElements()
Element* element = *it;
if(element->IsSelected()) {
- for(auto itp = m_elementList.begin(); itp != m_elementList.end(); ++itp) {
- Element* child = *itp;
- // Parent's element being deleted...
- for(int i = 0; i < (int)child->GetParentList().size(); i++) {
- Element* parent = child->GetParentList()[i];
- if(parent == element) {
- child->RemoveParent(parent);
- }
+
+ // Remove child/parent.
+ std::vector<Element*> childList = element->GetChildList();
+ for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
+ Element* child = *itc;
+ if(child) {
+ child->RemoveParent(element);
+ element->RemoveChild(child);
+ }
+ }
+ std::vector<Element*> parentList = element->GetParentList();
+ for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
+ Element* parent = *itp;
+ if(parent) {
+ parent->RemoveChild(element);
}
}
for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
Text* text = *itt;
- if(text->GetElement() == element) m_textList.erase(itt--);
+ if(text->GetElement() == element) {
+ m_textList.erase(itt--);
+ if(text) delete text;
+ }
}
m_elementList.erase(it--);
+ if(element) delete element;
}
}
for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
Text* text = *it;
- if(text->IsSelected()) m_textList.erase(it--);
+ if(text->IsSelected()) {
+ m_textList.erase(it--);
+ if(text) delete text;
+ }
}
Redraw();
@@ -1019,16 +1068,16 @@ void Workspace::Fit()
void Workspace::ValidateBusesVoltages(Element* initialBus)
{
- double nominalVoltage = ((Bus*)initialBus)->GetEletricalData().nominalVoltage;
- ElectricalUnit nominalVoltageUnit = ((Bus*)initialBus)->GetEletricalData().nominalVoltageUnit;
+ double nominalVoltage = static_cast<Bus*>(initialBus)->GetEletricalData().nominalVoltage;
+ ElectricalUnit nominalVoltageUnit = static_cast<Bus*>(initialBus)->GetEletricalData().nominalVoltageUnit;
for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
Element* child = *it;
if(typeid(*child) == typeid(Line)) {
if(child->GetParentList()[0] && child->GetParentList()[1]) {
- BusElectricalData data1 = ((Bus*)child->GetParentList()[0])->GetEletricalData();
- BusElectricalData data2 = ((Bus*)child->GetParentList()[1])->GetEletricalData();
+ BusElectricalData data1 = static_cast<Bus*>(child->GetParentList()[0])->GetEletricalData();
+ BusElectricalData data2 = static_cast<Bus*>(child->GetParentList()[1])->GetEletricalData();
if(data1.nominalVoltage != data2.nominalVoltage ||
data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
@@ -1037,8 +1086,8 @@ void Workspace::ValidateBusesVoltages(Element* initialBus)
data1.nominalVoltageUnit = nominalVoltageUnit;
data2.nominalVoltageUnit = nominalVoltageUnit;
- ((Bus*)child->GetParentList()[0])->SetElectricalData(data1);
- ((Bus*)child->GetParentList()[1])->SetElectricalData(data2);
+ static_cast<Bus*>(child->GetParentList()[0])->SetElectricalData(data1);
+ static_cast<Bus*>(child->GetParentList()[1])->SetElectricalData(data2);
it = m_elementList.begin(); // Restart search.
}
@@ -1057,7 +1106,7 @@ void Workspace::ValidateElementsVoltages()
std::vector<double> nominalVoltage;
std::vector<ElectricalUnit> nominalVoltageUnit;
for(int i = 0; i < (int)child->GetParentList().size(); i++) {
- Bus* parent = (Bus*)child->GetParentList()[i];
+ Bus* parent = static_cast<Bus*>(child->GetParentList()[i]);
if(parent) {
nominalVoltage.push_back(parent->GetEletricalData().nominalVoltage);
nominalVoltageUnit.push_back(parent->GetEletricalData().nominalVoltageUnit);
@@ -1084,7 +1133,7 @@ bool Workspace::RunPowerFlow()
void Workspace::UpdateTextElements()
{
- for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
+ for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
Text* text = *it;
text->UpdateText(100e6);
}
@@ -1092,13 +1141,14 @@ void Workspace::UpdateTextElements()
void Workspace::CopySelection()
{
+ UpdateElementsID();
std::vector<Element*> selectedElements;
// The buses need to be numerated to associate the child's parents to the copies.
int busNumber = 0;
for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
Element* element = *it;
if(typeid(*element) == typeid(Bus)) {
- Bus* bus = (Bus*)element;
+ Bus* bus = static_cast<Bus*>(element);
auto data = bus->GetEletricalData();
data.number = busNumber;
bus->SetElectricalData(data);
@@ -1149,9 +1199,9 @@ bool Workspace::Paste()
for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
Element* copy = (*it)->GetCopy();
if(copy) {
- pastedElements.push_back((Bus*)copy);
- pastedBusList.push_back((Bus*)copy);
- m_elementList.push_back((Bus*)copy);
+ pastedElements.push_back(copy);
+ pastedBusList.push_back(static_cast<Bus*>(copy));
+ m_elementList.push_back(copy);
}
}
@@ -1161,8 +1211,7 @@ bool Workspace::Paste()
Element* copy = (*it)->GetCopy();
if(copy) {
// Check if is text element
- if(typeid(*copy) == typeid(Text)) {
- Text* text = (Text*)copy;
+ if(Text* text = dynamic_cast<Text*>(copy)) {
// Check if element associated with the text exists.
bool elementExist = false;
for(int i = 0; i < (int)m_elementList.size(); i++) {
@@ -1173,19 +1222,22 @@ bool Workspace::Paste()
}
if(elementExist) {
pastedElements.push_back(copy);
- m_textList.push_back((Text*)copy);
+ m_textList.push_back(text);
}
} else {
// Change the parent if copied, otherwise remove it.
for(int j = 0; j < (int)copy->GetParentList().size(); j++) {
- Bus* currentParent = (Bus*)copy->GetParentList()[j];
+ Bus* currentParent = static_cast<Bus*>(copy->GetParentList()[j]);
if(currentParent) {
- int parentNumber = currentParent->GetEletricalData().number;
+ int parentID = currentParent->GetID();
bool parentCopied = false;
for(int k = 0; k < (int)pastedBusList.size(); k++) {
Bus* newParent = pastedBusList[k];
- if(parentNumber == newParent->GetEletricalData().number)
+ if(parentID == newParent->GetID()) {
+ parentCopied = true;
copy->ReplaceParent(currentParent, newParent);
+ break;
+ }
}
if(!parentCopied) copy->RemoveParent(currentParent);
}
@@ -1197,6 +1249,26 @@ bool Workspace::Paste()
}
}
+ // Update buses childs
+ for(auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
+ Bus* bus = *it;
+ std::vector<Element*> childList = bus->GetChildList();
+ for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
+ Element* currentChild = *it;
+ int childID = currentChild->GetID();
+ bool childCopied = false;
+ for(int i = 0; i < (int)pastedElements.size(); i++) {
+ Element* newChild = pastedElements[i];
+ if(childID == newChild->GetID()) {
+ childCopied = true;
+ bus->ReplaceChild(currentChild, newChild);
+ break;
+ }
+ }
+ if(!childCopied) bus->RemoveChild(currentChild);
+ }
+ }
+
// Move elements (and nodes) to the mouse position.
// The start position it's the center of the pasted objects.
wxPoint2DDouble leftUpCorner, rightDownCorner;
@@ -1218,10 +1290,11 @@ bool Workspace::Paste()
return false;
}
- Redraw();
+ UpdateElementsID();
m_mode = MODE_PASTE;
m_statusBar->SetStatusText(_("Click to paste."));
UpdateStatusBar();
+ Redraw();
return true;
}
@@ -1236,3 +1309,65 @@ void Workspace::UnselectAll()
text->SetSelected(false);
}
}
+
+void Workspace::UpdateElementsID()
+{
+ int id = 0;
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ Element* element = *it;
+ element->SetID(id);
+ id++;
+ }
+ for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
+ Text* text = *it;
+ text->SetID(id);
+ id++;
+ }
+}
+void Workspace::OnTimer(wxTimerEvent& event)
+{
+ if(m_tipWindow) {
+ m_tipWindow->Close();
+ m_tipWindow = NULL;
+ }
+ if(m_mode == MODE_EDIT) {
+ for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
+ Element* element = *it;
+ if(element->Contains(m_camera->GetMousePosition())) {
+ wxString tipText = element->GetTipText();
+ if(!tipText.IsEmpty()) {
+ m_tipWindow = new wxTipWindow(this, tipText, 10000, &m_tipWindow);
+ // Creates a very tiny bounding rect to remove the tip on any mouse movement.
+ m_tipWindow->SetBoundingRect(wxRect(wxGetMousePosition(), wxSize(1, 1)));
+ break;
+ }
+ }
+ }
+ }
+
+ m_timer->Stop();
+}
+
+void Workspace::SetTextList(std::vector<Text*> textList)
+{
+ m_textList.clear();
+ for(auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
+
+ UpdateTextElements();
+}
+
+void Workspace::SetElementList(std::vector<Element*> elementList)
+{
+ m_elementList.clear();
+ for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) m_elementList.push_back(*it);
+}
+
+void Workspace::OnIdle(wxIdleEvent& event)
+{
+ // TODO: Find other solution to text displayed wrong on opened file.
+ if(m_justOpened) {
+ m_justOpened = false;
+ UpdateTextElements();
+ Redraw();
+ }
+}