2021-10-27 12:28:16 +08:00
|
|
|
|
/* -*- 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"
|
|
|
|
|
#define TIMER_INTERVAL 5 //每隔5ms动画移动一次
|
|
|
|
|
#define MOVING_STEPS 40 //动画总共移动40次
|
|
|
|
|
|
|
|
|
|
SwitchButton::SwitchButton(QWidget *parent, bool useDisableStyle) :
|
|
|
|
|
QWidget(parent)
|
|
|
|
|
{
|
|
|
|
|
// this->resize(QSize(52, 24));
|
|
|
|
|
this->setFixedSize(QSize(50, 24));
|
|
|
|
|
|
|
|
|
|
checked = false;
|
|
|
|
|
hover = false;
|
|
|
|
|
disabled = false;
|
|
|
|
|
isMoving = false;
|
|
|
|
|
isAnimation = true;
|
|
|
|
|
m_useDisableStyle = useDisableStyle;
|
|
|
|
|
|
|
|
|
|
space = 4;
|
|
|
|
|
rectRadius = height()/2;
|
|
|
|
|
|
|
|
|
|
mStep = width()/MOVING_STEPS;//也就是40次动画就可以走完,每次时间间隔是固定的5ms
|
|
|
|
|
mStartX = 0;
|
|
|
|
|
mEndX= 0;
|
|
|
|
|
|
|
|
|
|
mTimer = new QTimer(this);
|
|
|
|
|
mTimer->setInterval(TIMER_INTERVAL);//动画更新时间
|
|
|
|
|
connect(mTimer, 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);
|
|
|
|
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
|
|
|
|
drawBg(&painter);
|
|
|
|
|
if(!isAnimation)//动画如果禁用,则圆形滑块isMoving始终为false
|
|
|
|
|
isMoving =false;
|
|
|
|
|
if(isMoving)
|
|
|
|
|
animation(&painter);
|
|
|
|
|
drawSlider(&painter);
|
|
|
|
|
painter.end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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::animation(QPainter *painter){
|
|
|
|
|
painter->save();
|
|
|
|
|
int h = height();
|
|
|
|
|
int w = width();
|
|
|
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
|
//颜色设置
|
|
|
|
|
if(checked){
|
|
|
|
|
//开关在左侧时
|
|
|
|
|
painter->setBrush(bgColorOn);
|
|
|
|
|
rect.setRect(0,0,h+mStartX,h);
|
|
|
|
|
}else{
|
|
|
|
|
painter->setBrush(bgColorOff);
|
|
|
|
|
rect.setRect(mStartX,0,w-mStartX,h);
|
|
|
|
|
}
|
|
|
|
|
painter->drawRoundedRect(rect,rectRadius,rectRadius);
|
|
|
|
|
|
|
|
|
|
painter->restore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//绘制背景
|
|
|
|
|
void SwitchButton::drawBg(QPainter *painter){
|
|
|
|
|
int w = width();
|
|
|
|
|
int h = height();
|
|
|
|
|
painter->save();
|
|
|
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
|
if (disabled && m_useDisableStyle) {
|
|
|
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
|
painter->setBrush(bgColorDisabled);
|
|
|
|
|
} else {
|
|
|
|
|
if(checked){
|
|
|
|
|
if(isMoving){
|
|
|
|
|
painter->setBrush(bgColorOff);
|
|
|
|
|
rect.setRect(mStartX,0,w-mStartX,h);
|
|
|
|
|
}else {
|
|
|
|
|
painter->setBrush(bgColorOn);
|
|
|
|
|
rect.setRect(0, 0, w, h);
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
if(isMoving){
|
|
|
|
|
painter->setBrush(bgColorOn);
|
|
|
|
|
rect.setRect(0,0,mStartX+h,h);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
painter->setBrush(bgColorOff);
|
|
|
|
|
rect.setRect(0, 0, w, h);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//半径为高度的一半
|
|
|
|
|
painter->drawRoundedRect(rect,rectRadius,rectRadius);
|
|
|
|
|
|
|
|
|
|
painter->restore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//绘制滑块,也就是圆形按钮
|
|
|
|
|
void SwitchButton::drawSlider(QPainter *painter){
|
|
|
|
|
painter->save();
|
|
|
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
|
|
|
|
|
|
if (!disabled || !m_useDisableStyle){
|
|
|
|
|
painter->setBrush(sliderColorEnabled);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
painter->setBrush(sliderColorDisabled);
|
|
|
|
|
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(mStartX + space, space, sliderWidth, sliderWidth);
|
|
|
|
|
painter->drawEllipse(sliderRect);
|
|
|
|
|
|
|
|
|
|
painter->restore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchButton::mousePressEvent(QMouseEvent *){
|
|
|
|
|
qDebug()<<isMoving<<checked<<disabled;
|
|
|
|
|
if (isMoving) {
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
if(disabled){
|
|
|
|
|
mEndX = 0;
|
2021-11-03 11:48:45 +08:00
|
|
|
|
Q_EMIT disabledClick();
|
2021-10-27 12:28:16 +08:00
|
|
|
|
return ;
|
|
|
|
|
}else{
|
|
|
|
|
checked = !checked;
|
|
|
|
|
Q_EMIT checkedChanged(checked);
|
|
|
|
|
|
|
|
|
|
mStep = width() / MOVING_STEPS;
|
|
|
|
|
|
|
|
|
|
if (checked){
|
|
|
|
|
//circle out
|
|
|
|
|
// endX = width() - height() + space;
|
|
|
|
|
//circle in
|
|
|
|
|
mEndX = width() - height();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mEndX = 0;
|
|
|
|
|
}
|
|
|
|
|
mTimer->start();
|
|
|
|
|
isMoving = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchButton::resizeEvent(QResizeEvent *){
|
|
|
|
|
//每次开始的x坐标都是跳过圆角,从直线的地方开始计算
|
|
|
|
|
mStep = width() / MOVING_STEPS;
|
|
|
|
|
|
|
|
|
|
if (checked){
|
|
|
|
|
//circle out
|
|
|
|
|
// startX = width() - height() + space;
|
|
|
|
|
//circle in
|
|
|
|
|
mStartX = width() - height();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
mStartX = 0;
|
|
|
|
|
|
|
|
|
|
rectRadius = height()/2;
|
|
|
|
|
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 (checked)
|
|
|
|
|
if (mStartX < mEndX-mStep){
|
|
|
|
|
mStartX = mStartX + mStep;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
mStartX = mEndX;
|
|
|
|
|
mTimer->stop();
|
|
|
|
|
isMoving = false;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
if (mStartX > mEndX+mStep){
|
|
|
|
|
mStartX = mStartX - mStep;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
mStartX = mEndX;
|
|
|
|
|
mTimer->stop();
|
|
|
|
|
isMoving = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchButton::setChecked(bool checked){
|
|
|
|
|
if (this->checked != checked){
|
|
|
|
|
this->checked = checked;
|
|
|
|
|
Q_EMIT checkedChanged(checked);
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mStep = width() / MOVING_STEPS;
|
|
|
|
|
|
|
|
|
|
if (checked){
|
|
|
|
|
//circle out
|
|
|
|
|
// endX = width() - height() + space;
|
|
|
|
|
//circle in
|
|
|
|
|
mEndX = width() - height();
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
mEndX = 0;
|
|
|
|
|
}
|
|
|
|
|
mTimer->start();
|
|
|
|
|
isMoving = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SwitchButton::isChecked(){
|
|
|
|
|
return this->checked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchButton::setDisabledFlag(bool value)
|
|
|
|
|
{
|
|
|
|
|
disabled = value;
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SwitchButton::getDisabledFlag()
|
|
|
|
|
{
|
|
|
|
|
return disabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchButton::setAnimation(bool on){
|
|
|
|
|
isAnimation = on;
|
|
|
|
|
}
|
|
|
|
|
|