+/* $BEGIN_LICENSE
+
+This file is part of Minitube.
+Copyright 2009, Flavio Tordini <flavio.tordini@gmail.com>
+
+Minitube is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Minitube is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Minitube. If not, see <http://www.gnu.org/licenses/>.
+
+$END_LICENSE */
+
#include "segmentedcontrol.h"
#include "fontutils.h"
+#include "iconutils.h"
#include "mainwindow.h"
+#include "painterutils.h"
-static const QColor borderColor = QColor(0x26, 0x26, 0x26);
-
-class SegmentedControl::Private {
-public:
- QList<QAction *> actionList;
- QAction *checkedAction;
- QAction *hoveredAction;
- QAction *pressedAction;
-};
-
-SegmentedControl::SegmentedControl (QWidget *parent)
- : QWidget(parent), d(new SegmentedControl::Private) {
+SegmentedControl::SegmentedControl(QWidget *parent) : QWidget(parent) {
+ setAttribute(Qt::WA_OpaquePaintEvent);
setMouseTracking(true);
- d->hoveredAction = 0;
- d->checkedAction = 0;
- d->pressedAction = 0;
-}
+ hoveredAction = nullptr;
+ checkedAction = nullptr;
+ pressedAction = nullptr;
-SegmentedControl::~SegmentedControl() {
- delete d;
+ setupColors();
+ connect(qApp, &QGuiApplication::paletteChanged, this, [this] {
+ setupColors();
+ update();
+ });
}
QAction *SegmentedControl::addAction(QAction *action) {
QWidget::addAction(action);
action->setCheckable(true);
- d->actionList.append(action);
+ actionList.append(action);
return action;
}
bool SegmentedControl::setCheckedAction(int index) {
if (index < 0) {
- d->checkedAction = 0;
+ checkedAction = nullptr;
return true;
}
- QAction* newCheckedAction = d->actionList.at(index);
+ QAction *newCheckedAction = actionList.at(index);
return setCheckedAction(newCheckedAction);
}
bool SegmentedControl::setCheckedAction(QAction *action) {
- if (d->checkedAction == action) {
+ if (checkedAction == action) {
return false;
}
- if (d->checkedAction)
- d->checkedAction->setChecked(false);
- d->checkedAction = action;
- d->checkedAction->setChecked(true);
+ if (checkedAction) checkedAction->setChecked(false);
+ checkedAction = action;
+ checkedAction->setChecked(true);
update();
return true;
}
-QSize SegmentedControl::minimumSizeHint (void) const {
- int itemsWidth = calculateButtonWidth() * d->actionList.size() * 1.2;
- return(QSize(itemsWidth, QFontMetrics(font()).height() * 1.9));
+QSize SegmentedControl::minimumSizeHint() const {
+ int itemsWidth = calculateButtonWidth() * actionList.size() * 1.2;
+ return (QSize(itemsWidth, QFontMetrics(font()).height() * 1.8));
}
-void SegmentedControl::paintEvent (QPaintEvent * /*event*/) {
- int height = rect().height();
- int width = rect().width();
+void SegmentedControl::paintEvent(QPaintEvent * /*event*/) {
+ const int height = rect().height();
+ const int width = rect().width();
QPainter p(this);
- QLinearGradient linearGrad(rect().topLeft(), rect().bottomLeft());
- linearGrad.setColorAt(0, borderColor);
- linearGrad.setColorAt(1, QColor(0x3c, 0x3c, 0x3c));
- p.fillRect(rect(), QBrush(linearGrad));
-
// Calculate Buttons Size & Location
- const int buttonWidth = width / d->actionList.size();
+ const int buttonWidth = width / actionList.size();
+
+ const qreal pixelRatio = devicePixelRatioF();
+ QPen pen(borderColor);
+ const qreal penWidth = 1. / pixelRatio;
+ pen.setWidthF(penWidth);
+ p.setPen(pen);
// Draw Buttons
QRect rect(0, 0, buttonWidth, height);
- const int actionCount = d->actionList.size();
+ const int actionCount = actionList.size();
for (int i = 0; i < actionCount; i++) {
- QAction *action = d->actionList.at(i);
-
+ QAction *action = actionList.at(i);
if (i + 1 == actionCount) {
- rect.setWidth(width - buttonWidth * (actionCount-1));
- drawButton(&p, rect, action);
+ // last button
+ rect.setWidth(width - buttonWidth * (actionCount - 1));
+ paintButton(&p, rect, action);
} else {
- drawButton(&p, rect, action);
+ paintButton(&p, rect, action);
rect.moveLeft(rect.x() + rect.width());
}
-
}
-
}
-void SegmentedControl::mouseMoveEvent (QMouseEvent *event) {
- QWidget::mouseMoveEvent(event);
+void SegmentedControl::mouseMoveEvent(QMouseEvent *event) {
+ QAction *action = findHoveredAction(event->pos());
- QAction *action = hoveredAction(event->pos());
-
- if (!action && d->hoveredAction) {
- d->hoveredAction = 0;
+ if (!action && hoveredAction) {
+ hoveredAction = nullptr;
update();
- } else if (action && action != d->hoveredAction) {
- d->hoveredAction = action;
+ } else if (action && action != hoveredAction) {
+ hoveredAction = action;
action->hover();
update();
void SegmentedControl::mousePressEvent(QMouseEvent *event) {
QWidget::mousePressEvent(event);
- if (d->hoveredAction) {
- d->pressedAction = d->hoveredAction;
+ if (hoveredAction) {
+ pressedAction = hoveredAction;
update();
}
}
void SegmentedControl::mouseReleaseEvent(QMouseEvent *event) {
QWidget::mouseReleaseEvent(event);
- d->pressedAction = 0;
- if (d->hoveredAction) {
- bool changed = setCheckedAction(d->hoveredAction);
- if (changed) d->hoveredAction->trigger();
+ pressedAction = nullptr;
+ if (hoveredAction) {
+ bool changed = setCheckedAction(hoveredAction);
+ if (changed) hoveredAction->trigger();
}
}
void SegmentedControl::leaveEvent(QEvent *event) {
QWidget::leaveEvent(event);
// status tip
- // static_cast<QMainWindow*>(window())->statusBar()->clearMessage();
- d->hoveredAction = 0;
- d->pressedAction = 0;
+ MainWindow::instance()->statusBar()->clearMessage();
+ hoveredAction = nullptr;
+ pressedAction = nullptr;
update();
}
-QAction *SegmentedControl::hoveredAction(const QPoint& pos) const {
- if (pos.y() <= 0 || pos.y() >= height())
- return 0;
+void SegmentedControl::setupColors() {
+ selectedColor = palette().color(QPalette::Base);
+ if (selectedColor.value() > 128) {
+ int factor = 105;
+ backgroundColor = selectedColor.darker(factor);
+ borderColor = backgroundColor;
+ hoveredColor = backgroundColor.darker(factor);
+ pressedColor = hoveredColor.darker(factor);
+ } else {
+ int factor = 130;
+ backgroundColor = selectedColor.lighter(factor);
+ borderColor = backgroundColor;
+ hoveredColor = backgroundColor.lighter(factor);
+ pressedColor = hoveredColor.lighter(factor);
+ }
+}
- int buttonWidth = width() / d->actionList.size();
- int buttonsWidth = width();
- int buttonsX = 0;
+QAction *SegmentedControl::findHoveredAction(const QPoint &pos) const {
+ const int w = width();
+ if (pos.y() <= 0 || pos.x() >= w || pos.y() >= height()) return nullptr;
- if (pos.x() <= buttonsX || pos.x() >= (buttonsX + buttonsWidth))
- return 0;
+ int buttonWidth = w / actionList.size();
- int buttonIndex = (pos.x() - buttonsX) / buttonWidth;
+ int buttonIndex = pos.x() / buttonWidth;
- if (buttonIndex >= d->actionList.size())
- return 0;
- return(d->actionList[buttonIndex]);
+ if (buttonIndex >= actionList.size()) return nullptr;
+ return actionList[buttonIndex];
}
-int SegmentedControl::calculateButtonWidth (void) const {
- QFont smallerBoldFont = FontUtils::smallBold();
- QFontMetrics fontMetrics(smallerBoldFont);
+int SegmentedControl::calculateButtonWidth() const {
+ QFontMetrics fontMetrics(font());
int tmpItemWidth, itemWidth = 0;
- foreach (QAction *action, d->actionList) {
+ for (QAction *action : actionList) {
tmpItemWidth = fontMetrics.width(action->text());
if (itemWidth < tmpItemWidth) itemWidth = tmpItemWidth;
}
return itemWidth;
}
-void SegmentedControl::drawButton (QPainter *painter,
- const QRect& rect,
- const QAction *action) {
- if (action == d->checkedAction)
- drawSelectedButton(painter, rect, action);
- else
- drawUnselectedButton(painter, rect, action);
-}
-
-void SegmentedControl::drawUnselectedButton (QPainter *painter,
- const QRect& rect,
- const QAction *action) {
- paintButton(painter, rect, action);
-}
-
-void SegmentedControl::drawSelectedButton (QPainter *painter,
- const QRect& rect,
- const QAction *action) {
- painter->save();
- painter->translate(rect.topLeft());
-
- const int width = rect.width();
- const int height = rect.height();
- const int hCenter = width * .5;
- QRadialGradient gradient(hCenter, 0,
- width,
- hCenter, 0);
- gradient.setColorAt(1, Qt::black);
- gradient.setColorAt(0, QColor(0x33, 0x33, 0x33));
- painter->fillRect(0, 0, width, height, QBrush(gradient));
-
- painter->restore();
- paintButton(painter, rect, action);
-}
-
-void SegmentedControl::paintButton(QPainter *painter, const QRect& rect, const QAction *action) {
+void SegmentedControl::paintButton(QPainter *painter, const QRect &rect, const QAction *action) {
painter->save();
painter->translate(rect.topLeft());
const int height = rect.height();
const int width = rect.width();
- if (action == d->pressedAction && action != d->checkedAction) {
- const int hCenter = width * .5;
- QRadialGradient gradient(hCenter, 0,
- width,
- hCenter, 0);
- gradient.setColorAt(1, QColor(0x00, 0x00, 0x00, 0));
- gradient.setColorAt(0, QColor(0x00, 0x00, 0x00, 16));
- painter->fillRect(0, 0, width, height, QBrush(gradient));
- } else if (action == d->hoveredAction && action != d->checkedAction) {
- const int hCenter = width * .5;
- QRadialGradient gradient(hCenter, 0,
- width,
- hCenter, 0);
- gradient.setColorAt(1, QColor(0xff, 0xff, 0xff, 0));
- gradient.setColorAt(0, QColor(0xff, 0xff, 0xff, 16));
- painter->fillRect(0, 0, width, height, QBrush(gradient));
+ QColor c;
+ if (action == checkedAction) {
+ c = selectedColor;
+ } else if (action == pressedAction) {
+ c = pressedColor;
+ } else if (action == hoveredAction) {
+ c = hoveredColor;
+ } else {
+ c = backgroundColor;
}
+ painter->fillRect(0, 0, width, height, c);
- painter->setPen(borderColor);
-#if defined(APP_MAC) | defined(APP_WIN)
- painter->drawRect(-1, -1, width, height);
-#else
- painter->drawRect(0, 0, width, height - 1);
-#endif
-
- painter->setFont(FontUtils::smallBold());
+ const QString text = action->text();
- // text shadow
- painter->setPen(QColor(0, 0, 0, 128));
- painter->drawText(0, -1, width, height, Qt::AlignCenter, action->text());
+ painter->setPen(palette().windowText().color());
+ painter->drawText(0, 0, width, height, Qt::AlignCenter, text);
- painter->setPen(QPen(Qt::white, 1));
- painter->drawText(0, 0, width, height, Qt::AlignCenter, action->text());
+ if (action->property("notifyCount").isValid()) {
+ QRect textBox = painter->boundingRect(rect, Qt::AlignCenter, text);
+ painter->translate((width + textBox.width()) / 2 + 10, (height - textBox.height()) / 2);
+ PainterUtils::paintBadge(painter, action->property("notifyCount").toString(), false, c);
+ }
painter->restore();
}
-