1 #include "segmentedcontrol.h"
4 static const QColor borderColor = QColor(0x26, 0x26, 0x26);
6 class SegmentedControl::Private {
8 QList<QAction *> actionList;
9 QAction *checkedAction;
10 QAction *hoveredAction;
11 QAction *pressedAction;
14 SegmentedControl::SegmentedControl (QWidget *parent)
15 : QWidget(parent), d(new SegmentedControl::Private) {
17 setMouseTracking(true);
24 SegmentedControl::~SegmentedControl() {
28 QAction *SegmentedControl::addAction(QAction *action) {
29 QWidget::addAction(action);
30 action->setCheckable(true);
31 d->actionList.append(action);
35 bool SegmentedControl::setCheckedAction(int index) {
40 QAction* newCheckedAction = d->actionList.at(index);
41 return setCheckedAction(newCheckedAction);
44 bool SegmentedControl::setCheckedAction(QAction *action) {
45 if (d->checkedAction == action) {
49 d->checkedAction->setChecked(false);
50 d->checkedAction = action;
51 d->checkedAction->setChecked(true);
56 QSize SegmentedControl::minimumSizeHint (void) const {
57 int itemsWidth = calculateButtonWidth() * d->actionList.size() * 1.2;
58 return(QSize(itemsWidth, QFontMetrics(font()).height() * 1.9));
61 void SegmentedControl::paintEvent (QPaintEvent * /*event*/) {
62 int height = rect().height();
63 int width = rect().width();
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));
72 // Calculate Buttons Size & Location
73 const int buttonWidth = width / d->actionList.size();
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);
81 if (i + 1 == actionCount) {
82 rect.setWidth(width - buttonWidth * (actionCount-1));
83 drawButton(&p, rect, action);
85 drawButton(&p, rect, action);
86 rect.moveLeft(rect.x() + rect.width());
93 void SegmentedControl::mouseMoveEvent (QMouseEvent *event) {
94 QWidget::mouseMoveEvent(event);
96 QAction *action = hoveredAction(event->pos());
98 if (!action && d->hoveredAction) {
101 } else if (action && action != d->hoveredAction) {
102 d->hoveredAction = action;
107 QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(window());
108 if (mainWindow) mainWindow->statusBar()->showMessage(action->statusTip());
112 void SegmentedControl::mousePressEvent(QMouseEvent *event) {
113 QWidget::mousePressEvent(event);
114 if (d->hoveredAction) {
115 d->pressedAction = d->hoveredAction;
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();
129 void SegmentedControl::leaveEvent(QEvent *event) {
130 QWidget::leaveEvent(event);
132 QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(window());
133 if (mainWindow) mainWindow->statusBar()->clearMessage();
134 d->hoveredAction = 0;
135 d->pressedAction = 0;
139 QAction *SegmentedControl::hoveredAction(const QPoint& pos) const {
140 if (pos.y() <= 0 || pos.y() >= height())
143 int buttonWidth = width() / d->actionList.size();
144 int buttonsWidth = width();
147 if (pos.x() <= buttonsX || pos.x() >= (buttonsX + buttonsWidth))
150 int buttonIndex = (pos.x() - buttonsX) / buttonWidth;
152 if (buttonIndex >= d->actionList.size())
154 return(d->actionList[buttonIndex]);
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;
168 void SegmentedControl::drawButton (QPainter *painter,
170 const QAction *action) {
171 if (action == d->checkedAction)
172 drawSelectedButton(painter, rect, action);
174 drawUnselectedButton(painter, rect, action);
177 void SegmentedControl::drawUnselectedButton (QPainter *painter,
179 const QAction *action) {
180 paintButton(painter, rect, action);
183 void SegmentedControl::drawSelectedButton (QPainter *painter,
185 const QAction *action) {
187 painter->translate(rect.topLeft());
189 const int width = rect.width();
190 const int height = rect.height();
191 const int hCenter = width * .5;
192 QRadialGradient gradient(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));
200 paintButton(painter, rect, action);
203 void SegmentedControl::paintButton(QPainter *painter, const QRect& rect, const QAction *action) {
205 painter->translate(rect.topLeft());
207 const int height = rect.height();
208 const int width = rect.width();
210 if (action == d->pressedAction && action != d->checkedAction) {
211 const int hCenter = width * .5;
212 QRadialGradient gradient(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,
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));
228 painter->setPen(borderColor);
229 #if defined(APP_MAC) | defined(APP_WIN)
230 painter->drawRect(-1, -1, width, height);
232 painter->drawRect(0, 0, width, height - 1);
235 painter->setFont(FontUtils::smallBold());
238 painter->setPen(QColor(0, 0, 0, 128));
239 painter->drawText(0, -1, width, height, Qt::AlignCenter, action->text());
241 painter->setPen(QPen(Qt::white, 1));
242 painter->drawText(0, 0, width, height, Qt::AlignCenter, action->text());