]> git.sur5r.net Git - minitube/blob - src/segmentedcontrol.cpp
Imported Upstream version 2.0
[minitube] / src / segmentedcontrol.cpp
1 #include "segmentedcontrol.h"
2 #include "fontutils.h"
3 #include "mainwindow.h"
4
5 static const QColor borderColor = QColor(0x26, 0x26, 0x26);
6
7 class SegmentedControl::Private {
8 public:
9     QList<QAction *> actionList;
10     QAction *checkedAction;
11     QAction *hoveredAction;
12     QAction *pressedAction;
13 };
14
15 SegmentedControl::SegmentedControl (QWidget *parent)
16     : QWidget(parent), d(new SegmentedControl::Private) {
17
18     setMouseTracking(true);
19
20     d->hoveredAction = 0;
21     d->checkedAction = 0;
22     d->pressedAction = 0;
23 }
24
25 SegmentedControl::~SegmentedControl() {
26     delete d;
27 }
28
29 QAction *SegmentedControl::addAction(QAction *action) {
30     QWidget::addAction(action);
31     action->setCheckable(true);
32     d->actionList.append(action);
33     return action;
34 }
35
36 bool SegmentedControl::setCheckedAction(int index) {
37     if (index < 0) {
38         d->checkedAction = 0;
39         return true;
40     }
41     QAction* newCheckedAction = d->actionList.at(index);
42     return setCheckedAction(newCheckedAction);
43 }
44
45 bool SegmentedControl::setCheckedAction(QAction *action) {
46     if (d->checkedAction == action) {
47         return false;
48     }
49     if (d->checkedAction)
50         d->checkedAction->setChecked(false);
51     d->checkedAction = action;
52     d->checkedAction->setChecked(true);
53     update();
54     return true;
55 }
56
57 QSize SegmentedControl::minimumSizeHint (void) const {
58     int itemsWidth = calculateButtonWidth() * d->actionList.size() * 1.2;
59     return(QSize(itemsWidth, QFontMetrics(font()).height() * 1.9));
60 }
61
62 void SegmentedControl::paintEvent (QPaintEvent * /*event*/) {
63     int height = rect().height();
64     int width = rect().width();
65
66     QPainter p(this);
67
68     QLinearGradient linearGrad(rect().topLeft(), rect().bottomLeft());
69     linearGrad.setColorAt(0, borderColor);
70     linearGrad.setColorAt(1, QColor(0x3c, 0x3c, 0x3c));
71     p.fillRect(rect(), QBrush(linearGrad));
72
73     // Calculate Buttons Size & Location
74     const int buttonWidth = width / d->actionList.size();
75
76     // Draw Buttons
77     QRect rect(0, 0, buttonWidth, height);
78     const int actionCount = d->actionList.size();
79     for (int i = 0; i < actionCount; i++) {
80         QAction *action = d->actionList.at(i);
81
82         if (i + 1 == actionCount) {
83             rect.setWidth(width - buttonWidth * (actionCount-1));
84             drawButton(&p, rect, action);
85         } else {
86             drawButton(&p, rect, action);
87             rect.moveLeft(rect.x() + rect.width());
88         }
89
90     }
91
92 }
93
94 void SegmentedControl::mouseMoveEvent (QMouseEvent *event) {
95     QWidget::mouseMoveEvent(event);
96
97     QAction *action = hoveredAction(event->pos());
98
99     if (!action && d->hoveredAction) {
100         d->hoveredAction = 0;
101         update();
102     } else if (action && action != d->hoveredAction) {
103         d->hoveredAction = action;
104         action->hover();
105         update();
106
107         // status tip
108         MainWindow::instance()->statusBar()->showMessage(action->statusTip());
109     }
110 }
111
112 void SegmentedControl::mousePressEvent(QMouseEvent *event) {
113     QWidget::mousePressEvent(event);
114     if (d->hoveredAction) {
115         d->pressedAction = d->hoveredAction;
116         update();
117     }
118 }
119
120 void SegmentedControl::mouseReleaseEvent(QMouseEvent *event) {
121     QWidget::mouseReleaseEvent(event);
122     d->pressedAction = 0;
123     if (d->hoveredAction) {
124         bool changed = setCheckedAction(d->hoveredAction);
125         if (changed) d->hoveredAction->trigger();
126     }
127 }
128
129 void SegmentedControl::leaveEvent(QEvent *event) {
130     QWidget::leaveEvent(event);
131     // status tip
132     // static_cast<QMainWindow*>(window())->statusBar()->clearMessage();
133     d->hoveredAction = 0;
134     d->pressedAction = 0;
135     update();
136 }
137
138 QAction *SegmentedControl::hoveredAction(const QPoint& pos) const {
139     if (pos.y() <= 0 || pos.y() >= height())
140         return 0;
141
142     int buttonWidth = width() / d->actionList.size();
143     int buttonsWidth = width();
144     int buttonsX = 0;
145
146     if (pos.x() <= buttonsX || pos.x() >= (buttonsX + buttonsWidth))
147         return 0;
148
149     int buttonIndex = (pos.x() - buttonsX) / buttonWidth;
150
151     if (buttonIndex >= d->actionList.size())
152         return 0;
153     return(d->actionList[buttonIndex]);
154 }
155
156 int SegmentedControl::calculateButtonWidth (void) const {
157     QFont smallerBoldFont = FontUtils::smallBold();
158     QFontMetrics fontMetrics(smallerBoldFont);
159     int tmpItemWidth, itemWidth = 0;
160     foreach (QAction *action, d->actionList) {
161         tmpItemWidth = fontMetrics.width(action->text());
162         if (itemWidth < tmpItemWidth) itemWidth = tmpItemWidth;
163     }
164     return itemWidth;
165 }
166
167 void SegmentedControl::drawButton (QPainter *painter,
168                               const QRect& rect,
169                               const QAction *action) {
170     if (action == d->checkedAction)
171         drawSelectedButton(painter, rect, action);
172     else
173         drawUnselectedButton(painter, rect, action);
174 }
175
176 void SegmentedControl::drawUnselectedButton (QPainter *painter,
177                                         const QRect& rect,
178                                         const QAction *action) {
179     paintButton(painter, rect, action);
180 }
181
182 void SegmentedControl::drawSelectedButton (QPainter *painter,
183                                       const QRect& rect,
184                                       const QAction *action) {
185     painter->save();
186     painter->translate(rect.topLeft());
187
188     const int width = rect.width();
189     const int height = rect.height();
190     const int hCenter = width * .5;
191     QRadialGradient gradient(hCenter, 0,
192                              width,
193                              hCenter, 0);
194     gradient.setColorAt(1, Qt::black);
195     gradient.setColorAt(0, QColor(0x33, 0x33, 0x33));
196     painter->fillRect(0, 0, width, height, QBrush(gradient));
197
198     painter->restore();
199     paintButton(painter, rect, action);
200 }
201
202 void SegmentedControl::paintButton(QPainter *painter, const QRect& rect, const QAction *action) {
203     painter->save();
204     painter->translate(rect.topLeft());
205
206     const int height = rect.height();
207     const int width = rect.width();
208
209     if (action == d->pressedAction && action != d->checkedAction) {
210         const int hCenter = width * .5;
211         QRadialGradient gradient(hCenter, 0,
212                                  width,
213                                  hCenter, 0);
214         gradient.setColorAt(1, QColor(0x00, 0x00, 0x00, 0));
215         gradient.setColorAt(0, QColor(0x00, 0x00, 0x00, 16));
216         painter->fillRect(0, 0, width, height, QBrush(gradient));
217     } else if (action == d->hoveredAction && action != d->checkedAction) {
218         const int hCenter = width * .5;
219         QRadialGradient gradient(hCenter, 0,
220                                  width,
221                                  hCenter, 0);
222         gradient.setColorAt(1, QColor(0xff, 0xff, 0xff, 0));
223         gradient.setColorAt(0, QColor(0xff, 0xff, 0xff, 16));
224         painter->fillRect(0, 0, width, height, QBrush(gradient));
225     }
226
227     painter->setPen(borderColor);
228 #if defined(APP_MAC) | defined(APP_WIN)
229     painter->drawRect(-1, -1, width, height);
230 #else
231     painter->drawRect(0, 0, width, height - 1);
232 #endif
233
234     painter->setFont(FontUtils::smallBold());
235
236     // text shadow
237     painter->setPen(QColor(0, 0, 0, 128));
238     painter->drawText(0, -1, width, height, Qt::AlignCenter, action->text());
239
240     painter->setPen(QPen(Qt::white, 1));
241     painter->drawText(0, 0, width, height, Qt::AlignCenter, action->text());
242
243     painter->restore();
244 }
245