summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Project/ConnectionLine.cpp89
-rw-r--r--Project/ConnectionLine.h13
-rw-r--r--Project/ControlEditor.cpp124
-rw-r--r--Project/ControlEditor.h6
-rw-r--r--Project/ControlEditor.wxcp7
-rw-r--r--Project/ControlEditorBase.cpp2
-rw-r--r--Project/ControlEditorBase.h1
-rw-r--r--Project/ControlElement.cpp59
-rw-r--r--Project/ControlElement.h14
-rw-r--r--Project/Element.h31
-rw-r--r--Project/Project.mk2
-rw-r--r--Project/TransferFunction.cpp44
-rw-r--r--Project/TransferFunction.h1
-rw-r--r--Project/Workspace.cpp2
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();