summaryrefslogtreecommitdiffstats
path: root/Project/ControlElement.cpp
blob: d75c6061fe0ab44aa85338c801ae7b1234f8e152 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "ControlElement.h"

Node::Node(wxPoint2DDouble position, NodeType nodeType, double borderSize)
{
    double totalRadius = m_radius + borderSize;
    m_rect = wxRect2DDouble(position.m_x - totalRadius, position.m_y - totalRadius, totalRadius * 2, totalRadius * 2);
    m_nodeType = nodeType;

    m_triPts.push_back(GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, m_radius));
    m_triPts.push_back(GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, -m_radius));
    m_triPts.push_back(GetPosition() + wxPoint2DDouble(-m_radius + 1, 0));
}

Node::~Node() {}

void Node::SetPosition(wxPoint2DDouble position)
{
    m_rect = wxRect2DDouble(
        position.m_x - m_rect.m_width / 2, position.m_y - m_rect.m_height / 2, m_rect.m_width, m_rect.m_height);
    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)
{
    m_moveStartPt = 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); }

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);
}

bool Node::Contains(wxPoint2DDouble position) const
{
    if(m_connected) return false;
    return m_rect.Contains(position);
}

ControlElement::ControlElement(int id)
    : Element()
{
    m_elementID = id;
}

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());
        }
    }
}

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);
    }
}

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);
    }
}