3 This file is part of Minitube.
4 Copyright 2009, Flavio Tordini <flavio.tordini@gmail.com>
6 Minitube is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 Minitube is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Minitube. If not, see <http://www.gnu.org/licenses/>.
21 #include "segmentedcontrol.h"
22 #include "mainwindow.h"
23 #include "fontutils.h"
24 #include "iconutils.h"
25 #include "painterutils.h"
27 SegmentedControl::SegmentedControl (QWidget *parent) : QWidget(parent) {
28 setAttribute(Qt::WA_OpaquePaintEvent);
30 setMouseTracking(true);
37 selectedColor = palette().color(QPalette::Base);
39 selectedColor = palette().color(QPalette::Window);
41 int darkerFactor = 105;
42 backgroundColor = selectedColor.darker(darkerFactor);
43 borderColor = backgroundColor;
44 hoveredColor = backgroundColor.darker(darkerFactor);
45 pressedColor = hoveredColor.darker(darkerFactor);
48 QAction *SegmentedControl::addAction(QAction *action) {
49 QWidget::addAction(action);
50 action->setCheckable(true);
51 actionList.append(action);
55 bool SegmentedControl::setCheckedAction(int index) {
60 QAction* newCheckedAction = actionList.at(index);
61 return setCheckedAction(newCheckedAction);
64 bool SegmentedControl::setCheckedAction(QAction *action) {
65 if (checkedAction == action) {
69 checkedAction->setChecked(false);
70 checkedAction = action;
71 checkedAction->setChecked(true);
76 QSize SegmentedControl::minimumSizeHint (void) const {
77 int itemsWidth = calculateButtonWidth() * actionList.size() * 1.2;
78 return(QSize(itemsWidth, QFontMetrics(font()).height() * 1.8));
81 void SegmentedControl::paintEvent (QPaintEvent * /*event*/) {
82 const int height = rect().height();
83 const int width = rect().width();
87 // Calculate Buttons Size & Location
88 const int buttonWidth = width / actionList.size();
90 const qreal pixelRatio = IconUtils::pixelRatio();
92 QPen pen(borderColor);
93 const qreal penWidth = 1. / pixelRatio;
94 pen.setWidthF(penWidth);
98 QRect rect(0, 0, buttonWidth, height);
99 const int actionCount = actionList.size();
100 for (int i = 0; i < actionCount; i++) {
101 QAction *action = actionList.at(i);
102 if (i + 1 == actionCount) {
104 rect.setWidth(width - buttonWidth * (actionCount-1));
105 paintButton(&p, rect, action);
107 paintButton(&p, rect, action);
108 rect.moveLeft(rect.x() + rect.width());
111 const qreal y = height - penWidth;
112 p.drawLine(QPointF(0, y), QPointF(width, y));
115 void SegmentedControl::mouseMoveEvent (QMouseEvent *event) {
116 QAction *action = findHoveredAction(event->pos());
118 if (!action && hoveredAction) {
121 } else if (action && action != hoveredAction) {
122 hoveredAction = action;
127 MainWindow::instance()->statusBar()->showMessage(action->statusTip());
131 void SegmentedControl::mousePressEvent(QMouseEvent *event) {
132 QWidget::mousePressEvent(event);
134 pressedAction = hoveredAction;
139 void SegmentedControl::mouseReleaseEvent(QMouseEvent *event) {
140 QWidget::mouseReleaseEvent(event);
143 bool changed = setCheckedAction(hoveredAction);
144 if (changed) hoveredAction->trigger();
148 void SegmentedControl::leaveEvent(QEvent *event) {
149 QWidget::leaveEvent(event);
151 MainWindow::instance()->statusBar()->clearMessage();
157 QAction *SegmentedControl::findHoveredAction(const QPoint& pos) const {
158 const int w = width();
159 if (pos.y() <= 0 || pos.x() >= w || pos.y() >= height())
162 int buttonWidth = w / actionList.size();
164 int buttonIndex = pos.x() / buttonWidth;
166 if (buttonIndex >= actionList.size())
168 return actionList[buttonIndex];
171 int SegmentedControl::calculateButtonWidth() const {
172 QFontMetrics fontMetrics(font());
173 int tmpItemWidth, itemWidth = 0;
174 for (QAction *action : actionList) {
175 tmpItemWidth = fontMetrics.width(action->text());
176 if (itemWidth < tmpItemWidth) itemWidth = tmpItemWidth;
181 void SegmentedControl::paintButton(QPainter *painter, const QRect& rect, const QAction *action) {
183 painter->translate(rect.topLeft());
185 const int height = rect.height();
186 const int width = rect.width();
189 if (action == checkedAction) {
191 } else if (action == pressedAction) {
193 } else if (action == hoveredAction) {
198 painter->fillRect(0, 0, width, height, c);
200 const QString text = action->text();
202 painter->setPen(palette().windowText().color());
203 painter->drawText(0, 0, width, height, Qt::AlignCenter, text);
205 if (action->property("notifyCount").isValid()) {
206 QRect textBox = painter->boundingRect(rect,
209 painter->translate((width + textBox.width()) / 2 + 10, (height - textBox.height()) / 2);
210 PainterUtils::paintBadge(painter, action->property("notifyCount").toString(), false, QColor(0,0,0,64));