X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fsegmentedcontrol.cpp;h=e763f12877da3ff73dc1699d1f33ebbd9401ee46;hb=434d88418722fd7717038e44bd74271ca1d92771;hp=a896fbd0517f6af9d6405c8d103b08f8f6075cff;hpb=a8e005af0aa72f809f823bbd741bb3d0def00ced;p=minitube diff --git a/src/segmentedcontrol.cpp b/src/segmentedcontrol.cpp index a896fbd..e763f12 100644 --- a/src/segmentedcontrol.cpp +++ b/src/segmentedcontrol.cpp @@ -1,106 +1,116 @@ +/* $BEGIN_LICENSE + +This file is part of Minitube. +Copyright 2009, Flavio Tordini + +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 . + +$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 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(); @@ -111,135 +121,98 @@ void SegmentedControl::mouseMoveEvent (QMouseEvent *event) { 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(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(); } -