diff options
author | Thales1330 <thaleslima.ufu@gmail.com> | 2017-03-03 18:50:40 -0300 |
---|---|---|
committer | Thales1330 <thaleslima.ufu@gmail.com> | 2017-03-03 18:50:40 -0300 |
commit | 4ddc7be64451db873e49169e951532ce8893e359 (patch) | |
tree | de034defff5a76a71249d53d8b0abb2a4eab17f9 | |
parent | a54f50d0bf86c7c4d400e8b4d30cbc6091cfd9df (diff) | |
download | PSP.git-4ddc7be64451db873e49169e951532ce8893e359.tar.gz PSP.git-4ddc7be64451db873e49169e951532ce8893e359.tar.xz PSP.git-4ddc7be64451db873e49169e951532ce8893e359.zip |
More connection line methods implemented
-rw-r--r-- | Project/ConnectionLine.cpp | 89 | ||||
-rw-r--r-- | Project/ConnectionLine.h | 13 | ||||
-rw-r--r-- | Project/ControlEditor.cpp | 124 | ||||
-rw-r--r-- | Project/ControlEditor.h | 6 | ||||
-rw-r--r-- | Project/ControlEditor.wxcp | 7 | ||||
-rw-r--r-- | Project/ControlEditorBase.cpp | 2 | ||||
-rw-r--r-- | Project/ControlEditorBase.h | 1 | ||||
-rw-r--r-- | Project/ControlElement.cpp | 59 | ||||
-rw-r--r-- | Project/ControlElement.h | 14 | ||||
-rw-r--r-- | Project/Element.h | 31 | ||||
-rw-r--r-- | Project/Project.mk | 2 | ||||
-rw-r--r-- | Project/TransferFunction.cpp | 44 | ||||
-rw-r--r-- | Project/TransferFunction.h | 1 | ||||
-rw-r--r-- | Project/Workspace.cpp | 2 |
14 files changed, 352 insertions, 43 deletions
diff --git a/Project/ConnectionLine.cpp b/Project/ConnectionLine.cpp index 68d893a..3cd6547 100644 --- a/Project/ConnectionLine.cpp +++ b/Project/ConnectionLine.cpp @@ -1,15 +1,31 @@ #include "ConnectionLine.h" -ConnectionLine::ConnectionLine() +ConnectionLine::ConnectionLine(Node* firstNode) : ControlElement() { + wxPoint2DDouble pt = firstNode->GetPosition(); + m_tmpSndPt = pt; + for(int i = 0; i < 6; i++) { + m_pointList.push_back(pt); + } + m_nodeList.push_back(firstNode); } ConnectionLine::~ConnectionLine() {} void ConnectionLine::Draw(wxPoint2DDouble translation, double scale) const { - + // Line selected (Layer 1). + if(m_selected) { + glLineWidth(1.5 + m_borderSize * 2.0); + glColor4dv(m_selectionColour.GetRGBA()); + DrawLine(m_pointList); + } + + // Draw line (Layer 2) + glLineWidth(1.5); + glColor4d(0.0, 0.0, 0.0, 1.0); + DrawLine(m_pointList); } bool ConnectionLine::Contains(wxPoint2DDouble position) const @@ -27,3 +43,72 @@ bool ConnectionLine::Intersects(wxRect2DDouble rect) const } return false; } + +void ConnectionLine::UpdatePoints() +{ + bool hasOneNode = true; + wxPoint2DDouble pt1 = m_nodeList[0]->GetPosition(); + wxPoint2DDouble pt2; + if(m_nodeList.size() == 1) + pt2 = m_tmpSndPt; + else { + pt2 = m_nodeList[1]->GetPosition(); + hasOneNode = false; + } + wxPoint2DDouble midPt = (pt1 + pt2) / 2.0 + wxPoint2DDouble(0.0, m_lineOffset); + + m_pointList[0] = pt1; + if(m_nodeList[0]->GetAngle() == 0.0) + m_pointList[1] = m_pointList[0] + wxPoint2DDouble(-10, 0); + else if(m_nodeList[0]->GetAngle() == 90.0) + m_pointList[1] = m_pointList[0] + wxPoint2DDouble(0, -10); + else if(m_nodeList[0]->GetAngle() == 180.0) + m_pointList[1] = m_pointList[0] + wxPoint2DDouble(10, 0); + else if(m_nodeList[0]->GetAngle() == 270.0) + m_pointList[1] = m_pointList[0] + wxPoint2DDouble(0, 10); + + m_pointList[2] = m_pointList[1] + wxPoint2DDouble(0.0, midPt.m_y - m_pointList[1].m_y); + + m_pointList[5] = pt2; + if(hasOneNode) + m_pointList[4] = pt2; + else { + if(m_nodeList[1]->GetAngle() == 0.0) + m_pointList[4] = m_pointList[5] + wxPoint2DDouble(-10, 0); + else if(m_nodeList[1]->GetAngle() == 90.0) + m_pointList[4] = m_pointList[5] + wxPoint2DDouble(0, -10); + else if(m_nodeList[1]->GetAngle() == 180.0) + m_pointList[4] = m_pointList[5] + wxPoint2DDouble(10, 0); + else if(m_nodeList[1]->GetAngle() == 270.0) + m_pointList[4] = m_pointList[5] + wxPoint2DDouble(0, 10); + } + + m_pointList[3] = m_pointList[4] + wxPoint2DDouble(0.0, midPt.m_y - m_pointList[4].m_y); +} + +bool ConnectionLine::AppendNode(Node* node, ControlElement* parent) +{ + if(m_nodeList.size() != 1) return false; + if(m_nodeList[0] == node) return false; + if(m_nodeList[0]->GetNodeType() == node->GetNodeType()) return false; + auto nodeList = parent->GetNodeList(); + for(auto it = nodeList.begin(), itEnd = nodeList.end(); it != itEnd; ++it) { + Node* parentNode = *it; + if(parentNode == m_nodeList[0]) return false; + } + + m_nodeList.push_back(node); + return true; +} + +void ConnectionLine::Move(wxPoint2DDouble position) +{ + m_lineOffset = m_moveStartOffset + position.m_y - m_moveStartPtY; + UpdatePoints(); +} + +void ConnectionLine::StartMove(wxPoint2DDouble position) +{ + m_moveStartPtY = position.m_y; + m_moveStartOffset = m_lineOffset; +} diff --git a/Project/ConnectionLine.h b/Project/ConnectionLine.h index 8249df8..cc7b51e 100644 --- a/Project/ConnectionLine.h +++ b/Project/ConnectionLine.h @@ -6,12 +6,23 @@ class ConnectionLine : public ControlElement { public: - ConnectionLine(); + ConnectionLine(Node* firstNode); ~ConnectionLine(); virtual void Draw(wxPoint2DDouble translation, double scale) const; virtual bool Contains(wxPoint2DDouble position) const; virtual bool Intersects(wxRect2DDouble rect) const; + virtual void StartMove(wxPoint2DDouble position); + virtual void Move(wxPoint2DDouble position); + virtual bool AppendNode(Node* node, ControlElement* parent); + virtual void UpdatePoints(); + virtual void SetTemporarySecondPoint(wxPoint2DDouble point) { m_tmpSndPt = point; }; + +protected: + double m_lineOffset = 0.0; + double m_moveStartPtY = 0.0; + double m_moveStartOffset = 0.0; + wxPoint2DDouble m_tmpSndPt; }; #endif // CONNECTIONLINE_H diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index cf79283..bfc81ad 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -3,6 +3,7 @@ #include "Camera.h" #include "ControlElement.h" #include "TransferFunction.h" +#include "ConnectionLine.h" ControlElementButton::ControlElementButton(wxWindow* parent, wxString label, wxImage image, wxWindowID id) : wxWindow(parent, id) @@ -235,6 +236,11 @@ void ControlEditor::OnPaint(wxPaintEvent& event) glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation + for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) { + ConnectionLine* line = *it; + line->Draw(m_camera->GetTranslation(), m_camera->GetScale()); + } + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) { Element* element = *it; element->Draw(m_camera->GetTranslation(), m_camera->GetScale()); @@ -293,11 +299,15 @@ void ControlEditor::OnLeftClickDown(wxMouseEvent& event) bool foundNode = false; auto nodeList = element->GetNodeList(); for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) { - Node node = *itN; - if(node.Contains(m_camera->ScreenToWorld(clickPoint))) { - wxLogMessage("Node click!"); - foundNode = true; + Node* node = *itN; + if(node->Contains(m_camera->ScreenToWorld(clickPoint))) { + m_mode = MODE_INSERT_LINE; + ConnectionLine* line = new ConnectionLine(node); + m_connectionList.push_back(line); + element->AddChild(line); + line->AddParent(element); foundElement = true; + foundNode = true; } } @@ -315,6 +325,17 @@ void ControlEditor::OnLeftClickDown(wxMouseEvent& event) } } } + if(m_mode != MODE_INSERT_LINE) { + for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) { + ConnectionLine* line = *it; + line->StartMove(m_camera->ScreenToWorld(clickPoint)); + if(line->Contains(m_camera->ScreenToWorld(clickPoint))) { + line->SetSelected(); + foundElement = true; + m_mode = MODE_MOVE_LINE; + } + } + } } if(!foundElement) { @@ -328,9 +349,25 @@ void ControlEditor::OnLeftClickDown(wxMouseEvent& event) void ControlEditor::OnLeftClickUp(wxMouseEvent& event) { + bool foundNode = false; for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) { - Element* element = *it; - if(m_mode == MODE_SELECTION_RECT) { + ControlElement* element = *it; + if(m_mode == MODE_INSERT_LINE) { + auto nodeList = element->GetNodeList(); + for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) { + Node* node = *itN; + if(node->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { + ConnectionLine* line = *(m_connectionList.end() - 1); + if(line->AppendNode(node, element)) { + line->AddParent(element); + element->AddChild(line); + line->UpdatePoints(); + m_mode = MODE_EDIT; + foundNode = true; + } + } + } + } else if(m_mode == MODE_SELECTION_RECT) { if(element->Intersects(m_selectionRect)) { element->SetSelected(); } else if(!event.ControlDown()) { @@ -342,9 +379,34 @@ void ControlEditor::OnLeftClickUp(wxMouseEvent& event) } } } + for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) { + ConnectionLine* line = *it; + if(m_mode == MODE_SELECTION_RECT) { + if(line->Intersects(m_selectionRect)) { + line->SetSelected(); + } else if(!event.ControlDown()) { + line->SetSelected(false); + } + } else if(!event.ControlDown()) { + if(!line->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { + line->SetSelected(false); + } + } + } m_selectionRect = wxRect2DDouble(0, 0, 0, 0); - if(m_mode != MODE_INSERT) { + + if(m_mode == MODE_INSERT_LINE && !foundNode) { + ConnectionLine* line = *(m_connectionList.end() - 1); + auto parentList = line->GetParentList(); + for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) { + Element* element = *it; + element->RemoveChild(line); + } + delete line; + m_connectionList.pop_back(); + m_mode = MODE_EDIT; + } else if(m_mode != MODE_INSERT) { m_mode = MODE_EDIT; } @@ -399,6 +461,12 @@ void ControlEditor::OnMouseMotion(wxMouseEvent& event) newElement->Move(m_camera->ScreenToWorld(clickPoint)); redraw = true; } break; + case MODE_INSERT_LINE: { + ConnectionLine* line = *(m_connectionList.end() - 1); + line->SetTemporarySecondPoint(m_camera->ScreenToWorld(clickPoint)); + line->UpdatePoints(); + redraw = true; + } break; case MODE_DRAG: case MODE_DRAG_INSERT: case MODE_DRAG_PASTE: { @@ -410,6 +478,20 @@ void ControlEditor::OnMouseMotion(wxMouseEvent& event) Element* element = *it; if(element->IsSelected()) { element->Move(m_camera->ScreenToWorld(clickPoint)); + auto childList = element->GetChildList(); + for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) { + ConnectionLine* line = static_cast<ConnectionLine*>(*itC); + line->UpdatePoints(); + } + redraw = true; + } + } + } break; + case MODE_MOVE_LINE: { + for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; it++) { + ConnectionLine* line = *it; + if(line->IsSelected()) { + line->Move(m_camera->ScreenToWorld(clickPoint)); redraw = true; } } @@ -464,3 +546,31 @@ void ControlEditor::OnIdle(wxIdleEvent& event) m_firstDraw = false; } } +void ControlEditor::OnKeyDown(wxKeyEvent& event) +{ + char key = event.GetUnicodeKey(); + if(key != WXK_NONE) { + switch(key) { + case 'R': // Rotate the selected elements. + { + RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT); + } break; + } + } +} + +void ControlEditor::RotateSelectedElements(bool clockwise) +{ + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) { + Element* element = *it; + if(element->IsSelected()) { + element->Rotate(clockwise); + auto childList = element->GetChildList(); + for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) { + ConnectionLine* line = static_cast<ConnectionLine*>(*itC); + line->UpdatePoints(); + } + } + } + Redraw(); +} diff --git a/Project/ControlEditor.h b/Project/ControlEditor.h index 92e1966..d4e99b7 100644 --- a/Project/ControlEditor.h +++ b/Project/ControlEditor.h @@ -12,6 +12,7 @@ class Camera; class ControlElement; class TransferFunction; +class ConnectionLine; enum ControlElementButtonID { ID_IO = 0, ID_TF, ID_SUM, ID_CONST, ID_LIMITER, ID_GAIN, ID_MULT, ID_SAT, ID_RATELIM }; @@ -49,9 +50,11 @@ public: enum ControlEditorMode { 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 @@ -61,8 +64,10 @@ public: virtual void AddElement(ControlElementButtonID id); virtual void Redraw() { m_glCanvas->Refresh(); } + virtual void RotateSelectedElements(bool clockwise); protected: + virtual void OnKeyDown(wxKeyEvent& event); virtual void OnIdle(wxIdleEvent& event); virtual void OnScroll(wxMouseEvent& event); virtual void OnDoubleClick(wxMouseEvent& event); @@ -86,6 +91,7 @@ protected: wxPoint2DDouble m_startSelRect; std::vector<ControlElement*> m_elementList; + std::vector<ConnectionLine*> m_connectionList; bool m_firstDraw = true; }; diff --git a/Project/ControlEditor.wxcp b/Project/ControlEditor.wxcp index c1e2d9b..d52e88e 100644 --- a/Project/ControlEditor.wxcp +++ b/Project/ControlEditor.wxcp @@ -1147,6 +1147,13 @@ "m_functionNameAndSignature": "OnIdle(wxIdleEvent& event)", "m_description": "Process a wxEVT_IDLE event", "m_noBody": false + }, { + "m_eventName": "wxEVT_KEY_DOWN", + "m_eventClass": "wxKeyEvent", + "m_eventHandler": "wxKeyEventHandler", + "m_functionNameAndSignature": "OnKeyDown(wxKeyEvent& event)", + "m_description": "Process a wxEVT_KEY_DOWN event (any key has been pressed)", + "m_noBody": false }], "m_children": [] }] diff --git a/Project/ControlEditorBase.cpp b/Project/ControlEditorBase.cpp index 87c1f98..5d350ca 100644 --- a/Project/ControlEditorBase.cpp +++ b/Project/ControlEditorBase.cpp @@ -140,6 +140,7 @@ ControlEditorBase::ControlEditorBase(wxWindow* parent, wxWindowID id, const wxSt m_glCanvas->Connect(wxEVT_MOTION, wxMouseEventHandler(ControlEditorBase::OnMouseMotion), NULL, this); m_glCanvas->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(ControlEditorBase::OnScroll), NULL, this); m_glCanvas->Connect(wxEVT_IDLE, wxIdleEventHandler(ControlEditorBase::OnIdle), NULL, this); + m_glCanvas->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(ControlEditorBase::OnKeyDown), NULL, this); } @@ -154,6 +155,7 @@ ControlEditorBase::~ControlEditorBase() m_glCanvas->Disconnect(wxEVT_MOTION, wxMouseEventHandler(ControlEditorBase::OnMouseMotion), NULL, this); m_glCanvas->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(ControlEditorBase::OnScroll), NULL, this); m_glCanvas->Disconnect(wxEVT_IDLE, wxIdleEventHandler(ControlEditorBase::OnIdle), NULL, this); + m_glCanvas->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(ControlEditorBase::OnKeyDown), NULL, this); m_auimgr->UnInit(); delete m_auimgr; diff --git a/Project/ControlEditorBase.h b/Project/ControlEditorBase.h index c4e846f..ecc655b 100644 --- a/Project/ControlEditorBase.h +++ b/Project/ControlEditorBase.h @@ -57,6 +57,7 @@ protected: virtual void OnMouseMotion(wxMouseEvent& event) { event.Skip(); } virtual void OnScroll(wxMouseEvent& event) { event.Skip(); } virtual void OnIdle(wxIdleEvent& event) { event.Skip(); } + virtual void OnKeyDown(wxKeyEvent& event) { event.Skip(); } public: wxToolBar* GetToolbarMain() { return m_toolbarMain; } diff --git a/Project/ControlElement.cpp b/Project/ControlElement.cpp index c7ce3c2..a1f2fc1 100644 --- a/Project/ControlElement.cpp +++ b/Project/ControlElement.cpp @@ -20,6 +20,9 @@ void Node::SetPosition(wxPoint2DDouble position) m_triPts[0] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, m_radius); m_triPts[1] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, -m_radius); m_triPts[2] = GetPosition() + wxPoint2DDouble(-m_radius + 1, 0); + + // Rotate according to the angle (node rect center as reference) + if(m_angle != 0.0) RotateTriPt(m_angle); } void Node::StartMove(wxPoint2DDouble position) @@ -28,16 +31,52 @@ void Node::StartMove(wxPoint2DDouble position) m_movePos = m_rect.GetPosition() - wxPoint2DDouble(-m_rect.m_width / 2, -m_rect.m_height / 2); } -void Node::Move(wxPoint2DDouble position) -{ - SetPosition(m_movePos + position - m_moveStartPt); -} +void Node::Move(wxPoint2DDouble position) { SetPosition(m_movePos + position - m_moveStartPt); } wxPoint2DDouble Node::GetPosition() const { return m_rect.GetPosition() + wxPoint2DDouble(m_rect.GetSize().GetWidth() / 2, m_rect.GetSize().GetHeight() / 2); } +void Node::RotateTriPt(double angle) +{ + double radAngle = wxDegToRad(angle); + wxPoint2DDouble rectCenter = + m_rect.GetPosition() + wxPoint2DDouble(m_rect.GetSize().GetWidth() / 2.0, m_rect.GetSize().GetHeight() / 2.0); + m_triPts[0] = wxPoint2DDouble(std::cos(radAngle) * (m_triPts[0].m_x - rectCenter.m_x) - + std::sin(radAngle) * (m_triPts[0].m_y - rectCenter.m_y) + rectCenter.m_x, + std::sin(radAngle) * (m_triPts[0].m_x - rectCenter.m_x) + + std::cos(radAngle) * (m_triPts[0].m_y - rectCenter.m_y) + rectCenter.m_y); + m_triPts[1] = wxPoint2DDouble(std::cos(radAngle) * (m_triPts[1].m_x - rectCenter.m_x) - + std::sin(radAngle) * (m_triPts[1].m_y - rectCenter.m_y) + rectCenter.m_x, + std::sin(radAngle) * (m_triPts[1].m_x - rectCenter.m_x) + + std::cos(radAngle) * (m_triPts[1].m_y - rectCenter.m_y) + rectCenter.m_y); + m_triPts[2] = wxPoint2DDouble(std::cos(radAngle) * (m_triPts[2].m_x - rectCenter.m_x) - + std::sin(radAngle) * (m_triPts[2].m_y - rectCenter.m_y) + rectCenter.m_x, + std::sin(radAngle) * (m_triPts[2].m_x - rectCenter.m_x) + + std::cos(radAngle) * (m_triPts[2].m_y - rectCenter.m_y) + rectCenter.m_y); +} + +void Node::Rotate(bool clockwise) +{ + if(clockwise) + m_angle += 90.0; + else + m_angle -= 90.0; + if(m_angle >= 360.0) + m_angle = 0.0; + else if(m_angle < 0) + m_angle = 270.0; + + // Update input triangle points. + m_triPts[0] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, m_radius); + m_triPts[1] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, -m_radius); + m_triPts[2] = GetPosition() + wxPoint2DDouble(-m_radius + 1, 0); + + // Rotate according to the angle (node rect center as reference) + if(m_angle != 0.0) RotateTriPt(m_angle); +} + ControlElement::ControlElement() : Element() { @@ -48,10 +87,10 @@ ControlElement::~ControlElement() {} void ControlElement::DrawNodes() const { for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) { - Node node = *it; - DrawCircle(node.GetPosition(), node.GetRadius(), 10, GL_POLYGON); - if(node.GetNodeType() == Node::NODE_IN) { - DrawTriangle(node.GetInTrianglePts()); + Node* node = *it; + DrawCircle(node->GetPosition(), node->GetRadius(), 10, GL_POLYGON); + if(node->GetNodeType() == Node::NODE_IN) { + DrawTriangle(node->GetInTrianglePts()); } } } @@ -61,7 +100,7 @@ void ControlElement::StartMove(wxPoint2DDouble position) m_moveStartPt = position; m_movePos = m_position; for(int i = 0; i < (int)m_nodeList.size(); ++i) { - m_nodeList[i].StartMove(position); + m_nodeList[i]->StartMove(position); } } @@ -69,6 +108,6 @@ void ControlElement::Move(wxPoint2DDouble position) { SetPosition(m_movePos + position - m_moveStartPt); for(int i = 0; i < (int)m_nodeList.size(); ++i) { - m_nodeList[i].Move(position); + m_nodeList[i]->Move(position); } } diff --git a/Project/ControlElement.h b/Project/ControlElement.h index 063b2a5..dedcc80 100644 --- a/Project/ControlElement.h +++ b/Project/ControlElement.h @@ -22,6 +22,13 @@ public: double GetRadius() const { return m_radius; } std::vector<wxPoint2DDouble> GetInTrianglePts() const { return m_triPts; } + + double GetAngle() const { return m_angle; } + void SetAngle(double angle) { m_angle = angle; } + + void Rotate(bool clockwise = true); + + void RotateTriPt(double angle); void StartMove(wxPoint2DDouble position); void Move(wxPoint2DDouble position); @@ -36,6 +43,7 @@ protected: double m_radius = 3.0; std::vector<wxPoint2DDouble> m_triPts; + double m_angle = 0.0; }; class ControlElement : public Element @@ -47,13 +55,13 @@ public: virtual void StartMove(wxPoint2DDouble position); virtual void Move(wxPoint2DDouble position); - void SetNodeList(std::vector<Node> nodeList) { m_nodeList = nodeList; } - std::vector<Node> GetNodeList() const { return m_nodeList; } + void SetNodeList(std::vector<Node*> nodeList) { m_nodeList = nodeList; } + std::vector<Node*> GetNodeList() const { return m_nodeList; } virtual void DrawNodes() const; protected: - std::vector<Node> m_nodeList; + std::vector<Node*> m_nodeList; }; #endif // CONTROLELEMENT_H diff --git a/Project/Element.h b/Project/Element.h index c2ce506..bd34f5c 100644 --- a/Project/Element.h +++ b/Project/Element.h @@ -225,14 +225,21 @@ public: virtual std::vector<wxPoint2DDouble> GetPointList() const { return m_pointList; } /** - * @brief Add a parent to the element. The parent must be a bus. The element basic points are calculated in this - * method, so apply this when the element is being inserted. + * @brief Add a parent to the element. This method must be used on power elements that connect to a bus, so the + * parent must be a bus. + * The element basic points are calculated in this method, so apply this when the element is being inserted. * @param parent Element parent. * @param position Node position in the parent. */ virtual bool AddParent(Element* parent, wxPoint2DDouble position) { return false; } /** + * @brief Add a parent to the element. + * @param parent Element parent. + */ + virtual void AddParent(Element* parent) { m_parentList.push_back(parent); } + + /** * @brief Checks if the element contains a position. * @param position Position to be checked. */ @@ -426,16 +433,16 @@ public: double scale, double offsetX = 0.0, double offsetY = 0.0) const; - virtual bool - /** - * @brief Check if two roteted rectangles intersect. - * @param rect1 First rect. - * @param rect2 Second rect. - * @param angle1 Rotation algle of first rectangle. - * @param angle2 Rotation angle of second rectangle. - */ - RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const; + /** + * @brief Check if two roteted rectangles intersect. + * @param rect1 First rect. + * @param rect2 Second rect. + * @param angle1 Rotation algle of first rectangle. + * @param angle2 Rotation angle of second rectangle. + */ + virtual bool + RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const; /** * @brief Draw a circle. @@ -563,7 +570,7 @@ public: * @param minDecimal Minimum number of decimal places. */ static wxString StringFromDouble(double value, int minDecimal = 1); - + /** * @brief Calculate the distance between a line (formed by point list) and a point. * @param point origin point. diff --git a/Project/Project.mk b/Project/Project.mk index 149318b..06bb923 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=Thales -Date :=23/02/2017 +Date :=03/03/2017 CodeLitePath :="C:/Program Files/CodeLite" LinkerName :=C:/TDM-GCC-64/bin/g++.exe SharedObjectLinkerName :=C:/TDM-GCC-64/bin/g++.exe -shared -fPIC diff --git a/Project/TransferFunction.cpp b/Project/TransferFunction.cpp index 74314a2..34d082c 100644 --- a/Project/TransferFunction.cpp +++ b/Project/TransferFunction.cpp @@ -22,10 +22,11 @@ TransferFunction::TransferFunction() m_denominator.push_back(1); UpdateTFText(); - Node node1(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize); - node1.StartMove(m_position); - Node node2(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize); - node2.StartMove(m_position); + Node* node1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize); + node1->StartMove(m_position); + Node* node2 = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize); + node2->SetAngle(180.0); + node2->StartMove(m_position); m_nodeList.push_back(node1); m_nodeList.push_back(node2); } @@ -190,8 +191,8 @@ void TransferFunction::UpdateTFText() GetTFString(num, den); SetText(num, den); if(m_nodeList.size() == 2) { - m_nodeList[0].SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0)); - m_nodeList[1].SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0)); + m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0)); + m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0)); } } @@ -205,3 +206,34 @@ bool TransferFunction::ShowForm(wxWindow* parent, Element* element) tfForm->Destroy(); return false; } + +void TransferFunction::Rotate(bool clockwise) +{ + if(clockwise) + m_angle += 90.0; + else + m_angle -= 90.0; + if(m_angle >= 360.0) + m_angle = 0.0; + else if(m_angle < 0) + m_angle = 270.0; + + if(m_angle == 0.0) { + m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0)); + m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0)); + } else if(m_angle == 90.0) { + m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2)); + m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2)); + } else if(m_angle == 180.0) { + m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0)); + m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0)); + } else if(m_angle == 270.0) { + m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2)); + m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2)); + } + + for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) { + Node* node = *it; + node->Rotate(clockwise); + } +} diff --git a/Project/TransferFunction.h b/Project/TransferFunction.h index d1d9529..34c23fc 100644 --- a/Project/TransferFunction.h +++ b/Project/TransferFunction.h @@ -18,6 +18,7 @@ public: virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); } virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); } virtual bool ShowForm(wxWindow* parent, Element* element); + virtual void Rotate(bool clockwise = true); virtual std::vector<double> GetNumerator() const { return m_numerator; } virtual std::vector<double> GetDenominator() const { return m_denominator; } diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp index 893f69c..f7bdf5f 100644 --- a/Project/Workspace.cpp +++ b/Project/Workspace.cpp @@ -655,7 +655,7 @@ void Workspace::OnKeyDown(wxKeyEvent& event) m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel.")); Redraw(); } - } + } break; case 'F': { if(event.GetModifiers() == wxMOD_SHIFT) { Fit(); |