File indexing completed on 2024-05-19 04:59:21

0001 /* ============================================================
0002 * VerticalTabs plugin for Falkon
0003 * Copyright (C) 2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "tablistdelegate.h"
0019 #include "tablistview.h"
0020 #include "loadinganimator.h"
0021 
0022 #include "tabmodel.h"
0023 #include "tabicon.h"
0024 
0025 #include <QPainter>
0026 
0027 TabListDelegate::TabListDelegate(TabListView *view)
0028     : QStyledItemDelegate()
0029     , m_view(view)
0030 {
0031     m_padding = qMax(5, m_view->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1);
0032 
0033     m_loadingAnimator = new LoadingAnimator(this);
0034     connect(m_loadingAnimator, &LoadingAnimator::updateIndex, m_view, &TabListView::updateIndex);
0035 }
0036 
0037 QRect TabListDelegate::audioButtonRect(const QModelIndex &index) const
0038 {
0039     if (!index.data(TabModel::AudioPlayingRole).toBool() && !index.data(TabModel::AudioMutedRole).toBool()) {
0040         return QRect();
0041     }
0042     const QRect rect = m_view->visualRect(index);
0043     const int center = rect.height() / 2 + rect.top();
0044     return QRect(rect.right() - 16, center - 16 / 2, 16, 16);
0045 }
0046 
0047 void TabListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0048 {
0049     const QWidget *w = option.widget;
0050     const QStyle *style = w ? w->style() : m_view->style();
0051 
0052     QStyleOptionViewItem opt = option;
0053     initStyleOption(&opt, index);
0054     m_view->adjustStyleOption(&opt);
0055 
0056     const int height = opt.rect.height();
0057     const int center = height / 2 + opt.rect.top();
0058 
0059     painter->setRenderHint(QPainter::Antialiasing);
0060 
0061     // Draw background
0062     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
0063 
0064     // Draw icon
0065     const int iconSize = 16;
0066     const int iconYPos = center - (iconSize / 2);
0067     QRect iconRect(opt.rect.left() + (opt.rect.width() - iconSize) / 2, iconYPos, iconSize, iconSize);
0068     QPixmap pixmap;
0069     if (index.data(TabModel::LoadingRole).toBool()) {
0070         pixmap = m_loadingAnimator->pixmap(index);
0071     } else {
0072         pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize);
0073     }
0074     painter->drawPixmap(iconRect, pixmap);
0075 
0076     // Draw audio icon
0077     const bool audioMuted = index.data(TabModel::AudioMutedRole).toBool();
0078     const bool audioPlaying = index.data(TabModel::AudioPlayingRole).toBool();
0079     if (audioMuted || audioPlaying) {
0080         QSize audioSize(16, 16);
0081         QPoint pos(opt.rect.right() - audioSize.width(), center - audioSize.height() / 2);
0082         QRect audioRect(pos, audioSize);
0083 
0084         QColor c = opt.palette.color(QPalette::Window);
0085         c.setAlpha(180);
0086         painter->setPen(c);
0087         painter->setBrush(c);
0088         painter->drawEllipse(audioRect);
0089 
0090         painter->drawPixmap(audioRect, audioMuted ? TabIcon::data()->audioMutedPixmap : TabIcon::data()->audioPlayingPixmap);
0091     }
0092 
0093     // Draw background activity indicator
0094     const bool backgroundActivity = index.data(TabModel::BackgroundActivityRole).toBool();
0095     if (backgroundActivity) {
0096         QSize activitySize(7, 7);
0097         QPoint pos(iconRect.center().x() - activitySize.width() / 2 + 1, iconRect.bottom() - 2);
0098         QRect activityRect(pos, activitySize);
0099 
0100         QColor c1 = opt.palette.color(QPalette::Window);
0101         c1.setAlpha(180);
0102         painter->setPen(Qt::transparent);
0103         painter->setBrush(c1);
0104         painter->drawEllipse(activityRect);
0105 
0106         const QRect r2 = activityRect.adjusted(1, 1, -1, -1);
0107         painter->setPen(Qt::transparent);
0108         painter->setBrush(opt.palette.color(QPalette::Text));
0109         painter->drawEllipse(r2);
0110     }
0111 }
0112 
0113 QSize TabListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0114 {
0115     QStyleOptionViewItem opt(option);
0116     initStyleOption(&opt, index);
0117 
0118     return QSize(m_padding * 4 + 16, m_padding * 2 + opt.fontMetrics.height());
0119 }