Files
2021-10-18 17:37:32 +08:00

307 lines
7.9 KiB
C++

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* Copyright (C) 2019 Tianjin KYLIN Information Technology 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "switchbutton.h"
#include <QDebug>
#define THEME_QT_SCHEMA "org.ukui.style"
#define THEME_GTK_SCHEMA "org.mate.interface"
SwitchButton::SwitchButton(QWidget *parent) :
QWidget(parent)
{
// this->resize(QSize(52, 24));
this->setFixedSize(QSize(50, 24));
checked = false;
hover = false;
disabled = false;
space = 4;
// rectRadius = 5;
step = width() / 40;
startX = 0;
endX= 0;
timer = new QTimer(this);
timer->setInterval(5);
connect(timer, SIGNAL(timeout()), this, SLOT(updatevalue()));
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();
changeColor(style);
connect(m_qtThemeSetting,&QGSettings::changed, [this] (const QString &key) {
QString style = m_qtThemeSetting->get("styleName").toString();
if (key == "styleName") {
changeColor(style);
}
});
}
}
SwitchButton::~SwitchButton()
{
}
void SwitchButton::paintEvent(QPaintEvent *){
//启用反锯齿
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
drawBg(&painter);
drawSlider(&painter);
}
void SwitchButton::changeColor(const QString &themes) {
if (hover) {
return ;
}
if (themes == "ukui-dark" || themes == "ukui-black") {
bgColorOff = QColor(OFF_BG_DARK_COLOR);
bgColorOn = QColor(ON_BG_DARK_COLOR);
rectColorEnabled = QColor(ENABLE_RECT_DARK_COLOR);
rectColorDisabled = QColor(DISABLE_RECT_DARK_COLOR);
sliderColorDisabled = QColor(DISABLE_RECT_DARK_COLOR);
sliderColorEnabled = QColor(ENABLE_RECT_DARK_COLOR);
bgHoverOnColor = QColor(ON_HOVER_BG_DARK_COLOR);
bgHoverOffColor = QColor(OFF_HOVER_BG_DARK_COLOR);
bgColorDisabled = QColor(DISABLE_DARK_COLOR);
} else {
bgColorOff = QColor(OFF_BG_LIGHT_COLOR);
bgColorOn = QColor(ON_BG_LIGHT_COLOR);
rectColorEnabled = QColor(ENABLE_RECT_LIGHT_COLOR);
rectColorDisabled = QColor(DISABLE_RECT_LIGHT_COLOR);
sliderColorDisabled = QColor(DISABLE_RECT_LIGHT_COLOR);
sliderColorEnabled = QColor(ENABLE_RECT_LIGHT_COLOR);
bgHoverOnColor = QColor(ON_HOVER_BG_LIGHT_COLOR);
bgHoverOffColor = QColor(OFF_HOVER_BG_LIGHT_COLOR);
bgColorDisabled = QColor(DISABLE_LIGHT_COLOR);
}
}
void SwitchButton::drawBg(QPainter *painter){
painter->save();
// painter->setPen(Qt::NoPen);
if (disabled) {
painter->setPen(Qt::NoPen);
painter->setBrush(bgColorDisabled);
} else {
if (!checked){
painter->setPen(Qt::NoPen);
painter->setBrush(bgColorOff);
}
else {
painter->setPen(Qt::NoPen);
painter->setBrush(bgColorOn);
}
}
//circle out
// QRect rect(space, space, width() - space * 2, height() - space * 2);
// painter->drawRoundedRect(rect, rectRadius, rectRadius);
//circle in
QRect rect(0, 0, width(), height());
//半径为高度的一半
int radius = rect.height() / 2;
//圆的宽度为高度
int circleWidth = rect.height();
QPainterPath path;
path.moveTo(radius, rect.left());
path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180);
path.lineTo(rect.width() - radius, rect.height());
path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180);
path.lineTo(radius, rect.top());
painter->drawPath(path);
painter->restore();
}
void SwitchButton::drawSlider(QPainter *painter){
painter->save();
painter->setPen(Qt::NoPen);
if (!disabled){
painter->setBrush(sliderColorEnabled);
}
else
painter->setBrush(sliderColorDisabled);
//circle out
// QRect rect(0, 0, width() - space, height() - space);
// int sliderwidth = rect.height();
// QRect sliderRect(startX, space / 2, sliderwidth, sliderwidth);
// painter->drawEllipse(sliderRect);
//circle in
if (disabled) {
if (checked) {
QRect smallRect(8, height() / 2 - 2, 10 , 4);
painter->drawRoundedRect(smallRect,3,3);
} else {
QRect smallRect(width() - 8 * 2, height() / 2 - 2, 10 , 4);
painter->drawRoundedRect(smallRect,3,3);
}
}
QRect rect(0, 0, width(), height());
int sliderWidth = rect.height() - space * 2;
QRect sliderRect(startX + space, space, sliderWidth, sliderWidth);
painter->drawEllipse(sliderRect);
painter->restore();
}
void SwitchButton::mousePressEvent(QMouseEvent *event){
if (timer->isActive()) {
return ;
}
if (!disabled){
checked = !checked;
step = width() / 40;
if (checked){
//circle out
// endX = width() - height() + space;
//circle in
endX = width() - height();
}
else {
endX = 0;
}
timer->start();
Q_EMIT checkedChanged(checked);
}
else {
endX = 0;
}
// return QWidget::mousePressEvent(event);
}
void SwitchButton::resizeEvent(QResizeEvent *){
//
step = width() / 40;
if (checked){
//circle out
// startX = width() - height() + space;
//circle in
startX = width() - height();
}
else
startX = 0;
update();
}
void SwitchButton::enterEvent(QEvent *event) {
bgColorOn = bgHoverOnColor;
bgColorOff = bgHoverOffColor;
hover = true;
update();
return QWidget::enterEvent(event);
}
void SwitchButton::leaveEvent(QEvent *event) {
hover = false;
QString style = m_qtThemeSetting->get("styleName").toString();
changeColor(style);
update();
return QWidget::leaveEvent(event);
}
void SwitchButton::updatevalue(){
if (disabled) {
return ;
}
if (checked)
if (startX < endX){
startX = startX + step;
}
else {
startX = endX;
timer->stop();
}
else {
if (startX > endX){
startX = startX - step;
}
else {
startX = endX;
timer->stop();
}
}
update();
}
void SwitchButton::setChecked(bool checked){
if (this->checked != checked){
this->checked = checked;
Q_EMIT checkedChanged(checked);
update();
}
step = width() / 40;
if (checked){
//circle out
// endX = width() - height() + space;
//circle in
endX = width() - height();
}
else {
endX = 0;
}
timer->start();
}
bool SwitchButton::isChecked(){
return this->checked;
}
void SwitchButton::setDisabledFlag(bool value)
{
disabled = value;
update();
}
bool SwitchButton::getDisabledFlag()
{
return disabled;
}