Files

283 lines
9.1 KiB
C++
Raw Permalink Normal View History

2021-11-22 20:09:49 +08:00
/*
* Copyright 2021 KylinSoft Co., Ltd.
*
* 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 2 of the License, or
* (at your option) 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
2020-10-20 17:24:46 +08:00
/* CloseButton by David Peng
* 2020 10.20
* Version Beta 1.0
* 介绍:该控件是用于对话框的关闭按钮,只需指定父对象即可可自动回收。
* 使用方法:
* 1、new CloseButton(this); //这样会直接调用主题的关闭按钮。
* 2、new CloseButton(黑色图标路径,this); //这样会用一个黑色的'X'图标SVG,hover时会渲染成白色。
* 3、new CloseButton(黑色图标路径,白色图标路径,this) //这样会用两张图片来实现图标显示。
*/
#include "closebutton.h"
#include <QApplication>
2020-10-21 09:32:52 +08:00
#include <QDebug>
2020-10-20 17:24:46 +08:00
2020-10-21 10:34:51 +08:00
#define THEME_QT_SCHEMA "org.ukui.style"
#define THEME_GTK_SCHEMA "org.mate.interface"
2020-10-20 17:24:46 +08:00
CloseButton::CloseButton(QWidget *parent, const QString &filePath, const QString &hoverPath) : QLabel(parent)
{
//Allocation
2020-10-21 10:34:51 +08:00
2020-10-20 17:24:46 +08:00
if(filePath != "" && filePath != "window-close-symbolic")
m_icon = new QIcon(filePath);
else if(filePath == "window-close-symbolic"){
QIcon icon = QIcon::fromTheme("window-close-symbolic");
m_icon = new QIcon(icon);
} else {
m_icon = nullptr;
}
if(hoverPath != "")
m_hoverIcon = new QIcon(hoverPath);
else
m_hoverIcon = nullptr;
//Properties
2020-10-21 09:32:52 +08:00
//setProperty("useIconHighlightEffect", true);
//setProperty("iconHighlightEffectMode", 1);
2020-10-20 17:24:46 +08:00
setFocusPolicy(Qt::NoFocus);
//Initial componentss
m_bIsChecked = false;
m_bIsPressed = false;
2020-10-20 18:06:52 +08:00
m_settedBkg = false;
m_szHoverIn = "white";
2020-10-21 10:34:51 +08:00
m_szHoverOut = "default";
2020-10-20 17:24:46 +08:00
m_cSize = 16;
m_colorBkg = palette().color(QPalette::Base);
setAlignment(Qt::AlignCenter);
if(m_icon != nullptr) {
2020-10-20 18:06:52 +08:00
setPixmap(renderSvg(*m_icon,m_szHoverOut));
2020-10-20 17:24:46 +08:00
}
2020-10-21 10:34:51 +08:00
if(QGSettings::isSchemaInstalled(THEME_GTK_SCHEMA) && QGSettings::isSchemaInstalled(THEME_QT_SCHEMA)) {
QByteArray qtThemeID(THEME_QT_SCHEMA);
QByteArray gtkThemeID(THEME_GTK_SCHEMA);
m_gtkThemeSetting = new QGSettings(gtkThemeID,QByteArray(),this);
m_qtThemeSetting = new QGSettings(qtThemeID,QByteArray(),this);
QString style = m_qtThemeSetting->get("styleName").toString();
2021-01-27 08:56:18 +08:00
if(style == "ukui-black" || style == "ukui-dark") {
2020-10-21 10:34:51 +08:00
m_szHoverOut = "white";
} else {
m_szHoverOut = "default";
}
connect(m_qtThemeSetting,&QGSettings::changed, [this] (const QString &key) {
QString style = m_qtThemeSetting->get("styleName").toString();
if(key == "styleName") {
2021-01-27 08:56:18 +08:00
if(style == "ukui-black" || style == "ukui-dark") {
2020-10-21 10:34:51 +08:00
m_szHoverOut = "white";
} else {
m_szHoverOut = "default";
}
}
});
}
2020-10-20 17:24:46 +08:00
}
const QPixmap CloseButton::renderSvg(const QIcon &icon, QString cgColor) {
int size = m_cSize;
const auto ratio = qApp->devicePixelRatio();
if ( 2 == ratio) {
2021-03-30 18:40:10 +08:00
size = m_cSize * 2;
2020-10-20 17:24:46 +08:00
} else if (3 == ratio) {
2021-03-30 18:40:10 +08:00
size = m_cSize * 3;
2020-10-20 17:24:46 +08:00
}
QPixmap iconPixmap = icon.pixmap(size,size);
iconPixmap.setDevicePixelRatio(ratio);
QImage img = iconPixmap.toImage();
for (int x = 0; x < img.width(); x++) {
for (int y = 0; y < img.height(); y++) {
auto color = img.pixelColor(x, y);
if (color.alpha() > 0) {
if ("white" == cgColor) {
color.setRed(255);
color.setGreen(255);
color.setBlue(255);
img.setPixelColor(x, y, color);
} else if ("black" == cgColor) {
color.setRed(0);
color.setGreen(0);
color.setBlue(0);
// color.setAlpha(0.1);
2020-10-21 10:34:51 +08:00
color.setAlphaF(0.12);
2020-10-20 17:24:46 +08:00
img.setPixelColor(x, y, color);
} else if ("gray" == cgColor) {
color.setRed(152);
color.setGreen(163);
color.setBlue(164);
img.setPixelColor(x, y, color);
} else if ("blue" == cgColor){
color.setRed(61);
color.setGreen(107);
color.setBlue(229);
img.setPixelColor(x, y, color);
} else {
return iconPixmap;
}
}
}
}
return QPixmap::fromImage(img);
}
QPixmap CloseButton::drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor)
{
QImage img = source.toImage();
for (int x = 0; x < img.width(); x++) {
for (int y = 0; y < img.height(); y++) {
auto color = img.pixelColor(x, y);
if (color.alpha() > 0) {
if ("white" == cgColor) {
color.setRed(255);
color.setGreen(255);
color.setBlue(255);
img.setPixelColor(x, y, color);
} else if ("black" == cgColor) {
color.setRed(0);
color.setGreen(0);
color.setBlue(0);
color.setAlphaF(0.9);
img.setPixelColor(x, y, color);
} else if ("gray" == cgColor) {
color.setRed(152);
color.setGreen(163);
color.setBlue(164);
img.setPixelColor(x, y, color);
} else if ("blue" == cgColor){
color.setRed(61);
color.setGreen(107);
color.setBlue(229);
img.setPixelColor(x, y, color);
} else {
return source;
}
}
}
}
return QPixmap::fromImage(img);
}
void CloseButton::enterEvent(QEvent *event) {
Q_UNUSED(event);
if(m_hoverIcon == nullptr && m_icon != nullptr)
2020-10-20 18:06:52 +08:00
setPixmap(renderSvg(*m_icon,m_szHoverIn));
2020-10-20 17:24:46 +08:00
else if(m_hoverIcon != nullptr && m_icon != nullptr)
setPixmap(m_hoverIcon->pixmap(m_cSize,m_cSize));
else if(m_customIcon != nullptr)
2020-10-20 18:06:52 +08:00
setPixmap(renderSvg(*m_customIcon,m_szHoverIn));
2020-10-20 17:24:46 +08:00
m_colorBkg = QColor("#FA6056");
}
void CloseButton::mousePressEvent(QMouseEvent *event) {
if(event->button() == Qt::LeftButton)
{
m_colorBkg = QColor("#E54A50");
m_bIsPressed = true;
update();
}
}
void CloseButton::mouseReleaseEvent(QMouseEvent *event) {
Q_UNUSED(event);
if(m_bIsPressed && this->rect().contains(event->pos()))
{
m_bIsChecked = !m_bIsChecked;
emit clicked(m_bIsChecked);
m_bIsPressed = false;
}
}
void CloseButton::leaveEvent(QEvent *event) {
Q_UNUSED(event);
2020-10-20 18:06:52 +08:00
m_colorBkg = m_customBkg.isValid() ? m_customBkg : palette().color(QPalette::Base);
2020-10-20 17:24:46 +08:00
if(m_icon != nullptr)
2020-10-20 18:06:52 +08:00
setPixmap(renderSvg(*m_icon,m_szHoverOut));
2020-10-20 17:24:46 +08:00
else if(m_customIcon != nullptr)
2020-10-20 18:06:52 +08:00
setPixmap(renderSvg(*m_customIcon,m_szHoverOut));
2020-10-20 17:24:46 +08:00
}
void CloseButton::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
painter.setPen(Qt::transparent);
painter.setBrush(QBrush(m_colorBkg));
painter.drawRoundedRect(rect(), 4, 4);
painter.end();
return QLabel::paintEvent(event);
}
void CloseButton::setIconSize(int size) {
m_cSize = size;
update();
}
void CloseButton::setIcon(const QIcon &icon) {
m_customIcon = new QIcon(icon);
2020-10-20 18:06:52 +08:00
setPixmap(renderSvg(*m_customIcon,m_szHoverOut));
}
void CloseButton::setBkg(const QColor &color) {
m_settedBkg = true;
m_customBkg = color;
m_colorBkg = m_customBkg;
if(m_icon != nullptr) {
setPixmap(renderSvg(*m_icon,m_szHoverOut));
} else if(m_customIcon != nullptr) {
setPixmap(renderSvg(*m_customIcon,m_szHoverOut));
}
}
void CloseButton::setHoverIn(const QString &hoverIn) {
m_szHoverIn = hoverIn;
update();
}
void CloseButton::setHoverOut(const QString &hoverOut) {
m_szHoverOut = hoverOut;
if(m_icon != nullptr) {
setPixmap(renderSvg(*m_icon,m_szHoverOut));
} else if(m_customIcon != nullptr) {
setPixmap(renderSvg(*m_customIcon,m_szHoverOut));
}
update();
2020-10-20 17:24:46 +08:00
}
CloseButton::~CloseButton() {
if(m_icon != nullptr) {
delete m_icon;
m_icon = nullptr;
2020-10-20 17:24:46 +08:00
}
if(m_hoverIcon != nullptr) {
2020-10-20 17:24:46 +08:00
delete m_hoverIcon;
m_hoverIcon = nullptr;
}
if(m_customIcon != nullptr) {
2020-10-20 17:24:46 +08:00
delete m_customIcon;
m_customIcon = nullptr;
}
2020-10-20 17:24:46 +08:00
}