]> git.sur5r.net Git - minitube/blobdiff - src/segmentedcontrol.cpp
Upload 3.9.3-2 to unstable
[minitube] / src / segmentedcontrol.cpp
index a355152ef6a89c037ae85d70a4fe2ca52c7d3fb6..e763f12877da3ff73dc1699d1f33ebbd9401ee46 100644 (file)
@@ -19,108 +19,98 @@ 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"
-#include "fontutils.h"
-
-static const QColor borderColor = QColor(158, 157, 159);
-
-class SegmentedControl::Private {
-public:
-    QList<QAction *> actionList;
-    QAction *checkedAction;
-    QAction *hoveredAction;
-    QAction *pressedAction;
-};
-
-SegmentedControl::SegmentedControl (QWidget *parent)
-    : QWidget(parent), d(new SegmentedControl::Private) {
 
-    setFont(FontUtils::small());
+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, QColor(185, 183, 185));
-    linearGrad.setColorAt(1, QColor(176, 176, 178));
-    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();
 
@@ -131,18 +121,18 @@ 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();
     }
 }
 
@@ -150,126 +140,78 @@ void SegmentedControl::leaveEvent(QEvent *event) {
     QWidget::leaveEvent(event);
     // status tip
     MainWindow::instance()->statusBar()->clearMessage();
-    d->hoveredAction = 0;
-    d->pressedAction = 0;
+    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() 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) {
-    painter->setPen(QColor(0, 0, 0, 128));
-    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, QColor(212, 210, 212));
-    gradient.setColorAt(0, QColor(203, 203, 205));
-    painter->fillRect(0, 0, width, height, QBrush(gradient));
-
-    painter->restore();
-    painter->setPen(palette().windowText().color());
-    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();
 
-    painter->save();
-    painter->setPen(QPen(borderColor, 1.0 / qApp->devicePixelRatio()));
-#if defined(APP_MAC) | defined(APP_WIN)
-    painter->drawRect(-1, -1, width, height);
-#else
-    painter->drawRect(0, 0, width, height - 1);
-#endif
-    painter->restore();
+    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);
 
     const QString text = action->text();
 
-    // text shadow
-    /*
-    painter->setPen(QColor(0, 0, 0, 128));
-    painter->drawText(0, -1, width, height, Qt::AlignCenter, text);
-    */
-
+    painter->setPen(palette().windowText().color());
     painter->drawText(0, 0, width, height, Qt::AlignCenter, text);
 
     if (action->property("notifyCount").isValid()) {
-        QRect textBox = painter->boundingRect(rect,
-                                              Qt::AlignCenter,
-                                              text);
-        painter->translate((width + textBox.width()) / 2 + 10, (height - 20) / 2);
-        PainterUtils::paintBadge(painter, action->property("notifyCount").toString());
-    }
-
-    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, 32));
-        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(0x00, 0x00, 0x00, 0));
-        gradient.setColorAt(0, QColor(0x00, 0x00, 0x00, 16));
-        painter->fillRect(0, 0, width, height, QBrush(gradient));
+        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();