targetselector.cpp 6.45 KB
Newer Older
1
2
#include "targetselector.h"

3
4
#include <utils/qtcassert.h>

5
6
7
8
9
10
11
12
13
14
15
16
#include <QtGui/QPainter>
#include <QtGui/QMouseEvent>
#include <QtGui/QFontMetrics>

static const int TARGET_WIDTH = 109;
static const int TARGET_HEIGHT = 43;
static const int ADDBUTTON_WIDTH = 27;

using namespace ProjectExplorer::Internal;

TargetSelector::TargetSelector(QWidget *parent) :
    QWidget(parent),
17
18
19
20
    m_unselected(QLatin1String(":/projectexplorer/images/targetunselected.png")),
    m_runselected(QLatin1String(":/projectexplorer/images/targetrunselected.png")),
    m_buildselected(QLatin1String(":/projectexplorer/images/targetbuildselected.png")),
    m_targetaddbutton(QLatin1String(":/projectexplorer/images/targetaddbutton.png")),
21
22
23
24
    m_targetremovebutton(QLatin1String(":/projectexplorer/images/targetremovebutton.png")),
    m_currentTargetIndex(-1),
    m_addButtonEnabled(true),
    m_removeButtonEnabled(false)
25
{
Tobias Hunger's avatar
Tobias Hunger committed
26
27
28
29
    QFont f = font();
    f.setPixelSize(10);
    f.setBold(true);
    setFont(f);
30
31
32
33
}

void TargetSelector::addTarget(const QString &name)
{
34
35
36
37
38
39
40
    insertTarget(m_targets.count(), name);
}

void TargetSelector::insertTarget(int index, const QString &name)
{
    QTC_ASSERT(index >= 0 && index <= m_targets.count(), return);

41
42
43
    Target target;
    target.name = name;
    target.currentSubIndex = 0;
Tobias Hunger's avatar
Tobias Hunger committed
44
    target.isActive = false;
45
46
47

    m_targets.insert(index, target);

48
    if (m_currentTargetIndex == -1)
49
        setCurrentIndex(index);
Tobias Hunger's avatar
Tobias Hunger committed
50
51
52
53
54
    update();
}

void TargetSelector::markActive(int index)
{
55
56
    QTC_ASSERT(index >= 0 && index < m_targets.count(), return);

Tobias Hunger's avatar
Tobias Hunger committed
57
58
    for (int i = 0; i < m_targets.count(); ++i)
        m_targets[i].isActive = (i == index);
59
60
61
62
63
    update();
}

void TargetSelector::removeTarget(int index)
{
64
65
    QTC_ASSERT(index >= 0 && index < m_targets.count(), return);

66
    m_targets.removeAt(index);
67
68
69
70
    if (m_currentTargetIndex > index)
        setCurrentIndex(m_currentTargetIndex - 1);
    if (m_currentTargetIndex == m_targets.count())
        setCurrentIndex(m_currentTargetIndex - 1);
Tobias Hunger's avatar
Tobias Hunger committed
71
72
73
74
75
76
77
78
79
80
    update();
}

void TargetSelector::setCurrentIndex(int index)
{
    if (index < -1 ||
        index >= m_targets.count() ||
        index == m_currentTargetIndex)
        return;

81
82
83
    if (index == -1 && !m_targets.isEmpty())
        return;

Tobias Hunger's avatar
Tobias Hunger committed
84
85
86
87
88
89
90
    m_currentTargetIndex = index;

    update();
    emit currentIndexChanged(m_currentTargetIndex,
                             m_currentTargetIndex >= 0 ? m_targets.at(m_currentTargetIndex).currentSubIndex : -1);
}

91
92
93
94
95
96
97
98
99
100
void TargetSelector::setAddButtonEnabled(bool enabled)
{
    m_addButtonEnabled = enabled;
}

void TargetSelector::setRemoveButtonEnabled(bool enabled)
{
    m_removeButtonEnabled = enabled;
}

Tobias Hunger's avatar
Tobias Hunger committed
101
102
103
104
void TargetSelector::setCurrentSubIndex(int subindex)
{
    if (subindex < 0 ||
        subindex >= 2 ||
105
        m_currentTargetIndex < 0 ||
Tobias Hunger's avatar
Tobias Hunger committed
106
107
108
109
        subindex == m_targets.at(m_currentTargetIndex).currentSubIndex)
        return;
    m_targets[m_currentTargetIndex].currentSubIndex = subindex;

110
    update();
Tobias Hunger's avatar
Tobias Hunger committed
111
112
    emit currentIndexChanged(m_currentTargetIndex,
                             m_targets.at(m_currentTargetIndex).currentSubIndex);
113
114
115
116
117
118
119
}

