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