File indexing completed on 2024-12-15 04:00:58

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "android_style.hpp"
0008 
0009 #include <QStyleOptionSlider>
0010 #include <QPainter>
0011 #include <QTextLayout>
0012 
0013 int glaxnimate::android::AndroidStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
0014 {
0015     switch ( metric )
0016     {
0017         case PM_SmallIconSize:
0018         case PM_LargeIconSize:
0019         case PM_IconViewIconSize:
0020         case PM_ListViewIconSize:
0021         case PM_IndicatorWidth:
0022         case PM_IndicatorHeight:
0023         case PM_ExclusiveIndicatorWidth:
0024         case PM_ExclusiveIndicatorHeight:
0025             return 80;
0026         default:
0027             return QProxyStyle::pixelMetric(metric, option, widget);
0028     }
0029 }
0030 
0031 QRect glaxnimate::android::AndroidStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const
0032 {
0033     auto rect = QProxyStyle::subControlRect(cc, opt, sc, widget);
0034 
0035     switch ( sc )
0036     {
0037         case SC_ScrollBarAddLine:
0038         {
0039             auto option = static_cast<const QStyleOptionSlider*>(opt);
0040             if ( option->orientation == Qt::Horizontal )
0041             {
0042                 return QRect(
0043                 option->rect.topRight() - QPoint(option->rect.height(), 0),
0044                 option->rect.bottomRight()
0045                 );
0046             }
0047             break;
0048         }
0049         case SC_ScrollBarSubLine:
0050         {
0051             auto option = static_cast<const QStyleOptionSlider*>(opt);
0052             if ( option->orientation == Qt::Horizontal )
0053             {
0054                 return QRect(
0055                 option->rect.topLeft(),
0056                 option->rect.bottomLeft() + QPoint(option->rect.height(), 0)
0057                 );
0058             }
0059             break;
0060         }
0061         case SC_ScrollBarGroove:
0062         {
0063             auto option = static_cast<const QStyleOptionSlider*>(opt);
0064             if ( option->orientation == Qt::Horizontal )
0065             {
0066                 return QRect(
0067                 option->rect.topLeft() + QPoint(option->rect.height(), 0),
0068                 option->rect.bottomRight() - QPoint(option->rect.height(), 0)
0069                 );
0070             }
0071             break;
0072         }
0073         case SC_ScrollBarSlider:
0074         {
0075             auto option = static_cast<const QStyleOptionSlider*>(opt);
0076             if ( option->minimum < option->maximum )
0077             {
0078                 qreal delta = option->maximum - option->minimum;
0079                 qreal factor = (option->sliderValue - option->minimum) / delta;
0080                 if ( option->orientation == Qt::Horizontal )
0081                 {
0082                     qreal avail = option->rect.width() - option->rect.height() * 3;
0083                     int x = qRound(factor * avail + option->rect.left() + option->rect.height());
0084 
0085                     return QRect(
0086                     QPoint(x, option->rect.top()),
0087                     QPoint(x+option->rect.height(), option->rect.bottom())
0088                     );
0089 
0090                 }
0091             }
0092             break;
0093         }
0094         default:
0095             break;
0096     }
0097 
0098     return rect;
0099 }
0100 
0101 QSize glaxnimate::android::AndroidStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
0102 {
0103     QSize sz = QProxyStyle::sizeFromContents(type, option, size, widget);
0104     if ( type == CT_ItemViewItem && size.isValid() )
0105     {
0106         if ( qstyleoption_cast<const QStyleOptionViewItem *>(option) )
0107             return sz.expandedTo({80, 80});
0108     }
0109 
0110     return sz;
0111 }
0112 
0113 QRect glaxnimate::android::AndroidStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
0114 {
0115     auto rect = QProxyStyle::subElementRect(element, option, widget);
0116     if ( element == SE_ItemViewItemDecoration )
0117         if ( qstyleoption_cast<const QStyleOptionViewItem *>(option) )
0118             return QRect(option->rect.topLeft(), QSize(80, 80));
0119     return rect;
0120 }
0121 
0122 void glaxnimate::android::AndroidStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *widget) const
0123 {
0124     if ( element != CE_ItemViewItem )
0125         return QProxyStyle::drawControl(element, opt, p, widget);
0126 
0127     const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
0128     if ( !vopt )
0129         return;
0130 
0131     QStyleOptionViewItem copy = *vopt;
0132     copy.decorationSize = QSize();
0133     copy.icon = {};
0134     QProxyStyle::drawControl(element, &copy, p, widget);
0135 
0136     if ( !vopt->icon.isNull() )
0137     {
0138         p->save();
0139         p->setClipRect(opt->rect);
0140         QRect iconRect = subElementRect(SE_ItemViewItemDecoration, vopt, widget);
0141         auto pix = vopt->icon.pixmap(iconRect.size());
0142         p->drawPixmap(iconRect, pix);
0143         p->restore();
0144     }
0145 }