TargetSelector::Target TargetSelector::targetAt(int index) const
{
    return m_targets.at(index);
}

120
121
122
123
124
125
126
127
128
129
bool TargetSelector::isAddButtonEnabled() const
{
    return m_addButtonEnabled;
}

bool TargetSelector::isRemoveButtonEnabled() const
{
    return m_removeButtonEnabled;
}

130
131
QSize TargetSelector::minimumSizeHint() const
{
132
    return QSize((TARGET_WIDTH + 1) * m_targets.size() + (ADDBUTTON_WIDTH + 1) * 2 + 1, TARGET_HEIGHT + 2);
133
134
135
136
}

void TargetSelector::mousePressEvent(QMouseEvent *event)
{
137
138
139
140
141
    if (event->x() < ADDBUTTON_WIDTH) {
        event->accept();
        if (m_removeButtonEnabled)
            emit removeButtonClicked();
    } else if (event->x() > ADDBUTTON_WIDTH + (TARGET_WIDTH + 1) * m_targets.size()) {
142
143
        // check for add button
        event->accept();
144
145
        if (m_addButtonEnabled)
            emit addButtonClicked();
146
147
    } else {
        // find the clicked target button
148
        int x = ADDBUTTON_WIDTH;
149
150
151
152
153
154
155
156
157
158
159
160
        int index;
        for (index = 0; index < m_targets.size(); ++index) {
            if (event->x() <= x) {
                break;
            }
            x += TARGET_WIDTH + 1;
        }
        --index;
        if (index >= 0 && index < m_targets.size()) {
            // handle clicked target
            // check if user clicked on Build or Run
            if (event->y() > TARGET_HEIGHT * 3/5) {
161
                if ((event->x() - (ADDBUTTON_WIDTH + (TARGET_WIDTH + 1) * index)) - 2 > TARGET_WIDTH / 2) {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
                    m_targets[index].currentSubIndex = 1;
                } else {
                    m_targets[index].currentSubIndex = 0;
                }
            }
            m_currentTargetIndex = index;
            //TODO don't emit if nothing changed!
            update();
            emit currentIndexChanged(m_currentTargetIndex, m_targets.at(m_currentTargetIndex).currentSubIndex);
        } else {
            event->ignore();
        }
    }
}

void TargetSelector::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter p(this);
    p.setPen(QColor(89, 89, 89));
    QSize size = minimumSizeHint();
    //draw frame
    p.drawLine(1, 0, size.width() - 2, 0);
    p.drawLine(1, size.height() - 1, size.width() - 2, size.height() - 1);
    p.drawLine(0, 1, 0, size.height() - 2);
    p.drawLine(size.width() - 1, 1, size.width() - 1, size.height() - 2);
    //draw targets
    int x = 1;
    int index = 0;
    QFontMetrics fm(font());
193
194
195
196
197
    p.drawPixmap(x, 1, m_targetremovebutton);
    x += m_targetremovebutton.width();
    p.setPen(QColor(0, 0, 0));
    p.drawLine(x, 1, x, TARGET_HEIGHT);
    x += 1;
198
    foreach (const Target &target, m_targets) {
199
        const QPixmap *pixmap = &m_unselected;
200
201
202
        if (index == m_currentTargetIndex) {
            p.setPen(QColor(255, 255, 255));
            if (target.currentSubIndex == 0) {
203
                pixmap = &m_buildselected;
204
            } else {
205
                pixmap = &m_runselected;
206
207
208
209
210
            }
        } else {
            p.setPen(QColor(0, 0, 0));
        }
        p.drawPixmap(x, 1, *pixmap);
Tobias Hunger's avatar
Tobias Hunger committed
211
212
213
214
215
        QString targetName;
        if (target.isActive)
            targetName = QChar('*') + target.name + QChar('*');
        else
            targetName = target.name;
216
        p.drawText(x + (TARGET_WIDTH - fm.width(targetName))/2 + 1, 7 + fm.ascent(),
Tobias Hunger's avatar
Tobias Hunger committed
217
            targetName);
218
219
220
221
222
223
        x += TARGET_WIDTH;
        p.drawLine(x, 1, x, TARGET_HEIGHT);
        ++x;
        ++index;
    }
    // draw add button
224
    p.drawPixmap(x, 1, m_targetaddbutton);
225
}