/* * Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd. * * Author: zhaoyingzhen * * Maintainer: zhaoyingzhen * * This program 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 * any later version. * * This program 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 this program. If not, see . */ #include "devitemdelegate.h" #include #include #include #include #define RADIUS_VALUE 10 #define ITEM_SPACE 20 #define ICON_WIDTH 16 #define ICON_HEIGHT 16 #define TEXT_RECT_HEIGHT 20 #define ITEM_HEIGHT 36 #define INDICATOR_SHADOW_OFFSET 10 DevItemDelegate::DevItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { } void DevItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid()) return; painter->setRenderHint(QPainter::Antialiasing); QVariant var = index.data(StaticDataRole); DevItemData itemData = var.value(); QRect rect = option.rect; QPen pen; pen.setWidth(2); // 鼠标悬停 if (option.state.testFlag(QStyle::State_MouseOver)) { pen.setColor(QColor("#EBECED")); painter->setPen(pen); painter->setBrush(QColor("#EBECED")); painter->drawRoundedRect(rect, RADIUS_VALUE, RADIUS_VALUE); } // 选中背景(连接上和选中) int result = index.data(ResultDataRole).toInt(); if (option.state.testFlag(QStyle::State_Selected) && result == Connected) { pen.setColor(QColor("#0081FF")); painter->setPen(pen); painter->setBrush(QColor("#0081FF")); painter->drawRoundedRect(rect, RADIUS_VALUE, RADIUS_VALUE); } else { // 绘制默认背景 pen.setColor(QColor("#EBECED")); painter->setPen(pen); painter->setBrush(QColor("#EBECED")); painter->drawRoundedRect(rect, RADIUS_VALUE, RADIUS_VALUE); } bool selected = (option.state.testFlag(QStyle::State_Selected) && result == Connected); // 绘制Icon QString imagePath = selected ? itemData.checkedIconPath : itemData.iconPath; QRect iconRect = QRect(rect.left() + ITEM_SPACE, rect.top() + rect.height() / 2 - ICON_HEIGHT / 2, ICON_WIDTH, ICON_HEIGHT); painter->drawImage(iconRect, QImage(imagePath)); // 绘制text QFont font = Dtk::Widget::DFontSizeManager::instance()->t4(); painter->setFont(font); pen.setColor(selected ? Qt::white : Qt::black); painter->setPen(pen); int textRectWidth = rect.width() - ITEM_SPACE - iconRect.width() - iconRect.width() - ITEM_SPACE; QRect textRect = QRect(iconRect.right() + ITEM_SPACE, rect.top() + 2, textRectWidth, rect.height()); QFontMetrics fm(font); QString itemText = fm.elidedText(itemData.text, Qt::ElideRight, textRectWidth); painter->drawText(textRect, itemText); switch (result) { case ResultState::Connected: drawResultState(painter, rect); break; case ResultState::Connecting: drawWaitingState(painter, rect, index.data(DegreeDataRole).toInt()); break; default: break; } } QSize DevItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) return QSize(option.rect.width(), ITEM_HEIGHT); } void DevItemDelegate::drawWaitingState(QPainter *painter, const QRect &rect, int degree) const { int left = rect.width() - ITEM_SPACE; int top = rect.top() + rect.height() / 2 - ICON_HEIGHT / 2; QRect newRect(left, top, ICON_WIDTH, ICON_HEIGHT); painter->setRenderHint(QPainter::Antialiasing, true); QList> indicatorColors; for (int i = 0; i < 3; i++) indicatorColors << createDefaultIndicatorColorList(QColor("#0081FF")); double radius = 16 * 0.66; auto center = QRectF(newRect).center(); auto indicatorRadius = radius / 2 / 2 * 1.1; auto indicatorDegreeDelta = 360 / indicatorColors.count(); for (int i = 0; i < indicatorColors.count(); ++i) { QList colors = indicatorColors.value(i); for (int j = 0; j < colors.count(); ++j) { double degreeCurrent = degree - j * INDICATOR_SHADOW_OFFSET + indicatorDegreeDelta * i; auto x = (radius - indicatorRadius) * qCos(qDegreesToRadians(degreeCurrent)); auto y = (radius - indicatorRadius) * qSin(qDegreesToRadians(degreeCurrent)); x = center.x() + x; y = center.y() + y; auto tl = QPointF(x - 1 * indicatorRadius, y - 1 * indicatorRadius); QRectF rf(tl.x(), tl.y(), indicatorRadius * 2, indicatorRadius * 2); QPainterPath path; path.addEllipse(rf); painter->fillPath(path, colors.value(j)); } } } void DevItemDelegate::drawResultState(QPainter *painter, const QRect &rect) const { // 绘制对勾,14x12 int left = rect.width() - ITEM_SPACE; int top = rect.top() + rect.height() / 2 - 6; QPainterPath path; path.moveTo(left, top + 6); path.lineTo(left + 4, top + 11); path.lineTo(left + 12, top + 1); painter->drawPath(path); } QList DevItemDelegate::createDefaultIndicatorColorList(QColor color) const { QList colors; QList opacitys; opacitys << 100 << 30 << 15 << 10 << 5 << 4 << 3 << 2 << 1; for (int i = 0; i < opacitys.count(); ++i) { color.setAlpha(255 * opacitys.value(i) / 100); colors << color; } return colors; }