Import Upstream version 3.1.4.1~0509
This commit is contained in:
commit
7db61cc789
|
@ -0,0 +1,104 @@
|
|||
name: Check build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
archlinux-latest:
|
||||
name: on Archlinux Latest
|
||||
runs-on: ubuntu-20.04
|
||||
container: docker.io/library/archlinux:latest
|
||||
steps:
|
||||
- name: Checkout qt5-ukui-platformtheme source code
|
||||
uses: actions/checkout@v2
|
||||
- name: Refresh pacman repository
|
||||
run: pacman -Sy
|
||||
- name: Install build dependencies
|
||||
run: pacman -S --noconfirm base-devel qt5-base gsettings-qt kwindowsystem qt5-tools dconf glibc
|
||||
- name: QMake configure & Make
|
||||
run: |
|
||||
mkdir build;
|
||||
cd build;
|
||||
qmake-qt5 ..;
|
||||
make -j$(nproc);
|
||||
|
||||
debian-sid:
|
||||
name: on Debian Sid
|
||||
runs-on: ubuntu-20.04
|
||||
container: docker.io/library/debian:sid
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
steps:
|
||||
- name: Checkout qt5-ukui-platformtheme source code
|
||||
uses: actions/checkout@v2
|
||||
- name: Update apt repository
|
||||
run: apt-get update -y
|
||||
- name: Install build dependcies
|
||||
run: apt-get install -y build-essential qttools5-dev-tools debhelper-compat pkg-kde-tools libglib2.0-dev libqt5x11extras5-dev libkf5windowsystem-dev libgsettings-qt-dev pkg-config qt5-qmake qtbase5-dev qtbase5-dev-tools qtbase5-private-dev qtchooser qttools5-dev-tools
|
||||
- name: QMake configure & Make
|
||||
run: |
|
||||
mkdir build;
|
||||
cd build;
|
||||
qmake ..;
|
||||
make -j$(nproc);
|
||||
|
||||
fedora-latest:
|
||||
name: on Fedora Latest
|
||||
runs-on: ubuntu-20.04
|
||||
container: docker.io/library/fedora:latest
|
||||
steps:
|
||||
- name: Checkout qt5-ukui-platformtheme source code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install build dependencies
|
||||
run: dnf install -y which gcc gcc-c++ make cmake cmake-rpm-macros autoconf automake intltool rpm-build qt5-rpm-macros glib2-devel qt5-qtx11extras-devel kf5-kwindowsystem-devel gsettings-desktop-schemas-devel qt5-qtbase-devel qt5-qtbase-private-devel qt5-qtbase-static qt5-qttools-devel gsettings-qt-devel
|
||||
- name: QMake configure & Make
|
||||
run: |
|
||||
mkdir build;
|
||||
cd build;
|
||||
qmake-qt5 ..;
|
||||
make -j$(nproc);
|
||||
|
||||
fedora-rawhide:
|
||||
name: on Fedora Rawhide
|
||||
runs-on: ubuntu-20.04
|
||||
container: docker.io/library/fedora:rawhide
|
||||
steps:
|
||||
- name: Checkout peony source code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install build dependencies
|
||||
run: dnf install --refresh --nogpg -y make gcc gcc-c++ which cmake cmake-rpm-macros autoconf automake intltool rpm-build qt5-rpm-macros glib2-devel qt5-qtx11extras-devel kf5-kwindowsystem-devel gsettings-desktop-schemas-devel qt5-qtbase-devel qt5-qtbase-private-devel qt5-qtbase-static qt5-qttools-devel gsettings-qt-devel
|
||||
- name: QMake configure & Make
|
||||
run: |
|
||||
mkdir build;
|
||||
cd build;
|
||||
qmake-qt5 ..;
|
||||
make -j$(nproc);
|
||||
|
||||
ubuntu-latest:
|
||||
name: on Ubuntu Latest
|
||||
runs-on: ubuntu-20.04
|
||||
container: docker.io/library/ubuntu:latest
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
steps:
|
||||
- name: Checkout qt5-ukui-platformtheme source code
|
||||
uses: actions/checkout@v2
|
||||
- name: Update apt repository
|
||||
run: apt-get update -y
|
||||
- name: Install build dependcies
|
||||
run: apt-get install -y build-essential qt5-default qttools5-dev-tools qtmultimedia5-dev debhelper-compat pkg-kde-tools libglib2.0-dev libqt5x11extras5-dev libkf5windowsystem-dev libgsettings-qt-dev pkg-config qt5-qmake qtbase5-dev qtbase5-dev-tools qtbase5-private-dev qtchooser qttools5-dev-tools
|
||||
- name: QMake configure & Make
|
||||
run: |
|
||||
mkdir build;
|
||||
cd build;
|
||||
qmake ..;
|
||||
make -j$(nproc);
|
|
@ -0,0 +1,56 @@
|
|||
# How to contribute
|
||||
|
||||
## language
|
||||
### [zh_CN](CONTRIBUTING_zh_CN.md)
|
||||
|
||||
## As an user
|
||||
|
||||
UKUI style effects almost whole qt's applications in UKUI Desktop Environment. Such as button's rounded radius and color, tab page's switch animations, menu's transparency and blur effects, etc.
|
||||
|
||||
We hope users point out the inconsistencies and lackes of details. That will help us make targeted improvements.
|
||||
|
||||
However, ukui-style can not take over all works of application's displaying. One application might have it own style, even in UKUI. And there also might be some adjustment for applications which using ukui-style. It is hard to distinguish wether it is fully ukui-styled application for user.
|
||||
|
||||
Anyway, if you found out a problem about visual senses or bugs. You can emit a issue to us. Whatever here or at projects which have problems.
|
||||
|
||||
## As a developer
|
||||
|
||||
If you are familiar with Qt5 QPA platformtheme and QStyle, you will know the structure of this project quickly. This project is similar to some other platformtheme project, such as qt5-gtk2-platformtheme, qt5ct, kde, etc. By the platformtheme and style plugins of this project, we build our own desktop environment theme, that means not only our own applications, but also other qt's applications will seemed as UKUI style in our DE, too.
|
||||
|
||||
Platformtheme will completely resove the problem that developers have to cost much time for tuning style to attach UKUI's desgin. We hope developers spend more their time in business logic and functions, and also can ensure the styled unity even in other platform, such as KDE.
|
||||
|
||||
To archive that goal, it's hard to rely on me alone. Developers also need to understand how to develop an application in a standard, and how to comply with standards and expand the application. By doing that you will find its significance in long term.
|
||||
|
||||
For now, Although I have put almost all my energy into the development of this project, It still progresses very slowly. There are many troubles that want volunteers' help to resolve.
|
||||
|
||||
### Platform Theme Level
|
||||
As other platform themes have done, we also want to provide all the features about a platform.
|
||||
|
||||
- Platform Dialogs, such as filechooser dialogs.
|
||||
- Platform Configs, such as font.
|
||||
- Platform Extensions, such as global menu.
|
||||
|
||||
Gtk's applcations theme is also a problem, we have to consider providing a way to uniform the applications' styles between Qt and Gtk.
|
||||
|
||||
### Styles Level
|
||||
A nice looking style is always complex, such as breeze and oxygen. For making our own style, we have to spend a lot of time for UI designing and details maintaining.
|
||||
|
||||
As a developer, we need change the desgin to codes. There could be roughly divided into 2 parts.
|
||||
|
||||
- Tuning of control's painting, such as button, menu's round radius. System or control's palette.
|
||||
- Combing animations with controls, such as tab switching with sliding, button hovering with fading.
|
||||
|
||||
You first need to understand how QStyle and style plugins work, how they draw a control and let control animated.
|
||||
|
||||
### Animations Frameworks Level
|
||||
Animation Frameworks is usually based on Qt's Animations Frameworks. It aims to:
|
||||
|
||||
- Make widgets and view items animated, and let the state changing more smoothly and cool.
|
||||
|
||||
Note that even though Animations Frameworks is relatively independent with platform. But it will have great influence on the theme or style.
|
||||
|
||||
## Active communication
|
||||
|
||||
If you were intersted to contribute, I would also be pleasure to help you understand this project for my best. Starting with an issue or e-mail is good.
|
||||
|
||||
Yue Lan, <lanyue@kylinos.cn>
|
|
@ -0,0 +1,51 @@
|
|||
# 贡献指南
|
||||
|
||||
## 写给使用者
|
||||
|
||||
UKUI的使用者都是此项目的用户,因为它影响了所有UKUI上的Qt应用,我们能从一个标准qt应用的按钮圆角弧度,菜单透明度,动画以及毛玻璃特效等方面看到它对控件样式带来的影响。
|
||||
|
||||
我们希望用户能够指出我们在应用和主题风格设计上的不统一处,以及视觉上的不足与问题,这些都有助于我们对项目进行有针对性的提升。
|
||||
|
||||
当然,UKUI主题框架不可能接管所有应用的控件风格与绘制,一个应用可能希望保持自己的主题,或者针对现有主题的不足进行改进。对于用户来说,可能很难分辨一个控件是否是属于UKUI主题框架内的标准控件,而只能够发现风格上的不同。
|
||||
|
||||
无论如何,如果你找到了视觉上的问题,你都可以向我们提交issue,可以在相应的应用项目中,也可以在这里。
|
||||
|
||||
## 写给开发者
|
||||
|
||||
如果你对Qt5 QPA PlatformTheme以及QStyle比较熟悉,那么你应该能够很快的了解这个项目,并且知道如何参与其中。和其它platform theme,如qt5-gtk2-platformtheme、qt5ct、KDE等项目一样,我们希望通过提供平台插件和主题风格插件来构建我们自己的桌面环境主题,这样做将意味着不光是我们自己开发的应用,其它开发这开发的Qt应用也将会在我们的桌面环境中具有UKUI的风格。
|
||||
|
||||
这种做法将从根本上解决Qt开发者不得不花费大量时间去调整自己应用的样式以达到接近UKUI设计风格的问题。我们希望开发者花费更多时间在业务逻辑和功能实现上,并且还能够保证应用在其它平台上(如KDE)也能够具有风格的统一性。
|
||||
|
||||
为了实现这一目标,我需要开发者们的理解和支持。开发者首先需要知道如何以标准的方式进行应用的开发,然后还需要掌握如何在标准之上针对需求进行合理的调优。通过自己体验这样的流程,你将明白它的长远意义。
|
||||
|
||||
现在,我几乎将我全部的精力投入到这个项目的开发中去了,然而它的推进仍然十分缓慢。我一个人很难在短时间内解决所有的问题,所以希望有志愿者能够帮助我。我简单的列出了一些问题:
|
||||
|
||||
### Platform Theme层面
|
||||
和其它platform theme一样,我们希望在UKUI中提供其它platform theme所提供的特性。
|
||||
|
||||
- 平台对话框,比如文件选择对话框
|
||||
- 平台配置,比如字体配置
|
||||
- 平台扩展,比如全局菜单
|
||||
|
||||
当然,Gtk应用的主题风格与Qt应用的风格主题也是一个比较棘手的问题,我们需要考虑怎样合理的统一它们。
|
||||
|
||||
### Style层面
|
||||
一个好看的主题往往是极其复杂的,比如breeze和oxygen。要构建我们自己的主题,我们需要花费大量的时间在UI设计和细节优化上。作为一名开发者,我们需要做的是将设计稿的内容转化成代码,这大致可以分为2个部分:
|
||||
|
||||
- 控件的样式绘制与调优,比如按钮菜单的圆角弧度,调色板中的颜色等
|
||||
- 动画与控件的结合,比如标签页的滑动切换,按钮的悬浮与渐变效果等
|
||||
|
||||
你首先得了解QStyle和主题插件的相关流程,它们是怎么绘制一个控件,怎么让控件具有动画效果的。
|
||||
|
||||
### 动画框架层
|
||||
动画框架一般来说基于Qt的Animation框架,它的目标是:
|
||||
|
||||
- 让widgets和视图元素具有动画效果,并且让状态的改版更加的平滑和炫酷
|
||||
|
||||
需要注意的是动画框架是相对独立的,然而它对主题的影响还是非常之大。
|
||||
|
||||
## 积极的交流
|
||||
|
||||
如果你对参与项目感兴趣,我也乐意尽力帮助你熟悉这个项目。你可以以提交issue的方式作为开始,也可以通过邮件与我交流。
|
||||
|
||||
Yue Lan, <lanyue@kylinos.cn>
|
|
@ -0,0 +1,165 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -0,0 +1,45 @@
|
|||
# qt5-ukui-platformtheme
|
||||
|
||||
![build](https://github.com/ukui/qt5-ukui-platformtheme/workflows/Check%20build/badge.svg?branch=master)
|
||||
|
||||
The UKUI platform theme for qt5 QPA.
|
||||
|
||||
## Document
|
||||
See [doxygen/README.md](doxygen/README.md).
|
||||
|
||||
## Description
|
||||
In the early development of the UKUI 3.0, we used qt5-gtk2-platformtheme to ensure the unity of the UKUI desktop style. However, it has many limitations for our new desgin.
|
||||
|
||||
This project is intend to provide a common resolution of desktop application development with qt5 in UKUI3.0. We hope provide a platform theme to unify and beautify all qt applications according to the design of UKUI3.0, not only our own applications. We are also committed to building our applications that can adapt to different styles. This project is first step to archive those objectives.
|
||||
|
||||
qt5-ukui-platformtheme's route brings us closer to the upstream communities. It is not a division, but a desire for fusion and individuality in a compatible way.
|
||||
|
||||
## Build and Test
|
||||
### Build Depends (reference debian/contorl)
|
||||
- pkg-config
|
||||
- qt5-default
|
||||
- qtbase5-private-dev
|
||||
- libkf5windowsystem-dev
|
||||
- libgsettings-qt-dev
|
||||
- libglib2.0-dev
|
||||
|
||||
### Testing
|
||||
To test the project, you should first install it into system and make sure that the current qpa platform is ukui.
|
||||
You can export the QT_QPA_PLATFORMTHEME in terminal.
|
||||
|
||||
> export QT_QPA_PLATFORMTHEME=ukui
|
||||
|
||||
One more important job,
|
||||
|
||||
> sudo glib-compile-schemas /usr/share/glib-2.0/schemas
|
||||
|
||||
That will let the gsettings used by qt5-ukui-platformtheme worked.
|
||||
|
||||
Then you can run the test in project, or run any qt5 program for testing with ukui platformtheme.
|
||||
|
||||
### ToDoList
|
||||
- menu blur
|
||||
- custom palette
|
||||
- style switch/management
|
||||
- Change style's details through configuration file
|
||||
- animations
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
# Generate html document
|
||||
|
||||
## How to
|
||||
|
||||
I have provided a configure file to generate the html document of this project. The document is autogen from the file Doxygen.in and the whole project codes. If you want to generate the doc correctly, you should make sure:
|
||||
|
||||
doxygen and graphviz have been installed in your system. If you're user of Debian or Ubuntu, you can use this command for packages installation.
|
||||
|
||||
> sudo apt install doxygen graphviz
|
||||
|
||||
Then just clone this project, cd into this directory, run command:
|
||||
|
||||
> doxygen Doxygen.in
|
||||
|
||||
After command is executed, you should see a new folder named 'out' generated in this directory. Find index.html in this new folder and open it in your browser. Then you can view the project document locally.
|
||||
|
||||
By the way, in progress of generating document, you can also use doxywizard to configure the .in file by yourself. This is very helpful if you want to adjust the scope, content, and format of doc generation. doxywizard is provided by doxygen-gui in Debian and Ubuntu.
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "animation-helper.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include "animator-iface.h"
|
||||
|
||||
AnimationHelper::AnimationHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_animators = new QHash<const QWidget *, AnimatorIface *>();
|
||||
}
|
||||
|
||||
AnimationHelper::~AnimationHelper()
|
||||
{
|
||||
// for (auto animator : *m_animators) {
|
||||
// delete animator;
|
||||
// }
|
||||
delete m_animators;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANIMATIONHELPER_H
|
||||
#define ANIMATIONHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QWidget;
|
||||
class AnimatorIface;
|
||||
|
||||
class AnimationHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AnimationHelper(QObject *parent = nullptr);
|
||||
virtual ~AnimationHelper();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
virtual bool registerWidget(QWidget *) {return false;}
|
||||
virtual bool unregisterWidget(QWidget *) {return false;}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief m_animators
|
||||
* \deprecated
|
||||
* You should not use this member in newly-written code.
|
||||
*/
|
||||
QHash<const QWidget *, AnimatorIface*> *m_animators = nullptr;
|
||||
};
|
||||
|
||||
#endif // ANIMATIONHELPER_H
|
|
@ -0,0 +1,13 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/..
|
||||
|
||||
include(tabwidget/tabwidget.pri)
|
||||
include(scrollbar/scrollbar.pri)
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/animator-plugin-iface.h \
|
||||
$$PWD/animator-iface.h \
|
||||
$$PWD/animation-helper.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/animation-helper.cpp
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANIMATORIFACE_H
|
||||
#define ANIMATORIFACE_H
|
||||
|
||||
#include "animator-plugin-iface.h"
|
||||
#include <QVariant>
|
||||
|
||||
class QWidget;
|
||||
|
||||
class AnimatorIface
|
||||
{
|
||||
public:
|
||||
virtual ~AnimatorIface() {}
|
||||
|
||||
virtual bool bindWidget(QWidget *w) {return false;}
|
||||
virtual bool unboundWidget() {return false;}
|
||||
virtual QWidget *boundedWidget() {return nullptr;}
|
||||
|
||||
virtual QVariant value(const QString &property) {return QVariant();}
|
||||
virtual bool setAnimatorStartValue(const QString &property, const QVariant &value) {return false;}
|
||||
virtual bool setAnimatorEndValue(const QString &property, const QVariant &value) {return false;}
|
||||
virtual bool setAnimatorDuration(const QString &property, int duration) {return false;}
|
||||
|
||||
virtual void setAnimatorDirectionForward(const QString &property = nullptr, bool forward = true) {}
|
||||
virtual bool isRunning(const QString &property = nullptr) {return false;}
|
||||
virtual void startAnimator(const QString &property = nullptr) {}
|
||||
virtual void stopAnimator(const QString &property = nullptr) {}
|
||||
virtual int currentAnimatorTime(const QString &property = nullptr) {return 0;}
|
||||
virtual void setAnimatorCurrentTime(const QString &property = nullptr, const int msecs = 0) {}
|
||||
virtual int totalAnimationDuration(const QString &property = nullptr) {return 0;}
|
||||
};
|
||||
|
||||
#endif // ANIMATORIFACE_H
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANIMATORPLUGINIFACE_H
|
||||
#define ANIMATORPLUGINIFACE_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class UKUIAnimatorPluginIface
|
||||
{
|
||||
public:
|
||||
enum AnimatorPluginType {
|
||||
TabWidget,
|
||||
StackedWidget,
|
||||
PushButton,
|
||||
ItemView,
|
||||
ScrollBar,
|
||||
MenuBar,
|
||||
Menu,
|
||||
Other
|
||||
};
|
||||
|
||||
virtual ~UKUIAnimatorPluginIface() {}
|
||||
|
||||
/*!
|
||||
* \brief id
|
||||
* \return unique plugin's id.
|
||||
* \details
|
||||
* You have to define a unique id for your animator plugin.
|
||||
*/
|
||||
virtual const QString id() = 0;
|
||||
/*!
|
||||
* \brief brief
|
||||
* \return a brief of animator.
|
||||
*/
|
||||
virtual const QString brief() = 0;
|
||||
|
||||
/*!
|
||||
* \brief pluginType
|
||||
* \return animator type for indicating what kinds of widget to bind with.
|
||||
*/
|
||||
virtual AnimatorPluginType pluginType() = 0;
|
||||
|
||||
/*!
|
||||
* \brief inhertKey
|
||||
* \return
|
||||
* \details
|
||||
* When a style polish a widget, ukui animation frameworks will bind the animator
|
||||
* to the widget. This value is the keyword for judgeing if the widget should be bound
|
||||
* with animator. For example, return this value with "QWidget", then all the widgets
|
||||
* will be bound.
|
||||
*/
|
||||
virtual const QString inhertKey() = 0;
|
||||
|
||||
/*!
|
||||
* \brief excludeKeys
|
||||
* \return
|
||||
* \details
|
||||
* In contrast to inhertKey(), this list is a "blacklist" of
|
||||
* widgets should not be bound with the animator.
|
||||
*/
|
||||
virtual const QStringList excludeKeys() = 0;
|
||||
|
||||
/*!
|
||||
* \brief isParallel
|
||||
* \return
|
||||
* \details
|
||||
* Indicate if the animator which plugin created is compatible with other
|
||||
* animators.
|
||||
*
|
||||
* \note
|
||||
* This variable has no practical effect,
|
||||
* but we hope that the animations acting on the same control
|
||||
* can be parallelized, although it is difficult to achieve.
|
||||
*
|
||||
* If you note the animator is not parallelized, other animator
|
||||
* might be invalid. For example, the default tabwidget slide animator
|
||||
* will hijack the paint event of current tabwidget's tab. This might
|
||||
* let other animator can not do a paint in current tab.
|
||||
*/
|
||||
virtual bool isParallel() = 0;
|
||||
};
|
||||
|
||||
#endif // ANIMATORPLUGINIFACE_H
|
|
@ -0,0 +1,5 @@
|
|||
HEADERS += \
|
||||
$$PWD/ukui-scrollbar-default-interaction-animator.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/ukui-scrollbar-default-interaction-animator.cpp
|
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ukui-scrollbar-default-interaction-animator.h"
|
||||
#include <QScrollBar>
|
||||
|
||||
#include <QVariantAnimation>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace UKUI::ScrollBar;
|
||||
|
||||
DefaultInteractionAnimator::DefaultInteractionAnimator(QObject *parent) : QParallelAnimationGroup (parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief DefaultInteractionAnimator::bindWidget
|
||||
* \param w
|
||||
* \return
|
||||
*
|
||||
* \details
|
||||
* QObject has a feature that parent object can use findChild() method
|
||||
* getting a specific named child.
|
||||
*
|
||||
* I use QObject::setObjectName() set my animator and bind to a scroll bar.
|
||||
* So that i could not cache a hash or map to manage animators.
|
||||
*
|
||||
* \bug
|
||||
* Cause I use named QObject child to cache the animator for a scrollbar,
|
||||
* However there are some troubles for my unexcepted.
|
||||
*
|
||||
* For example, qt5 assistant's main view can not find child correctly.
|
||||
* I don't know if animator bind with child was been removed at some times.
|
||||
*/
|
||||
bool DefaultInteractionAnimator::bindWidget(QWidget *w)
|
||||
{
|
||||
if (w->property("doNotAnimate").toBool())
|
||||
return false;
|
||||
|
||||
if (qobject_cast<QScrollBar*>(w)) {
|
||||
m_widget = w;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_groove_width = new QVariantAnimation(this);
|
||||
m_groove_width->setStartValue(0.0);
|
||||
m_groove_width->setEndValue(1.0);
|
||||
m_groove_width->setDuration(150);
|
||||
addAnimation(m_groove_width);
|
||||
|
||||
m_slider_opacity = new QVariantAnimation(this);
|
||||
m_slider_opacity->setStartValue(0.0);
|
||||
m_slider_opacity->setEndValue(0.10);
|
||||
m_slider_opacity->setDuration(150);
|
||||
addAnimation(m_slider_opacity);
|
||||
|
||||
m_sunken_silder_additional_opacity = new QVariantAnimation(this);
|
||||
m_sunken_silder_additional_opacity->setStartValue(0.0);
|
||||
m_sunken_silder_additional_opacity->setEndValue(0.10);
|
||||
m_sunken_silder_additional_opacity->setDuration(150);
|
||||
addAnimation(m_sunken_silder_additional_opacity);
|
||||
|
||||
setObjectName("ukui_scrollbar_default_interaction_animator");
|
||||
|
||||
connect(m_groove_width, &QVariantAnimation::valueChanged, w, [=]() {
|
||||
w->repaint();
|
||||
});
|
||||
connect(m_slider_opacity, &QVariantAnimation::valueChanged, w, [=]() {
|
||||
w->repaint();
|
||||
});
|
||||
connect(m_sunken_silder_additional_opacity, &QVariantAnimation::valueChanged, w, [=]() {
|
||||
w->repaint();
|
||||
});
|
||||
connect(m_groove_width, &QVariantAnimation::finished, w, [=]() {
|
||||
w->repaint();
|
||||
});
|
||||
connect(m_slider_opacity, &QVariantAnimation::finished, w, [=]() {
|
||||
w->repaint();
|
||||
});
|
||||
connect(m_sunken_silder_additional_opacity, &QVariantAnimation::finished, w, [=]() {
|
||||
w->repaint();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefaultInteractionAnimator::unboundWidget()
|
||||
{
|
||||
this->stop();
|
||||
this->setDirection(QAbstractAnimation::Forward);
|
||||
m_groove_width->deleteLater();
|
||||
m_slider_opacity->deleteLater();
|
||||
m_sunken_silder_additional_opacity->deleteLater();
|
||||
|
||||
if (m_widget) {
|
||||
this->setParent(nullptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant DefaultInteractionAnimator::value(const QString &property)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
return m_groove_width->currentValue();
|
||||
} else if (property == "slider_opacity") {
|
||||
return m_slider_opacity->currentValue();
|
||||
} else if (property == "additional_opacity") {
|
||||
return m_sunken_silder_additional_opacity->currentValue();
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultInteractionAnimator::setAnimatorStartValue(const QString &property, const QVariant &value)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
m_groove_width->setStartValue(value);
|
||||
return true;
|
||||
} else if (property == "slider_opacity") {
|
||||
m_slider_opacity->setStartValue(value);
|
||||
return true;
|
||||
} else if (property == "additional_opacity")
|
||||
{
|
||||
m_sunken_silder_additional_opacity->setStartValue(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultInteractionAnimator::setAnimatorEndValue(const QString &property, const QVariant &value)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
m_groove_width->setEndValue(value);
|
||||
return true;
|
||||
} else if (property == "slider_opacity") {
|
||||
m_slider_opacity->setEndValue(value);
|
||||
return true;
|
||||
} else if (property == "additional_opacity") {
|
||||
m_sunken_silder_additional_opacity->setEndValue(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultInteractionAnimator::setAnimatorDuration(const QString &property, int duration)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
m_groove_width->setDuration(duration);
|
||||
return true;
|
||||
} else if (property == "slider_opacity") {
|
||||
m_groove_width->setDuration(duration);
|
||||
return true;
|
||||
} else if (property == "additional_opacity") {
|
||||
m_sunken_silder_additional_opacity->setDuration(duration);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultInteractionAnimator::setAnimatorDirectionForward(const QString &property, bool forward)
|
||||
{
|
||||
auto d = forward? QAbstractAnimation::Forward: QAbstractAnimation::Backward;
|
||||
if (property == "groove_width") {
|
||||
m_groove_width->setDirection(d);
|
||||
} else if (property == "slider_opacity") {
|
||||
m_slider_opacity->setDirection(d);
|
||||
} else if (property == "additional_opacity") {
|
||||
m_sunken_silder_additional_opacity->setDirection(d);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultInteractionAnimator::isRunning(const QString &property)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
return m_groove_width->state() == Running;
|
||||
} else if (property == "slider_opacity") {
|
||||
return m_slider_opacity->state() == Running;
|
||||
} else if (property == "additional_opacity") {
|
||||
return m_sunken_silder_additional_opacity->state() == Running;
|
||||
} else {
|
||||
return this->state() == Running;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultInteractionAnimator::startAnimator(const QString &property)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
m_groove_width->start();
|
||||
} else if (property == "slider_opacity") {
|
||||
m_slider_opacity->start();
|
||||
} else if (property == "additional_opacity") {
|
||||
m_sunken_silder_additional_opacity->start();
|
||||
} else {
|
||||
this->start();
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultInteractionAnimator::stopAnimator(const QString &property)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
m_groove_width->stop();
|
||||
} else if (property == "slider_opacity") {
|
||||
m_slider_opacity->stop();
|
||||
} else if (property == "additional_opacity") {
|
||||
m_sunken_silder_additional_opacity->stop();
|
||||
} else {
|
||||
this->stop();
|
||||
}
|
||||
}
|
||||
|
||||
int DefaultInteractionAnimator::currentAnimatorTime(const QString &property)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
return m_groove_width->currentTime();
|
||||
} else if (property == "slider_opacity") {
|
||||
return m_slider_opacity->currentTime();
|
||||
} else if (property == "additional_opacity") {
|
||||
return m_sunken_silder_additional_opacity->currentTime();
|
||||
} else {
|
||||
return this->currentTime();
|
||||
}
|
||||
}
|
||||
|
||||
int DefaultInteractionAnimator::totalAnimationDuration(const QString &property)
|
||||
{
|
||||
if (property == "groove_width") {
|
||||
return m_groove_width->duration();
|
||||
} else if (property == "slider_opacity") {
|
||||
return m_slider_opacity->duration();
|
||||
} else if (property == "additional_opacity") {
|
||||
return m_sunken_silder_additional_opacity->duration();
|
||||
} else {
|
||||
return this->duration();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUISCROLLBARDEFAULTINTERACTIONANIMATOR_H
|
||||
#define UKUISCROLLBARDEFAULTINTERACTIONANIMATOR_H
|
||||
|
||||
#include <QParallelAnimationGroup>
|
||||
#include "animator-iface.h"
|
||||
|
||||
class QVariantAnimation;
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
namespace ScrollBar {
|
||||
|
||||
class DefaultInteractionAnimator : public QParallelAnimationGroup, public AnimatorIface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DefaultInteractionAnimator(QObject *parent = nullptr);
|
||||
|
||||
bool bindWidget(QWidget *w);
|
||||
bool unboundWidget();
|
||||
QWidget *boundedWidget() {return m_widget;}
|
||||
|
||||
QVariant value(const QString &property);
|
||||
bool isRunning(const QString &property = nullptr);
|
||||
bool setAnimatorStartValue(const QString &property, const QVariant &value);
|
||||
bool setAnimatorEndValue(const QString &property, const QVariant &value);
|
||||
|
||||
bool setAnimatorDuration(const QString &property, int duration);
|
||||
void setAnimatorDirectionForward(const QString &property = nullptr, bool forward = true);
|
||||
void startAnimator(const QString &property = nullptr);
|
||||
void stopAnimator(const QString &property = nullptr);
|
||||
int currentAnimatorTime(const QString &property = nullptr);
|
||||
int totalAnimationDuration(const QString &property);
|
||||
|
||||
private:
|
||||
QWidget *m_widget = nullptr;
|
||||
|
||||
QVariantAnimation *m_groove_width;
|
||||
QVariantAnimation *m_slider_opacity;
|
||||
QVariantAnimation *m_sunken_silder_additional_opacity;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // UKUISCROLLBARDEFAULTINTERACTIONANIMATOR_H
|
|
@ -0,0 +1,13 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/ukui-tabwidget-animator-iface.h \
|
||||
$$PWD/ukui-tabwidget-animator-plugin-iface.h \
|
||||
$$PWD/ukui-tabwidget-default-slide-animator-factory.h \
|
||||
$$PWD/ukui-tabwidget-default-slide-animator.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/ukui-tabwidget-default-slide-animator-factory.cpp \
|
||||
$$PWD/ukui-tabwidget-default-slide-animator.cpp
|
||||
|
||||
INCLUDEPATH += $$PWD/..
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUITABWIDGETANIMATORIFACE_H
|
||||
#define UKUITABWIDGETANIMATORIFACE_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include "animator-iface.h"
|
||||
|
||||
/*!
|
||||
* \brief The UKUITabWidgetAnimatorIface class
|
||||
* \details
|
||||
* This class define the interface for doing a QTabWidget's animation.
|
||||
* a tabwidget animator should bind only one tabwidget with bindTabWidget(),
|
||||
* and can be unbounded with unboundTabWidget().
|
||||
*
|
||||
* Animator is created by AnimatorPlugin, which is another interface's implement
|
||||
* of UKUI style animation's frameworks.
|
||||
*
|
||||
* \see UKUITabWidgetAnimatorPluginIface
|
||||
*/
|
||||
class UKUITabWidgetAnimatorIface : public AnimatorIface
|
||||
{
|
||||
public:
|
||||
virtual ~UKUITabWidgetAnimatorIface() {}
|
||||
|
||||
virtual bool bindWidget(QWidget *w) {
|
||||
return bindTabWidget(qobject_cast<QTabWidget *>(w));
|
||||
}
|
||||
|
||||
virtual bool unboundWidget() {
|
||||
return unboundTabWidget();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief bindTabWidget
|
||||
* \param w widget should be bound.
|
||||
* \return true if successed.
|
||||
* \details
|
||||
* this method is used for binding a animator instance for a tab widget.
|
||||
* You have to implement this function in your own implement class.
|
||||
*/
|
||||
virtual bool bindTabWidget(QTabWidget *w) = 0;
|
||||
|
||||
/*!
|
||||
* \brief unboundTabWidget
|
||||
* \return true if successed.
|
||||
* \details
|
||||
* this method is used to unbound the animator instance and tab widget.
|
||||
* You have to implement this function in your own implement class.
|
||||
*/
|
||||
virtual bool unboundTabWidget() = 0;
|
||||
};
|
||||
|
||||
#endif // UKUITABWIDGETANIMATORIFACE_H
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUITABWIDGETANIMATORPLUGINIFACE_H
|
||||
#define UKUITABWIDGETANIMATORPLUGINIFACE_H
|
||||
|
||||
#include <QString>
|
||||
#include "animator-plugin-iface.h"
|
||||
#include "ukui-tabwidget-animator-iface.h"
|
||||
|
||||
#define UKUITabWidgetAnimatorPluginInterface_iid "org.ukui.style.animatons.TabWidgetPluginInterface"
|
||||
|
||||
/*!
|
||||
* \brief The UKUITabWidgetAnimatorPluginIface class
|
||||
* \details
|
||||
* This class is used to create a tabwidget animator instace.
|
||||
*
|
||||
* UKUI Animation's frameworks is desgined to be extensiable.
|
||||
* And this interface is an entry of plugin.
|
||||
*
|
||||
* \see UKUITabWidgetAnimatorIface
|
||||
*/
|
||||
class UKUITabWidgetAnimatorPluginIface : public UKUIAnimatorPluginIface
|
||||
{
|
||||
public:
|
||||
virtual ~UKUITabWidgetAnimatorPluginIface() {}
|
||||
|
||||
/*!
|
||||
* \brief key
|
||||
* \return
|
||||
* A key word of plugin, such as "slide".
|
||||
*/
|
||||
virtual const QString key() = 0;
|
||||
|
||||
/*!
|
||||
* \brief description
|
||||
* \return
|
||||
* A description for animator. For example, "Animator for do a horizon slide
|
||||
* for tab widget."
|
||||
*/
|
||||
virtual const QString description() = 0;
|
||||
|
||||
/*!
|
||||
* \brief createAnimator
|
||||
* \return
|
||||
* an animator instance, for example a UKUI::TabWidget::DefaultSlideAnimator.
|
||||
*/
|
||||
virtual UKUITabWidgetAnimatorIface *createAnimator() = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(UKUITabWidgetAnimatorPluginIface, UKUITabWidgetAnimatorPluginInterface_iid)
|
||||
|
||||
#endif // UKUITABWIDGETANIMATORPLUGINIFACE_H
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ukui-tabwidget-default-slide-animator-factory.h"
|
||||
#include "ukui-tabwidget-default-slide-animator.h"
|
||||
|
||||
using namespace UKUI::TabWidget;
|
||||
|
||||
DefaultSlideAnimatorFactory::DefaultSlideAnimatorFactory(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UKUITabWidgetAnimatorIface *DefaultSlideAnimatorFactory::createAnimator()
|
||||
{
|
||||
return new DefaultSlideAnimator;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUITABWIDGETDEFAULTSLIDEANIMATORFACTORY_H
|
||||
#define UKUITABWIDGETDEFAULTSLIDEANIMATORFACTORY_H
|
||||
|
||||
#include <QObject>
|
||||
#include "ukui-tabwidget-animator-plugin-iface.h"
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
namespace TabWidget {
|
||||
|
||||
/*!
|
||||
* \brief The DefaultSlideAnimatorFactory class
|
||||
* \details
|
||||
* This class is an internal plugin. It provides a default tabwidget
|
||||
* switch animation for QTabWidget and its drived class.
|
||||
*
|
||||
* \note
|
||||
* Note that it used in ukui-style, but you can also use its api in other
|
||||
* desktop environment.
|
||||
*/
|
||||
class DefaultSlideAnimatorFactory : public QObject, public UKUITabWidgetAnimatorPluginIface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DefaultSlideAnimatorFactory(QObject *parent = nullptr);
|
||||
|
||||
const QString id() {return tr("Default Slide");}
|
||||
const QString brief() {return tr("Let tab widget switch with a slide animation.");}
|
||||
|
||||
const QString key() {return "tab_slide";}
|
||||
const QString description() {return brief();}
|
||||
AnimatorPluginType pluginType() {return TabWidget;}
|
||||
|
||||
const QString inhertKey() {return "QTabWidget";}
|
||||
const QStringList excludeKeys() {return QStringList()<<"Peony::DirectoryWidget";}
|
||||
bool isParallel() {return false;}
|
||||
|
||||
UKUITabWidgetAnimatorIface *createAnimator();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // UKUITABWIDGETDEFAULTSLIDEANIMATORFACTORY_H
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ukui-tabwidget-default-slide-animator.h"
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QChildEvent>
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QTabBar>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace UKUI::TabWidget;
|
||||
|
||||
/*!
|
||||
* \brief DefaultSlideAnimator::DefaultSlideAnimator
|
||||
* \param parent
|
||||
* \details
|
||||
* This class define a slide animator for tab widget sliding animation.
|
||||
* Animator based on QVariantAnimation, paint on a tmp widgets when running.
|
||||
* The content of widget is based on animation's current value and 2 pixmap
|
||||
* grabbed at appropriate times.
|
||||
*
|
||||
* \note
|
||||
* Once an animator have bound a tab widget, it have to unbound current widget at first.
|
||||
* Then it can bind another tab widget again.
|
||||
*/
|
||||
DefaultSlideAnimator::DefaultSlideAnimator(QObject *parent) : QVariantAnimation (parent)
|
||||
{
|
||||
setDuration(200);
|
||||
setEasingCurve(QEasingCurve::OutQuad);
|
||||
setStartValue(0.0);
|
||||
setEndValue(1.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief DefaultSlideAnimator::bindTabWidget
|
||||
* \param w A QTabWidget instance, most passed in QStyle::polish().
|
||||
* \return result if Tab widget be bound \c true for binding successed.
|
||||
* \details
|
||||
* When do a tab widget binding, animator will create a tmp child page for tab widget's
|
||||
* stack widget. Then it will watched their event waiting for preparing and doing a animation.
|
||||
*/
|
||||
|
||||
bool DefaultSlideAnimator::bindTabWidget(QTabWidget *w)
|
||||
{
|
||||
if (w) {
|
||||
m_bound_widget = w;
|
||||
|
||||
//watch tab widget
|
||||
w->installEventFilter(this);
|
||||
|
||||
m_tmp_page = new QWidget;
|
||||
//watch tmp page;
|
||||
m_tmp_page->installEventFilter(this);
|
||||
|
||||
for (auto child : w->children()) {
|
||||
if (child->objectName() == "qt_tabwidget_stackedwidget") {
|
||||
auto stack = qobject_cast<QStackedWidget *>(child);
|
||||
m_stack = stack;
|
||||
//watch stack widget
|
||||
m_tmp_page->setParent(m_stack);
|
||||
m_tmp_page->resize(m_stack->size());
|
||||
m_stack->installEventFilter(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < w->count(); i++) {
|
||||
//watch sub page
|
||||
watchSubPage(w->widget(i));
|
||||
}
|
||||
|
||||
m_tmp_page->setAttribute(Qt::WA_TranslucentBackground, m_bound_widget->testAttribute(Qt::WA_TranslucentBackground));
|
||||
|
||||
previous_widget = m_bound_widget->currentWidget();
|
||||
pervIndex = m_bound_widget->currentIndex();
|
||||
|
||||
connect(w, &QTabWidget::currentChanged, this, [=](int index){
|
||||
this->stop();
|
||||
m_tmp_page->hide();
|
||||
if (m_bound_widget->currentWidget() && m_bound_widget->currentWidget() != previous_widget) {
|
||||
left_right = m_bound_widget->currentIndex() > pervIndex;
|
||||
pervIndex = m_bound_widget->currentIndex();
|
||||
/*
|
||||
* This way not suitable for 4k
|
||||
*/
|
||||
//m_next_pixmap = m_bound_widget->grab(QRect(m_bound_widget->rect().x(), m_bound_widget->tabBar()->height(),
|
||||
//m_bound_widget->currentWidget()->width(), m_bound_widget->currentWidget()->height()));
|
||||
|
||||
QPixmap pixmap(m_stack->size());
|
||||
pixmap.fill(QColor(Qt::transparent));
|
||||
|
||||
/*
|
||||
* This way some widget such as QFrame.
|
||||
* QPalette::Window was used to draw the background during the screenshot,
|
||||
* but QWidget itself did not draw the entire area with others during the screenshot,
|
||||
* resulting in some areas in the screenshot that the background drawn by QPalette::Window was different from the actual drawing.
|
||||
*/
|
||||
//m_bound_widget->currentWidget()->render(&pixmap, QPoint(), m_bound_widget->currentWidget()->rect());
|
||||
|
||||
/*
|
||||
* This way by modifying the way of QPalette, get the same screenshot as the actual state
|
||||
*/
|
||||
//QPalette palette, palette_save;
|
||||
//palette = palette_save = m_bound_widget->currentWidget()->palette();
|
||||
//palette.setBrush(QPalette::Window, palette.brush(QPalette::Base));
|
||||
//m_bound_widget->currentWidget()->setPalette(palette);
|
||||
//m_bound_widget->currentWidget()->render(&pixmap, QPoint(), m_bound_widget->currentWidget()->rect());
|
||||
//m_bound_widget->currentWidget()->setPalette(palette_save);
|
||||
|
||||
m_bound_widget->render(&pixmap, QPoint(), m_stack->geometry());
|
||||
m_next_pixmap = pixmap;
|
||||
|
||||
if (qobject_cast<QWidget *>(previous_widget)) {
|
||||
QPixmap previous_pixmap(m_stack->size());
|
||||
previous_pixmap.fill(QColor(Qt::transparent));
|
||||
QPalette palette = m_bound_widget->palette();
|
||||
QPalette palette_save = previous_widget->palette();
|
||||
|
||||
/*
|
||||
* This use QPalette::Base to replace QPalette::Window, Mabey have unknow bug.
|
||||
*/
|
||||
if (!m_bound_widget->testAttribute(Qt::WA_TranslucentBackground)) {
|
||||
previous_widget->render(&previous_pixmap);
|
||||
}
|
||||
palette.setBrush(QPalette::Window, palette.brush(QPalette::Base));
|
||||
previous_widget->setPalette(palette);
|
||||
previous_widget->render(&previous_pixmap);
|
||||
previous_widget->setPalette(palette_save);
|
||||
m_previous_pixmap = previous_pixmap;
|
||||
|
||||
switch (w->tabBar()->shape()) {
|
||||
case QTabBar::RoundedNorth:
|
||||
case QTabBar::TriangularNorth:
|
||||
case QTabBar::RoundedSouth:
|
||||
case QTabBar::TriangularSouth:
|
||||
horizontal = false;
|
||||
break;
|
||||
case QTabBar::RoundedWest:
|
||||
case QTabBar::TriangularWest:
|
||||
case QTabBar::RoundedEast:
|
||||
case QTabBar::TriangularEast:
|
||||
horizontal = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this->start();
|
||||
m_tmp_page->raise();
|
||||
m_tmp_page->show();
|
||||
}
|
||||
}
|
||||
previous_widget = m_bound_widget->currentWidget();
|
||||
});
|
||||
|
||||
connect(this, &QVariantAnimation::valueChanged, m_tmp_page, [=]() {
|
||||
m_tmp_page->repaint();
|
||||
});
|
||||
connect(this, &QVariantAnimation::finished, m_tmp_page, [=]() {
|
||||
m_tmp_page->repaint();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DefaultSlideAnimator::unboundTabWidget()
|
||||
{
|
||||
clearPixmap();
|
||||
if (m_bound_widget) {
|
||||
disconnect(m_bound_widget, &QTabWidget::currentChanged, this, nullptr);
|
||||
for (auto w : m_bound_widget->children()) {
|
||||
w->removeEventFilter(this);
|
||||
}
|
||||
|
||||
m_tmp_page->removeEventFilter(this);
|
||||
m_tmp_page->deleteLater();
|
||||
m_tmp_page = nullptr;
|
||||
previous_widget = nullptr;
|
||||
m_bound_widget = nullptr;
|
||||
this->deleteLater();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DefaultSlideAnimator::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
if (obj == m_tmp_page) {
|
||||
return filterTmpPage(obj, e);
|
||||
}
|
||||
if (obj == m_stack) {
|
||||
return filterStackedWidget(obj, e);
|
||||
}
|
||||
if (obj == m_bound_widget) {
|
||||
return filterTabWidget(obj, e);
|
||||
}
|
||||
return filterSubPage(obj, e);
|
||||
}
|
||||
|
||||
void DefaultSlideAnimator::watchSubPage(QWidget *w)
|
||||
{
|
||||
if (w)
|
||||
w->installEventFilter(this);
|
||||
}
|
||||
|
||||
bool DefaultSlideAnimator::filterTabWidget(QObject *obj, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::Close) {
|
||||
this->unboundTabWidget();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DefaultSlideAnimator::filterStackedWidget(QObject *obj, QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::ChildAdded:
|
||||
case QEvent::ChildRemoved: {
|
||||
if (obj->objectName() == "qt_tabwidget_stackedwidget") {
|
||||
QChildEvent *ce = static_cast<QChildEvent *>(e);
|
||||
if (!ce->child()->isWidgetType())
|
||||
return false;
|
||||
if (ce->added()) {
|
||||
ce->child()->installEventFilter(this);
|
||||
} else {
|
||||
ce->child()->removeEventFilter(this);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case QEvent::Resize:
|
||||
m_tab_resizing = true;
|
||||
return false;
|
||||
case QEvent::LayoutRequest: {
|
||||
/// there a 2 case we need excute these codes.
|
||||
/// 1. when stacked widget created and shown, it first do resize, then do a layout request.
|
||||
/// 2. after stacked widget resize.
|
||||
///
|
||||
/// This event is very suitable for the above two situations,
|
||||
/// both in terms of efficiency and trigger time.
|
||||
if (m_tab_resizing) {
|
||||
m_tmp_page->resize(m_stack->size());
|
||||
if(m_next_pixmap.isNull())
|
||||
pervIndex = m_bound_widget->currentIndex();
|
||||
}
|
||||
m_tab_resizing = false;
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DefaultSlideAnimator::filterSubPage(QObject *obj, QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::Show: {
|
||||
return false;
|
||||
}
|
||||
case QEvent::Hide: {
|
||||
/*
|
||||
* This way not suitable for 4k and multi-screen crash(Todo: get the screen change event, get the corresponding screen,
|
||||
* call the grabWindow method of QScreen to get the picture,
|
||||
* but the picture needs to be processed by 4k and orientation size)
|
||||
*/
|
||||
//if (m_bound_widget->currentWidget()) {
|
||||
//QScreen *screen = QGuiApplication::primaryScreen();
|
||||
//m_previous_pixmap = screen->grabWindow(m_bound_widget->winId(),
|
||||
// m_bound_widget->tabBar()->x() + 2,
|
||||
// m_bound_widget->tabBar()->height(),
|
||||
// m_bound_widget->currentWidget()->width(),
|
||||
// m_bound_widget->currentWidget()->height());
|
||||
//}
|
||||
this->stop();
|
||||
return false;
|
||||
}
|
||||
case QEvent::Resize: {
|
||||
this->stop();
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultSlideAnimator::filterTmpPage(QObject *obj, QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::Show: {
|
||||
return false;
|
||||
}
|
||||
case QEvent::Paint: {
|
||||
QWidget *w = qobject_cast<QWidget *>(obj);
|
||||
if (this->state() == QAbstractAnimation::Running) {
|
||||
QPainter p(w);
|
||||
auto value = this->currentValue().toDouble();
|
||||
p.setRenderHints(QPainter::Antialiasing);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
|
||||
//do a horizon slide.
|
||||
auto prevSrcRect = QRectF(m_previous_pixmap.rect());
|
||||
auto prevTargetRect = QRectF(m_previous_pixmap.rect());
|
||||
auto nextSrcRect = QRectF(m_next_pixmap.rect());
|
||||
auto nextTargetRect = QRectF(m_next_pixmap.rect());
|
||||
if (left_right) {
|
||||
if (horizontal) {
|
||||
prevSrcRect.setY(m_previous_pixmap.height() * value);
|
||||
prevSrcRect.setHeight(m_previous_pixmap.height() * (1 - value));
|
||||
prevTargetRect.setHeight(m_previous_pixmap.height() * (1 - value));
|
||||
} else {
|
||||
prevSrcRect.setX(m_previous_pixmap.width() * value);
|
||||
prevSrcRect.setWidth(m_previous_pixmap.width() * (1 - value));
|
||||
prevTargetRect.setWidth(m_previous_pixmap.width() * (1 - value));
|
||||
}
|
||||
p.drawPixmap(prevTargetRect, m_previous_pixmap, prevSrcRect);
|
||||
|
||||
if (horizontal) {
|
||||
nextSrcRect.setHeight(m_next_pixmap.height() * value);
|
||||
nextTargetRect.setY(m_next_pixmap.height() * (1 - value));
|
||||
nextTargetRect.setHeight(m_next_pixmap.height() * value);
|
||||
} else {
|
||||
nextSrcRect.setWidth(m_next_pixmap.width() * value);
|
||||
nextTargetRect.setX(m_next_pixmap.width() * (1 - value));
|
||||
nextTargetRect.setWidth(m_next_pixmap.width() * value);
|
||||
}
|
||||
p.drawPixmap(nextTargetRect, m_next_pixmap, nextSrcRect);
|
||||
} else {
|
||||
if (horizontal) {
|
||||
nextSrcRect.setY(m_next_pixmap.height() * (1 - value));
|
||||
nextSrcRect.setHeight(m_next_pixmap.height() * value);
|
||||
nextTargetRect.setHeight(m_next_pixmap.height() * value);
|
||||
} else {
|
||||
nextSrcRect.setX(m_next_pixmap.width() * (1 - value));
|
||||
nextSrcRect.setWidth(m_next_pixmap.width() * value);
|
||||
nextTargetRect.setWidth(m_next_pixmap.width() * value);
|
||||
}
|
||||
p.drawPixmap(nextTargetRect, m_next_pixmap, nextSrcRect);
|
||||
|
||||
if (horizontal) {
|
||||
prevSrcRect.setHeight(m_previous_pixmap.height() * (1 - value));
|
||||
prevTargetRect.setY(m_previous_pixmap.height() * value);
|
||||
prevTargetRect.setHeight(m_previous_pixmap.height() * (1 - value));
|
||||
} else {
|
||||
prevSrcRect.setWidth(m_previous_pixmap.width() * (1 - value));
|
||||
prevTargetRect.setX(m_previous_pixmap.width() * value);
|
||||
prevTargetRect.setWidth(m_previous_pixmap.width() * (1 - value));
|
||||
}
|
||||
p.drawPixmap(prevTargetRect, m_previous_pixmap, prevSrcRect);
|
||||
}
|
||||
|
||||
//eat event so that widget will not paint default items and override
|
||||
//our custom pixmap.
|
||||
return true;
|
||||
}
|
||||
m_tmp_page->hide();
|
||||
if (!m_next_pixmap.isNull())
|
||||
m_stack->stackUnder(m_tmp_page);
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultSlideAnimator::clearPixmap()
|
||||
{
|
||||
m_previous_pixmap = QPixmap();
|
||||
m_next_pixmap = QPixmap();
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUITABWIDGETDEFAULTSLIDEANIMATOR_H
|
||||
#define UKUITABWIDGETDEFAULTSLIDEANIMATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantAnimation>
|
||||
#include <QStackedWidget>
|
||||
#include "ukui-tabwidget-animator-iface.h"
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
namespace TabWidget {
|
||||
|
||||
/*!
|
||||
* \brief The DefaultSlideAnimator class
|
||||
* \details
|
||||
* This class is an implement of UKUITabWidgetAnimatorIface.
|
||||
*/
|
||||
class DefaultSlideAnimator : public QVariantAnimation, public UKUITabWidgetAnimatorIface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DefaultSlideAnimator(QObject *parent = nullptr);
|
||||
|
||||
bool bindTabWidget(QTabWidget *w);
|
||||
bool unboundTabWidget();
|
||||
QWidget *boundedWidget() {return m_bound_widget;}
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
|
||||
protected:
|
||||
void watchSubPage(QWidget *w);
|
||||
|
||||
bool filterTabWidget(QObject *obj, QEvent *e);
|
||||
bool filterStackedWidget(QObject *obj, QEvent *e);
|
||||
bool filterSubPage(QObject *obj, QEvent *e);
|
||||
bool filterTmpPage(QObject *obj, QEvent *e);
|
||||
|
||||
void clearPixmap();
|
||||
|
||||
private:
|
||||
QTabWidget *m_bound_widget = nullptr;
|
||||
QStackedWidget *m_stack = nullptr;
|
||||
QList<QWidget *> m_children;
|
||||
|
||||
QPixmap m_previous_pixmap;
|
||||
QPixmap m_next_pixmap;
|
||||
|
||||
/*!
|
||||
* \brief m_tmp_page
|
||||
* \note
|
||||
* insert a tmp tab page into tab widget directly is dangerous,
|
||||
* because a custom tab widget's page may be desgined different
|
||||
* with normal tab page, such as peony-qt's directory view.
|
||||
* In that case, it might lead program crashed when
|
||||
* application call a custom page but get a tmp page.
|
||||
*
|
||||
* for those reasons, i use a temporary widgets bound to the
|
||||
* stacked widget with qt's parent&child mechanism.
|
||||
* It can float on the top layer or hide on the lower layer of stack,
|
||||
* but it does not belong to the elements in the stack (no index),
|
||||
* which can avoid the above problems.
|
||||
*
|
||||
* However, this way might be incompatible with other animations.
|
||||
* Because it uses a new widget for painting, not relate with orignal
|
||||
* page. Another conflict is the oxygen's fade animation might force
|
||||
* raise current tab page when it finished. That might cause a incompleted
|
||||
* slide animation if slide duration is longer than fade's.
|
||||
*/
|
||||
QWidget *m_tmp_page = nullptr;
|
||||
|
||||
/*!
|
||||
* \brief m_tab_resizing
|
||||
* \details
|
||||
* If a went to a resize event, the animation should handle
|
||||
* widget's relayout after resized.
|
||||
* This bool varient is used to help judege if animator's pixmaps
|
||||
* and template widget' states should be updated.
|
||||
*/
|
||||
bool m_tab_resizing = false;
|
||||
int pervIndex = -1;
|
||||
bool left_right = true;
|
||||
bool horizontal = false;
|
||||
QWidget *previous_widget = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // UKUITABWIDGETDEFAULTSLIDEANIMATOR_H
|
|
@ -0,0 +1,7 @@
|
|||
Name: libqt5-ukui-style
|
||||
Description: UKUI style API for secondary development.
|
||||
Home Page: https://github.com/ukui/qt5-ukui-platformtheme
|
||||
Requires: Qt5Widgets >= 5.12.1 glib-2.0 gio-2.0 gsettings-qt
|
||||
Version: 1.0.0
|
||||
Libs: -L/usr/lib -L/usr/lib/x86_64-linux-gnu -lqt5-ukui-style
|
||||
Cflags: -I/usr/include/qt5-ukui
|
|
@ -0,0 +1,8 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/..
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/highlight-effect.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/highlight-effect.cpp
|
|
@ -0,0 +1,456 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "highlight-effect.h"
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QMenu>
|
||||
#include <QStyleOption>
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
|
||||
#include <QImage>
|
||||
#include <QtMath>
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#define ColorDifference 10
|
||||
|
||||
QColor HighLightEffect::symbolic_color = QColor(31, 32, 34, 192);
|
||||
|
||||
void HighLightEffect::setSkipEffect(QWidget *w, bool skip)
|
||||
{
|
||||
w->setProperty("skipHighlightIconEffect", skip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool HighLightEffect::isPixmapPureColor(const QPixmap &pixmap)
|
||||
{
|
||||
if (pixmap.isNull()) {
|
||||
qWarning("pixmap is null!");
|
||||
return false;
|
||||
}
|
||||
QImage image = pixmap.toImage();
|
||||
|
||||
QVector<QColor> vector;
|
||||
int total_red = 0;
|
||||
int total_green = 0;
|
||||
int total_blue = 0;
|
||||
bool pure = true;
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
for (int x = 0; x < image.width(); ++x) {
|
||||
if (image.pixelColor(x, y).alphaF() > 0.3) {
|
||||
QColor color = image.pixelColor(x, y);
|
||||
vector << color;
|
||||
total_red += color.red();
|
||||
total_green += color.green();
|
||||
total_blue += color.blue();
|
||||
int dr = qAbs(color.red() - symbolic_color.red());
|
||||
int dg = qAbs(color.green() - symbolic_color.green());
|
||||
int db = qAbs(color.blue() - symbolic_color.blue());
|
||||
if (dr > ColorDifference || dg > ColorDifference || db > ColorDifference)
|
||||
pure = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pure)
|
||||
return true;
|
||||
|
||||
qreal squareRoot_red = 0;
|
||||
qreal squareRoot_green = 0;
|
||||
qreal squareRoot_blue = 0;
|
||||
qreal average_red = total_red / vector.count();
|
||||
qreal average_green = total_green / vector.count();
|
||||
qreal average_blue = total_blue / vector.count();
|
||||
for (QColor color : vector) {
|
||||
squareRoot_red += (color.red() - average_red) * (color.red() - average_red);
|
||||
squareRoot_green += (color.green() - average_green) * (color.green() - average_green);
|
||||
squareRoot_blue += (color.blue() - average_blue) * (color.blue() - average_blue);
|
||||
}
|
||||
|
||||
qreal arithmeticSquareRoot_red = qSqrt(squareRoot_red / vector.count());
|
||||
qreal arithmeticSquareRoot_green = qSqrt(squareRoot_green / vector.count());
|
||||
qreal arithmeticSquareRoot_blue = qSqrt(squareRoot_blue / vector.count());
|
||||
return arithmeticSquareRoot_red < 2.0 && arithmeticSquareRoot_green < 2.0 && arithmeticSquareRoot_blue < 2.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool HighLightEffect::setMenuIconHighlightEffect(QMenu *menu, HighLightMode hlmode, EffectMode mode)
|
||||
{
|
||||
if (!menu)
|
||||
return false;
|
||||
|
||||
menu->setProperty("useIconHighlightEffect", hlmode);
|
||||
menu->setProperty("iconHighlightEffectMode", mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HighLightEffect::setViewItemIconHighlightEffect(QAbstractItemView *view, HighLightMode hlmode, EffectMode mode)
|
||||
{
|
||||
if (!view)
|
||||
return false;
|
||||
|
||||
view->viewport()->setProperty("useIconHighlightEffect", hlmode);
|
||||
view->viewport()->setProperty("iconHighlightEffectMode", mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
HighLightEffect::HighLightMode HighLightEffect::isWidgetIconUseHighlightEffect(const QWidget *w)
|
||||
{
|
||||
if (w) {
|
||||
if (w->property("useIconHighlightEffect").isValid())
|
||||
return HighLightMode(w->property("useIconHighlightEffect").toInt());
|
||||
}
|
||||
return HighLightEffect::skipHighlight;
|
||||
}
|
||||
|
||||
void HighLightEffect::setSymoblicColor(const QColor &color)
|
||||
{
|
||||
qApp->setProperty("symbolicColor", color);
|
||||
symbolic_color = color;
|
||||
}
|
||||
|
||||
void HighLightEffect::setWidgetIconFillSymbolicColor(QWidget *widget, bool fill)
|
||||
{
|
||||
widget->setProperty("fillIconSymbolicColor", fill);
|
||||
}
|
||||
|
||||
const QColor HighLightEffect::getCurrentSymbolicColor()
|
||||
{
|
||||
QIcon symbolic = QIcon::fromTheme("window-new-symbolic");
|
||||
QPixmap pix = symbolic.pixmap(QSize(16, 16));
|
||||
QImage img = pix.toImage();
|
||||
for (int x = 0; x < img.width(); x++) {
|
||||
for (int y = 0; y < img.height(); y++) {
|
||||
QColor color = img.pixelColor(x, y);
|
||||
if (color.alpha() > 0) {
|
||||
symbolic_color = color;
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
return symbolic_color;
|
||||
}
|
||||
|
||||
const QColor HighLightEffect::defaultStyleDark(const QStyleOption *option)
|
||||
{
|
||||
auto windowText = qApp->palette().windowText().color();
|
||||
qreal h, s, v;
|
||||
|
||||
if (option) {
|
||||
windowText = option->palette.windowText().color();
|
||||
}
|
||||
|
||||
windowText.getHsvF(&h, &s, &v);
|
||||
return QColor::fromHsvF(h, s, v);
|
||||
}
|
||||
|
||||
QPixmap HighLightEffect::generatePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget, bool force, EffectMode mode)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
return pixmap;
|
||||
if (!(option->state & QStyle::State_Enabled))
|
||||
return pixmap;
|
||||
if (widget && !widget->isEnabled())
|
||||
return pixmap;
|
||||
|
||||
QPixmap target = pixmap;
|
||||
bool isPurePixmap = isPixmapPureColor(pixmap);
|
||||
if (force) {
|
||||
if (!isPurePixmap)
|
||||
return pixmap;
|
||||
|
||||
QPainter p(&target);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
if (option->state & QStyle::State_MouseOver ||
|
||||
option->state & QStyle::State_Selected ||
|
||||
option->state & QStyle::State_On ||
|
||||
option->state & QStyle::State_Sunken) {
|
||||
p.fillRect(target.rect(), option->palette.highlightedText());
|
||||
} else {
|
||||
p.fillRect(target.rect(), mode ? option->palette.text() : defaultStyleDark(option));
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!widget) {
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
if (widget->property("skipHighlightIconEffect").isValid()) {
|
||||
bool skipEffect = widget->property("skipHighlightIconEffect").toBool();
|
||||
if (skipEffect)
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
if (widget->property("iconHighlightEffectMode").isValid()) {
|
||||
mode = EffectMode(widget->property("iconHighlightEffectMode").toBool());
|
||||
}
|
||||
|
||||
HighLightMode hlmode = isWidgetIconUseHighlightEffect(widget);
|
||||
|
||||
if (hlmode == skipHighlight) {
|
||||
return pixmap;
|
||||
} else if (hlmode == HighlightEffect) {
|
||||
bool fillIconSymbolicColor = false;
|
||||
if (widget->property("fillIconSymbolicColor").isValid()) {
|
||||
fillIconSymbolicColor = widget->property("fillIconSymbolicColor").toBool();
|
||||
}
|
||||
|
||||
bool isEnable = option->state.testFlag(QStyle::State_Enabled);
|
||||
bool overOrDown = option->state.testFlag(QStyle::State_MouseOver) ||
|
||||
option->state.testFlag(QStyle::State_Sunken) ||
|
||||
option->state.testFlag(QStyle::State_On) ||
|
||||
option->state.testFlag(QStyle::State_Selected);
|
||||
|
||||
if (qobject_cast<const QAbstractItemView *>(widget)) {
|
||||
if (!option->state.testFlag(QStyle::State_Selected))
|
||||
overOrDown = false;
|
||||
}
|
||||
|
||||
if (isEnable && overOrDown) {
|
||||
if (fillIconSymbolicColor) {
|
||||
target = filledSymbolicColoredPixmap(pixmap, option->palette.highlightedText().color());
|
||||
}
|
||||
|
||||
if (!isPurePixmap)
|
||||
return target;
|
||||
|
||||
QPainter p(&target);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
p.fillRect(target.rect(), option->palette.highlightedText());
|
||||
return target;
|
||||
} else {
|
||||
QPixmap target = pixmap;
|
||||
if (fillIconSymbolicColor) {
|
||||
target = filledSymbolicColoredPixmap(pixmap, option->palette.highlightedText().color());
|
||||
}
|
||||
if (!isPurePixmap)
|
||||
return target;
|
||||
|
||||
QPainter p(&target);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
p.fillRect(target.rect(), mode ? option->palette.text() : defaultStyleDark(option));
|
||||
return target;
|
||||
}
|
||||
} else if (hlmode == ordinaryHighLight) {
|
||||
return ordinaryGeneratePixmap(pixmap, option, widget, mode);
|
||||
} else if (hlmode == hoverHighLight) {
|
||||
return hoverGeneratePixmap(pixmap, option, widget);
|
||||
} else if (hlmode == defaultHighLight) {
|
||||
return bothOrdinaryAndHoverGeneratePixmap(pixmap, option, widget, mode);
|
||||
} else if (hlmode == filledSymbolicColorHighLight) {
|
||||
if (isPurePixmap) {
|
||||
return bothOrdinaryAndHoverGeneratePixmap(pixmap, option, widget, mode);
|
||||
} else {
|
||||
return filledSymbolicColoredGeneratePixmap(pixmap, option, widget, mode);
|
||||
}
|
||||
} else {
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPixmap HighLightEffect::ordinaryGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget, EffectMode mode)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
return pixmap;
|
||||
if (!isPixmapPureColor(pixmap) || !(option->state & QStyle::State_Enabled))
|
||||
return pixmap;
|
||||
|
||||
QPixmap target = pixmap;
|
||||
QColor color;
|
||||
if (widget && widget->property("setIconHighlightEffectDefaultColor").isValid() && widget->property("setIconHighlightEffectDefaultColor").canConvert<QColor>()) {
|
||||
color = widget->property("setIconHighlightEffectDefaultColor").value<QColor>();
|
||||
}
|
||||
|
||||
if (widget && widget->property("iconHighlightEffectMode").isValid()) {
|
||||
mode = EffectMode(widget->property("iconHighlightEffectMode").toBool());
|
||||
}
|
||||
|
||||
QPainter p(&target);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
p.fillRect(target.rect(), color.isValid() ? color : (mode ? option->palette.text() : defaultStyleDark(option)));
|
||||
return target;
|
||||
}
|
||||
|
||||
QPixmap HighLightEffect::hoverGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget, EffectMode mode)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
return pixmap;
|
||||
if (!isPixmapPureColor(pixmap) || !(option->state & QStyle::State_Enabled))
|
||||
return pixmap;
|
||||
|
||||
QPixmap target = pixmap;
|
||||
QColor color;
|
||||
if (widget && widget->property("setIconHighlightEffectHoverColor").isValid() && widget->property("setIconHighlightEffectHoverColor").canConvert<QColor>()) {
|
||||
color = widget->property("setIconHighlightEffectHoverColor").value<QColor>();
|
||||
}
|
||||
|
||||
if (widget && widget->property("iconHighlightEffectMode").isValid()) {
|
||||
mode = EffectMode(widget->property("iconHighlightEffectMode").toBool());
|
||||
}
|
||||
|
||||
bool overOrDown = option->state.testFlag(QStyle::State_MouseOver) ||
|
||||
option->state.testFlag(QStyle::State_Sunken) ||
|
||||
option->state.testFlag(QStyle::State_On) ||
|
||||
option->state.testFlag(QStyle::State_Selected);
|
||||
if (qobject_cast<const QAbstractItemView *>(widget)) {
|
||||
if (!option->state.testFlag(QStyle::State_Selected))
|
||||
overOrDown = false;
|
||||
}
|
||||
|
||||
QPainter p(&target);
|
||||
if (overOrDown) {
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
p.fillRect(target.rect(), color.isValid() ? color : option->palette.highlightedText());
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
QPixmap HighLightEffect::bothOrdinaryAndHoverGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget, EffectMode mode)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
return pixmap;
|
||||
if (!isPixmapPureColor(pixmap) || !(option->state & QStyle::State_Enabled))
|
||||
return pixmap;
|
||||
|
||||
QPixmap target = pixmap;
|
||||
QColor defaultColor, hoverColor;
|
||||
if (widget && widget->property("setIconHighlightEffectDefaultColor").isValid() && widget->property("setIconHighlightEffectDefaultColor").canConvert<QColor>()) {
|
||||
defaultColor = widget->property("setIconHighlightEffectDefaultColor").value<QColor>();
|
||||
}
|
||||
if (widget && widget->property("setIconHighlightEffectHoverColor").isValid() && widget->property("setIconHighlightEffectHoverColor").canConvert<QColor>()) {
|
||||
hoverColor = widget->property("setIconHighlightEffectHoverColor").value<QColor>();
|
||||
}
|
||||
|
||||
if (widget && widget->property("iconHighlightEffectMode").isValid()) {
|
||||
mode = EffectMode(widget->property("iconHighlightEffectMode").toBool());
|
||||
}
|
||||
|
||||
bool overOrDown = option->state.testFlag(QStyle::State_MouseOver) ||
|
||||
option->state.testFlag(QStyle::State_Sunken) ||
|
||||
option->state.testFlag(QStyle::State_On) ||
|
||||
option->state.testFlag(QStyle::State_Selected);
|
||||
if (qobject_cast<const QAbstractItemView *>(widget)) {
|
||||
if (!option->state.testFlag(QStyle::State_Selected))
|
||||
overOrDown = false;
|
||||
}
|
||||
|
||||
QPainter p(&target);
|
||||
if (overOrDown) {
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
p.fillRect(target.rect(), hoverColor.isValid() ? hoverColor : option->palette.highlightedText());
|
||||
} else {
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
p.fillRect(target.rect(), defaultColor.isValid() ? defaultColor : (mode ? option->palette.text() : defaultStyleDark(option)));
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
QPixmap HighLightEffect::filledSymbolicColoredGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget, EffectMode mode)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
return pixmap;
|
||||
if (isPixmapPureColor(pixmap))
|
||||
return bothOrdinaryAndHoverGeneratePixmap(pixmap, option, widget, mode);
|
||||
|
||||
QPixmap target = pixmap;
|
||||
QColor defaultColor, hoverColor;
|
||||
if (widget && widget->property("setIconHighlightEffectDefaultColor").isValid() && widget->property("setIconHighlightEffectDefaultColor").canConvert<QColor>()) {
|
||||
defaultColor = widget->property("setIconHighlightEffectDefaultColor").value<QColor>();
|
||||
}
|
||||
if (widget && widget->property("setIconHighlightEffectHoverColor").isValid() && widget->property("setIconHighlightEffectHoverColor").canConvert<QColor>()) {
|
||||
hoverColor = widget->property("setIconHighlightEffectHoverColor").value<QColor>();
|
||||
}
|
||||
|
||||
if (widget && widget->property("iconHighlightEffectMode").isValid()) {
|
||||
mode = EffectMode(widget->property("iconHighlightEffectMode").toBool());
|
||||
}
|
||||
bool isEnable = option->state.testFlag(QStyle::State_Enabled);
|
||||
bool overOrDown = option->state.testFlag(QStyle::State_MouseOver) ||
|
||||
option->state.testFlag(QStyle::State_Sunken) ||
|
||||
option->state.testFlag(QStyle::State_On) ||
|
||||
option->state.testFlag(QStyle::State_Selected);
|
||||
if (qobject_cast<const QAbstractItemView *>(widget)) {
|
||||
if (!option->state.testFlag(QStyle::State_Selected))
|
||||
overOrDown = false;
|
||||
}
|
||||
|
||||
if (isEnable && overOrDown) {
|
||||
return filledSymbolicColoredPixmap(target, hoverColor.isValid() ? hoverColor : option->palette.color(QPalette::HighlightedText));
|
||||
} else {
|
||||
return filledSymbolicColoredPixmap(target, defaultColor.isValid() ? defaultColor : (mode ? option->palette.color(QPalette::Text) : defaultStyleDark(option)));
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
HighLightEffect::HighLightEffect(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QPixmap HighLightEffect::filledSymbolicColoredPixmap(const QPixmap &source, const QColor &baseColor)
|
||||
{
|
||||
if (source.isNull())
|
||||
return source;
|
||||
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.3) {
|
||||
if (qAbs(color.red() - symbolic_color.red()) < 10 && qAbs(color.green() - symbolic_color.green()) < 10
|
||||
&& qAbs(color.blue() - symbolic_color.blue()) < 10) {
|
||||
color.setRed(baseColor.red());
|
||||
color.setGreen(baseColor.green());
|
||||
color.setBlue(baseColor.blue());
|
||||
img.setPixelColor(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return QPixmap::fromImage(img);
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HIGHLIGHTEFFECT_H
|
||||
#define HIGHLIGHTEFFECT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStyleOption>
|
||||
|
||||
class QAbstractItemView;
|
||||
class QMenu;
|
||||
|
||||
class HighLightEffect : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum HighLightMode {
|
||||
skipHighlight = 0x0,
|
||||
HighlightEffect = 0x1,
|
||||
ordinaryHighLight = 0x2,
|
||||
hoverHighLight = 0x4,
|
||||
defaultHighLight = 0x8,
|
||||
filledSymbolicColorHighLight = 0x10,
|
||||
};
|
||||
|
||||
enum EffectMode {
|
||||
HighlightOnly = 0x0,
|
||||
BothDefaultAndHighlit = 0x1
|
||||
};
|
||||
Q_ENUM(EffectMode)
|
||||
|
||||
/*!
|
||||
* \brief setSkipEffect
|
||||
* \param w
|
||||
* \param skip
|
||||
* \details
|
||||
* in ukui-style, some widget such as menu will be set use highlight
|
||||
* icon effect automaticlly,
|
||||
* but we might not want to compose a special pure color image.
|
||||
* This function is use to skip the effect.
|
||||
*/
|
||||
static QColor symbolic_color;
|
||||
static void setSkipEffect(QWidget *w, bool skip = true);
|
||||
static bool isPixmapPureColor(const QPixmap &pixmap);
|
||||
static bool setMenuIconHighlightEffect(QMenu *menu, HighLightMode hlmode = skipHighlight, EffectMode mode = HighlightOnly);
|
||||
static bool setViewItemIconHighlightEffect(QAbstractItemView *view, HighLightMode hlmode = skipHighlight, EffectMode mode = HighlightOnly);
|
||||
static HighLightMode isWidgetIconUseHighlightEffect(const QWidget *w);
|
||||
|
||||
static void setSymoblicColor(const QColor &color);
|
||||
static void setWidgetIconFillSymbolicColor(QWidget *widget, bool fill);
|
||||
|
||||
static const QColor getCurrentSymbolicColor();
|
||||
static const QColor defaultStyleDark(const QStyleOption *option);
|
||||
|
||||
static QPixmap generatePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget = nullptr, bool force = false, EffectMode mode = HighlightOnly);
|
||||
static QPixmap ordinaryGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget = nullptr, EffectMode mode = HighlightOnly);
|
||||
static QPixmap hoverGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget = nullptr, EffectMode mode = HighlightOnly);
|
||||
static QPixmap bothOrdinaryAndHoverGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget = nullptr, EffectMode mode = HighlightOnly);
|
||||
static QPixmap filledSymbolicColoredGeneratePixmap(const QPixmap &pixmap, const QStyleOption *option, const QWidget *widget = nullptr, EffectMode mode = HighlightOnly);
|
||||
|
||||
private:
|
||||
explicit HighLightEffect(QObject *parent = nullptr);
|
||||
|
||||
static QPixmap filledSymbolicColoredPixmap(const QPixmap &source, const QColor &baseColor);
|
||||
};
|
||||
|
||||
#endif // HIGHLIGHTEFFECT_H
|
|
@ -0,0 +1,10 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/..
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/ukui-two-finger-slide-gesture.h \
|
||||
$$PWD/ukui-two-finger-zoom-gesture.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/ukui-two-finger-slide-gesture.cpp \
|
||||
$$PWD/ukui-two-finger-zoom-gesture.cpp
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ukui-two-finger-slide-gesture.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <QTouchEvent>
|
||||
#include <QtMath>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace UKUI;
|
||||
|
||||
TwoFingerSlideGesture::TwoFingerSlideGesture(QObject *parent) : QGesture(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int TwoFingerSlideGesture::delta()
|
||||
{
|
||||
switch (m_direction) {
|
||||
case Horizal:
|
||||
return m_current_pos.x() - m_last_pos.x();
|
||||
case Vertical:
|
||||
return m_current_pos.y() - m_last_pos.y();
|
||||
case Invalid:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TwoFingerSlideGesture::totalDelta()
|
||||
{
|
||||
switch (m_direction) {
|
||||
case Horizal:
|
||||
return m_current_pos.x() - m_start_pos.x();
|
||||
case Vertical:
|
||||
return m_current_pos.y() - m_start_pos.y();
|
||||
case Invalid:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TwoFingerSlideGestureRecognizer::TwoFingerSlideGestureRecognizer() : QGestureRecognizer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QGesture *TwoFingerSlideGestureRecognizer::create(QObject *target)
|
||||
{
|
||||
//qDebug()<<"create";
|
||||
if (target && target->isWidgetType())
|
||||
static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
return new TwoFingerSlideGesture;
|
||||
}
|
||||
|
||||
QGestureRecognizer::Result TwoFingerSlideGestureRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event)
|
||||
{
|
||||
if (auto touchEvent = static_cast<QTouchEvent *>(event)) {
|
||||
auto slideGesture = static_cast<TwoFingerSlideGesture *>(gesture);
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin: {
|
||||
slideGesture->m_start_pos = touchEvent->touchPoints().first().pos().toPoint();
|
||||
slideGesture->m_current_pos = touchEvent->touchPoints().first().pos().toPoint();
|
||||
slideGesture->m_last_pos = touchEvent->touchPoints().first().pos().toPoint();
|
||||
gesture->setHotSpot(touchEvent->touchPoints().first().screenPos());
|
||||
return QGestureRecognizer::MayBeGesture;
|
||||
break;
|
||||
}
|
||||
case QEvent::TouchUpdate: {
|
||||
// only support 2 fingers
|
||||
if (touchEvent->touchPoints().count() != 2)
|
||||
return QGestureRecognizer::Ignore;
|
||||
|
||||
if (touchEvent->touchPointStates() & Qt::TouchPointPressed) {
|
||||
if (touchEvent->touchPoints().count() == 2) {
|
||||
// update start point center
|
||||
slideGesture->m_start_pos = (touchEvent->touchPoints().first().pos().toPoint() + touchEvent->touchPoints().last().pos().toPoint())/2;
|
||||
//qDebug()<<"update start point"<<slideGesture->startPos();
|
||||
return QGestureRecognizer::MayBeGesture;
|
||||
}
|
||||
}
|
||||
|
||||
if (touchEvent->touchPointStates() & Qt::TouchPointMoved) {
|
||||
// initial slide gesture direction, note that
|
||||
// once direction ensured, it will not be changed
|
||||
// untill the gesture finished or cancelled.
|
||||
if (slideGesture->direction() == TwoFingerSlideGesture::Invalid) {
|
||||
qreal distance = (touchEvent->touchPoints().first().pos().toPoint() - touchEvent->touchPoints().last().pos().toPoint()).manhattanLength();
|
||||
// we should distinguish slide and pinch zoom gesture.
|
||||
if (distance > 200)
|
||||
return QGestureRecognizer::Ignore;
|
||||
|
||||
QPoint offset = (touchEvent->touchPoints().first().pos().toPoint() + touchEvent->touchPoints().last().pos().toPoint())/2 - slideGesture->startPos();
|
||||
//qDebug()<<offset;
|
||||
if (qAbs(offset.y()) > 50) {
|
||||
slideGesture->m_direction = TwoFingerSlideGesture::Vertical;
|
||||
slideGesture->m_current_pos = touchEvent->touchPoints().first().pos().toPoint();
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
} else if (qAbs(offset.x()) > 50) {
|
||||
slideGesture->m_direction = TwoFingerSlideGesture::Horizal;
|
||||
slideGesture->m_current_pos = touchEvent->touchPoints().first().pos().toPoint();
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
} else {
|
||||
// if offset set not enough, ignore.
|
||||
return QGestureRecognizer::Ignore;
|
||||
}
|
||||
} else {
|
||||
// update gesture
|
||||
slideGesture->m_last_pos = slideGesture->m_current_pos;
|
||||
slideGesture->m_current_pos = touchEvent->touchPoints().first().pos().toPoint();
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case QEvent::TouchEnd: {
|
||||
reset(slideGesture);
|
||||
return QGestureRecognizer::FinishGesture;
|
||||
}
|
||||
case QEvent::TouchCancel: {
|
||||
reset(slideGesture);
|
||||
return QGestureRecognizer::CancelGesture;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QGestureRecognizer::Ignore;
|
||||
}
|
||||
|
||||
void TwoFingerSlideGestureRecognizer::reset(QGesture *gesture)
|
||||
{
|
||||
//qDebug()<<"reset";
|
||||
auto slideGesture = static_cast<TwoFingerSlideGesture *>(gesture);
|
||||
slideGesture->m_current_pos = QPoint();
|
||||
slideGesture->m_last_pos = QPoint();
|
||||
slideGesture->m_start_pos = QPoint();
|
||||
slideGesture->m_direction = TwoFingerSlideGesture::Invalid;
|
||||
QGestureRecognizer::reset(gesture);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWOFINGERSLIDEGESTURE_H
|
||||
#define TWOFINGERSLIDEGESTURE_H
|
||||
|
||||
#include <QGesture>
|
||||
#include <QGestureRecognizer>
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
class TwoFingerSlideGesture : public QGesture
|
||||
{
|
||||
friend class TwoFingerSlideGestureRecognizer;
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Direction {
|
||||
Invalid,
|
||||
Horizal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
explicit TwoFingerSlideGesture(QObject *parent = nullptr);
|
||||
|
||||
Direction direction() {return m_direction;}
|
||||
const QPoint startPos() {return m_start_pos;}
|
||||
const QPoint currentPos() {return m_current_pos;}
|
||||
int delta();
|
||||
int totalDelta();
|
||||
|
||||
private:
|
||||
QPoint m_start_pos;
|
||||
QPoint m_last_pos;
|
||||
QPoint m_current_pos;
|
||||
|
||||
Direction m_direction = Invalid;
|
||||
};
|
||||
|
||||
class TwoFingerSlideGestureRecognizer : public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
explicit TwoFingerSlideGestureRecognizer();
|
||||
|
||||
QGesture *create(QObject *target) override;
|
||||
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
|
||||
void reset(QGesture *gesture) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWOFINGERSLIDEGESTURE_H
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ukui-two-finger-zoom-gesture.h"
|
||||
|
||||
#include <QTouchEvent>
|
||||
#include <QtMath>
|
||||
#include <QWidget>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace UKUI;
|
||||
|
||||
TwoFingerZoomGesture::TwoFingerZoomGesture(QObject *parent) : QGesture(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UKUI::TwoFingerZoomGestureRecognizer::TwoFingerZoomGestureRecognizer() : QGestureRecognizer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QGesture *TwoFingerZoomGestureRecognizer::create(QObject *target)
|
||||
{
|
||||
if (target && target->isWidgetType())
|
||||
static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
return new TwoFingerZoomGesture;
|
||||
}
|
||||
|
||||
QGestureRecognizer::Result TwoFingerZoomGestureRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event)
|
||||
{
|
||||
if (auto touchEvent = static_cast<QTouchEvent *>(event)) {
|
||||
auto zoomGesture = static_cast<TwoFingerZoomGesture *>(gesture);
|
||||
|
||||
switch (touchEvent->type()) {
|
||||
case QEvent::TouchBegin:
|
||||
gesture->setHotSpot(touchEvent->touchPoints().first().screenPos());
|
||||
return QGestureRecognizer::MayBeGesture;
|
||||
break;
|
||||
case QEvent::TouchUpdate: {
|
||||
if (touchEvent->touchPoints().count() != 2)
|
||||
return QGestureRecognizer::Ignore;
|
||||
|
||||
switch (zoomGesture->zoomDirection()) {
|
||||
case TwoFingerZoomGesture::Invalid: {
|
||||
zoomGesture->m_start_points.first = touchEvent->touchPoints().first().pos().toPoint();
|
||||
zoomGesture->m_start_points.second = touchEvent->touchPoints().last().pos().toPoint();
|
||||
zoomGesture->m_last_points = zoomGesture->m_start_points;
|
||||
zoomGesture->m_current_points = zoomGesture->m_start_points;
|
||||
|
||||
zoomGesture->m_start_points_distance = (zoomGesture->m_start_points.first - zoomGesture->m_start_points.second).manhattanLength();
|
||||
zoomGesture->m_last_points_distance = zoomGesture->m_start_points_distance;
|
||||
|
||||
zoomGesture->m_zoom_direction = TwoFingerZoomGesture::Unkown;
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
}
|
||||
case TwoFingerZoomGesture::Unkown: {
|
||||
zoomGesture->m_last_points = zoomGesture->m_current_points;
|
||||
zoomGesture->m_current_points.first = touchEvent->touchPoints().first().pos().toPoint();
|
||||
zoomGesture->m_current_points.second = touchEvent->touchPoints().last().pos().toPoint();
|
||||
|
||||
qreal currentPointsDistance = (zoomGesture->m_current_points.first - zoomGesture->m_current_points.second).manhattanLength();
|
||||
qreal totalDelta = currentPointsDistance - zoomGesture->m_start_points_distance;
|
||||
|
||||
//qDebug()<<zoomGesture->m_start_points_distance<<currentPointsDistance<<totalDelta;
|
||||
|
||||
// only total delta is enough the gesture would be triggered.
|
||||
// note that once zoom direction ensured, it won't change until
|
||||
// the gesture cancelled.
|
||||
if (qAbs(totalDelta) > 100) {
|
||||
zoomGesture->m_last_points_distance = currentPointsDistance;
|
||||
if (totalDelta > 0) {
|
||||
zoomGesture->m_zoom_direction = TwoFingerZoomGesture::ZoomIn;
|
||||
} else {
|
||||
zoomGesture->m_zoom_direction = TwoFingerZoomGesture::ZoomOut;
|
||||
}
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
} else {
|
||||
return QGestureRecognizer::MayBeGesture;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TwoFingerZoomGesture::ZoomIn: {
|
||||
// check if gesture should trigger or cancel
|
||||
auto tmp = zoomGesture->m_current_points;
|
||||
zoomGesture->m_current_points.first = touchEvent->touchPoints().first().pos().toPoint();
|
||||
zoomGesture->m_current_points.second = touchEvent->touchPoints().last().pos().toPoint();
|
||||
qreal currentPointsDistance = (zoomGesture->m_current_points.first - zoomGesture->m_current_points.second).manhattanLength();
|
||||
qreal distanceOffset = currentPointsDistance - zoomGesture->m_last_points_distance;
|
||||
if (distanceOffset > 0) {
|
||||
// trigger zoom in
|
||||
zoomGesture->m_last_points = tmp;
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
} else {
|
||||
if (qAbs(distanceOffset) < 100) {
|
||||
return QGestureRecognizer::Ignore;
|
||||
} else {
|
||||
return QGestureRecognizer::CancelGesture;
|
||||
}
|
||||
}
|
||||
}
|
||||
case TwoFingerZoomGesture::ZoomOut: {
|
||||
// check if gesture should trigger or cancel
|
||||
auto tmp = zoomGesture->m_current_points;
|
||||
zoomGesture->m_current_points.first = touchEvent->touchPoints().first().pos().toPoint();
|
||||
zoomGesture->m_current_points.second = touchEvent->touchPoints().last().pos().toPoint();
|
||||
qreal currentPointsDistance = (zoomGesture->m_current_points.first - zoomGesture->m_current_points.second).manhattanLength();
|
||||
qreal distanceOffset = currentPointsDistance - zoomGesture->m_last_points_distance;
|
||||
if (distanceOffset < 0) {
|
||||
// trigger zoom out
|
||||
zoomGesture->m_last_points = tmp;
|
||||
return QGestureRecognizer::TriggerGesture;
|
||||
} else {
|
||||
if (qAbs(distanceOffset) < 100) {
|
||||
return QGestureRecognizer::Ignore;
|
||||
} else {
|
||||
return QGestureRecognizer::CancelGesture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::TouchCancel:
|
||||
reset(gesture);
|
||||
return QGestureRecognizer::CancelGesture;
|
||||
|
||||
case QEvent::TouchEnd:
|
||||
reset(gesture);
|
||||
return QGestureRecognizer::FinishGesture;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QGestureRecognizer::Ignore;
|
||||
}
|
||||
|
||||
void TwoFingerZoomGestureRecognizer::reset(QGesture *gesture)
|
||||
{
|
||||
auto zoomGesture = static_cast<TwoFingerZoomGesture *>(gesture);
|
||||
zoomGesture->m_start_points.first = QPoint();
|
||||
zoomGesture->m_start_points.second = QPoint();
|
||||
zoomGesture->m_current_points.first = QPoint();
|
||||
zoomGesture->m_current_points.second = QPoint();
|
||||
zoomGesture->m_zoom_direction = TwoFingerZoomGesture::Invalid;
|
||||
QGestureRecognizer::reset(gesture);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWOFINGERZOOMGESTURE_H
|
||||
#define TWOFINGERZOOMGESTURE_H
|
||||
|
||||
#include <QGesture>
|
||||
#include <QGestureRecognizer>
|
||||
|
||||
#include <QPair>
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
class TwoFingerZoomGesture : public QGesture
|
||||
{
|
||||
friend class TwoFingerZoomGestureRecognizer;
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Direction {
|
||||
Invalid,
|
||||
Unkown,
|
||||
ZoomIn,
|
||||
ZoomOut
|
||||
};
|
||||
|
||||
explicit TwoFingerZoomGesture(QObject *parent = nullptr);
|
||||
|
||||
Direction zoomDirection() {return m_zoom_direction;}
|
||||
QPair<QPoint, QPoint> startPoints() {return m_start_points;}
|
||||
QPair<QPoint, QPoint> lastPoints() {return m_last_points;}
|
||||
QPair<QPoint, QPoint> currentPoints() {return m_current_points;}
|
||||
|
||||
private:
|
||||
QPair<QPoint, QPoint> m_start_points;
|
||||
QPair<QPoint, QPoint> m_last_points;
|
||||
QPair<QPoint, QPoint> m_current_points;
|
||||
|
||||
qreal m_start_points_distance = -1;
|
||||
qreal m_last_points_distance = -1;
|
||||
|
||||
Direction m_zoom_direction = Invalid;
|
||||
};
|
||||
|
||||
class TwoFingerZoomGestureRecognizer : public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
explicit TwoFingerZoomGestureRecognizer();
|
||||
|
||||
QGesture *create(QObject *target) override;
|
||||
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
|
||||
void reset(QGesture *gesture) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TWOFINGERZOOMGESTURE_H
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "internal-style.h"
|
||||
|
||||
InternalStyle::InternalStyle(QStyle *parentStyle) : QProxyStyle (parentStyle)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
InternalStyle::InternalStyle(const QString parentStyleName) : QProxyStyle(parentStyleName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void InternalStyle::setUseSystemStyle(bool use)
|
||||
{
|
||||
Q_EMIT useSystemStylePolicyChanged(use);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INTERNALSTYLE_H
|
||||
#define INTERNALSTYLE_H
|
||||
|
||||
#include <QProxyStyle>
|
||||
|
||||
/*!
|
||||
* \brief The InternalStyle class
|
||||
* \details
|
||||
* This class is a interface type class. It is desgined as an extension of UKUI theme
|
||||
* frameworks. Applications which use internal style means that there will be no effect
|
||||
* when system theme switched, for example, from fusion to ukui-white.
|
||||
* But an internal style usually should response the palette settings changed for
|
||||
* keeping the unity as a desktop environment theme's extensions.
|
||||
*
|
||||
* The typical example which implement the internal style is MPSStyle.
|
||||
*/
|
||||
class InternalStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InternalStyle(QStyle *parentStyle = nullptr);
|
||||
explicit InternalStyle(const QString parentStyleName);
|
||||
|
||||
signals:
|
||||
void useSystemStylePolicyChanged(bool use);
|
||||
|
||||
public slots:
|
||||
virtual void setUseSystemStyle(bool use);
|
||||
};
|
||||
|
||||
#endif // INTERNALSTYLE_H
|
|
@ -0,0 +1,8 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/..
|
||||
|
||||
SOURCES += $$PWD/internal-style.cpp \
|
||||
$$PWD/mps-style.cpp
|
||||
|
||||
HEADERS += $$PWD/internal-style.h \
|
||||
$$PWD/mps-style.h
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mps-style.h"
|
||||
|
||||
MPSStyle::MPSStyle(bool dark) : InternalStyle ("fusion")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MPSStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::drawComplexControl(control, option, painter, widget);
|
||||
}
|
||||
|
||||
void MPSStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::drawControl(element, option, painter, widget);
|
||||
}
|
||||
|
||||
void MPSStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::drawItemPixmap(painter, rectangle, alignment, pixmap);
|
||||
}
|
||||
|
||||
void MPSStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole) const
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::drawItemText(painter, rectangle, alignment, palette, enabled, text, textRole);
|
||||
}
|
||||
|
||||
void MPSStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
||||
}
|
||||
|
||||
QPixmap MPSStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::generatedIconPixmap(iconMode, pixmap, option);
|
||||
}
|
||||
|
||||
QStyle::SubControl MPSStyle::hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::hitTestComplexControl(control, option, position, widget);
|
||||
}
|
||||
|
||||
QRect MPSStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::itemPixmapRect(rectangle, alignment, pixmap);
|
||||
}
|
||||
|
||||
QRect MPSStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::itemTextRect(metrics, rectangle, alignment, enabled, text);
|
||||
}
|
||||
|
||||
int MPSStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::pixelMetric(metric, option, widget);
|
||||
}
|
||||
|
||||
void MPSStyle::polish(QWidget *widget)
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::polish(widget);
|
||||
}
|
||||
|
||||
void MPSStyle::polish(QApplication *application)
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::polish(application);
|
||||
}
|
||||
|
||||
void MPSStyle::polish(QPalette &palette)
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::polish(palette);
|
||||
}
|
||||
|
||||
void MPSStyle::unpolish(QWidget *widget)
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::unpolish(widget);
|
||||
}
|
||||
|
||||
void MPSStyle::unpolish(QApplication *application)
|
||||
{
|
||||
//FIXME:
|
||||
QProxyStyle::unpolish(application);
|
||||
}
|
||||
|
||||
QSize MPSStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::sizeFromContents(type, option, contentsSize, widget);
|
||||
}
|
||||
|
||||
QIcon MPSStyle::standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::standardIcon(standardIcon, option, widget);
|
||||
}
|
||||
|
||||
QPalette MPSStyle::standardPalette() const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::standardPalette();
|
||||
}
|
||||
|
||||
int MPSStyle::styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
}
|
||||
|
||||
QRect MPSStyle::subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::subControlRect(control, option, subControl, widget);
|
||||
}
|
||||
|
||||
QRect MPSStyle::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const
|
||||
{
|
||||
//FIXME:
|
||||
return QProxyStyle::subElementRect(element, option, widget);
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MPSSTYLE_H
|
||||
#define MPSSTYLE_H
|
||||
|
||||
#include "internal-style.h"
|
||||
|
||||
/*!
|
||||
* \brief The MPSStyle class
|
||||
* \details
|
||||
* M(enu)P(anel)S(idebar)Style is an internal style shared in several
|
||||
* UKUI desktop applications, such as UKUI Menu, UKUI Panel and UKUI Sidebar, etc.
|
||||
*
|
||||
* Usually, applications use the styles which have been installed as qstyle plugin in
|
||||
* UKUI desktop environment, such as ukui-white and ukui-black. However one style may
|
||||
* be not enough for UKUI3.0 desgin. The menu, panel and sidebar desgin is Noticeably
|
||||
* different from the common style which we used in peony or other qt's applications.
|
||||
* To integrate the unique style into the theme, I came up the idea of internal styles,
|
||||
* and combine them with current platform theme's frameworks. So it will Looks like a
|
||||
* whole style.
|
||||
*
|
||||
* \see InternalStyle
|
||||
*/
|
||||
class MPSStyle : public InternalStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MPSStyle(bool dark = true);
|
||||
|
||||
void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const;
|
||||
void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const;
|
||||
void drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const;
|
||||
void drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
|
||||
void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const;
|
||||
|
||||
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const;
|
||||
QStyle::SubControl hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget = nullptr) const;
|
||||
QRect itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const;
|
||||
QRect itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const;
|
||||
//virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget);
|
||||
int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const;
|
||||
|
||||
void polish(QWidget *widget);
|
||||
void polish(QApplication *application);
|
||||
void polish(QPalette &palette);
|
||||
void unpolish(QWidget *widget);
|
||||
void unpolish(QApplication *application);
|
||||
|
||||
QSize sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget = nullptr) const;
|
||||
QIcon standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
|
||||
QPalette standardPalette() const;
|
||||
int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const;
|
||||
QRect subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget = nullptr) const;
|
||||
QRect subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget = nullptr) const;
|
||||
};
|
||||
|
||||
#endif // MPSSTYLE_H
|
|
@ -0,0 +1,7 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
include(animations/animations.pri)
|
||||
include(settings/settings.pri)
|
||||
include(internal-styles/internal-styles.pri)
|
||||
include(effects/effects.pri)
|
||||
include(gestures/gestures.pri)
|
|
@ -0,0 +1,46 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2020-01-02T12:00:35
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += widgets concurrent
|
||||
|
||||
TARGET = qt5-ukui-style
|
||||
TEMPLATE = lib
|
||||
|
||||
DEFINES += LIBQT5UKUISTYLE_LIBRARY
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
#DEFINES += QT_NO_DEBUG_OUTPUT
|
||||
DEFINES += QT_MESSAGELOGCONTEXT
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
include(libqt5-ukui-style.pri)
|
||||
|
||||
CONFIG += c++11 link_pkgconfig
|
||||
PKGCONFIG += gsettings-qt
|
||||
|
||||
DISTFILES += \
|
||||
org.ukui.style.gschema.xml
|
||||
|
||||
unix {
|
||||
target.path = $$[QT_INSTALL_LIBS]
|
||||
INSTALLS += target
|
||||
|
||||
gschema.path = /usr/share/glib-2.0/schemas
|
||||
gschema.files += $$PWD/settings/org.ukui.style.gschema.xml
|
||||
INSTALLS += gschema
|
||||
|
||||
pkgconfig.path = $$[QT_INSTALL_LIBS]/pkgconfig
|
||||
pkgconfig.files += development-files/qt5-ukui.pc
|
||||
INSTALLS += pkgconfig
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "application-style-settings.h"
|
||||
#include <QApplication>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QStandardPaths>
|
||||
#include <QStyle>
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
static ApplicationStyleSettings *global_instance = nullptr;
|
||||
|
||||
ApplicationStyleSettings *ApplicationStyleSettings::getInstance()
|
||||
{
|
||||
if (!global_instance)
|
||||
global_instance = new ApplicationStyleSettings;
|
||||
return global_instance;
|
||||
}
|
||||
|
||||
const QString ApplicationStyleSettings::currentCustomStyleName()
|
||||
{
|
||||
if (m_style_stretagy == Default)
|
||||
return nullptr;
|
||||
return m_current_custom_style_name;
|
||||
}
|
||||
|
||||
void ApplicationStyleSettings::setColor(const QPalette::ColorRole &role, const QColor &color, const QPalette::ColorGroup &group)
|
||||
{
|
||||
beginGroup(m_color_group_enum.key(group));
|
||||
setValue(m_color_role_enum.key(role), color);
|
||||
endGroup();
|
||||
QtConcurrent::run([=](){
|
||||
this->sync();
|
||||
});
|
||||
auto palette = QApplication::palette();
|
||||
palette.setColor(group, role, color);
|
||||
QApplication::setPalette(palette);
|
||||
qApp->paletteChanged(palette);
|
||||
}
|
||||
|
||||
const QColor ApplicationStyleSettings::getColor(const QPalette::ColorRole &role, const QPalette::ColorGroup &group)
|
||||
{
|
||||
beginGroup(m_color_role_enum.key(group));
|
||||
auto data = value(m_color_role_enum.key(role));
|
||||
QColor color = qvariant_cast<QColor>(data);
|
||||
endGroup();
|
||||
if (color.isValid())
|
||||
return color;
|
||||
return QApplication::palette().color(group, role);
|
||||
}
|
||||
|
||||
void ApplicationStyleSettings::setColorStretagy(ApplicationStyleSettings::ColorStretagy stretagy)
|
||||
{
|
||||
if (m_color_stretagy != stretagy) {
|
||||
m_color_stretagy = stretagy;
|
||||
setValue("color-stretagy", stretagy);
|
||||
Q_EMIT colorStretageChanged(stretagy);
|
||||
QtConcurrent::run([=](){
|
||||
this->sync();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationStyleSettings::setStyleStretagy(ApplicationStyleSettings::StyleStretagy stretagy)
|
||||
{
|
||||
if (m_style_stretagy != stretagy) {
|
||||
m_style_stretagy = stretagy;
|
||||
setValue("style-stretagy", stretagy);
|
||||
Q_EMIT styleStretageChanged(stretagy);
|
||||
QtConcurrent::run([=](){
|
||||
this->sync();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationStyleSettings::setCustomStyle(const QString &style)
|
||||
{
|
||||
m_current_custom_style_name = style;
|
||||
QApplication::setStyle(style);
|
||||
}
|
||||
|
||||
void ApplicationStyleSettings::refreshData(bool forceSync)
|
||||
{
|
||||
sync();
|
||||
m_custom_palette = QApplication::palette();
|
||||
|
||||
auto color_stretagy = qvariant_cast<ColorStretagy>(value("color-stretagy"));
|
||||
if (color_stretagy != m_color_stretagy) {
|
||||
m_color_stretagy = color_stretagy;
|
||||
Q_EMIT colorStretageChanged(m_color_stretagy);
|
||||
}
|
||||
|
||||
auto style_stretagy = qvariant_cast<StyleStretagy>(value("style-stretagy"));
|
||||
if (style_stretagy != m_style_stretagy) {
|
||||
m_style_stretagy = style_stretagy;
|
||||
Q_EMIT styleStretageChanged(m_style_stretagy);
|
||||
}
|
||||
|
||||
auto current_custom_style_name = value("custom-style").toString();
|
||||
if (m_current_custom_style_name != current_custom_style_name) {
|
||||
m_current_custom_style_name = current_custom_style_name;
|
||||
QApplication::setStyle(m_current_custom_style_name);
|
||||
}
|
||||
|
||||
readPalleteSettings();
|
||||
|
||||
if (forceSync) {
|
||||
QtConcurrent::run([=](){
|
||||
this->sync();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationStyleSettings::readPalleteSettings()
|
||||
{
|
||||
for (int i = 0; i < m_color_group_enum.keyCount(); i++) {
|
||||
beginGroup(m_color_group_enum.key(i));
|
||||
for (int j = 0; j < m_color_role_enum.keyCount(); j++) {
|
||||
auto data = value(m_color_role_enum.key(j));
|
||||
if (data.isValid()) {
|
||||
m_custom_palette.setColor(QPalette::ColorGroup(i),
|
||||
QPalette::ColorRole(j),
|
||||
qvariant_cast<QColor>(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationStyleSettings::ApplicationStyleSettings(QObject *parent) : QSettings(parent)
|
||||
{
|
||||
/*!
|
||||
\todo make settings together into an ini file.
|
||||
*/
|
||||
// QString configFileName = QApplication::organizationDomain() + "." + QApplication::organizationName() + "." + QApplication::applicationName();
|
||||
// QString configDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + "ukui";
|
||||
// QString configPath = configDir + "/" + configFileName;
|
||||
// setPath(QSettings::IniFormat, QSettings::UserScope, configPath);
|
||||
// setDefaultFormat(QSettings::IniFormat);
|
||||
setDefaultFormat(QSettings::IniFormat);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0))
|
||||
setAtomicSyncRequired(true);
|
||||
#endif
|
||||
|
||||
m_color_stretagy = qvariant_cast<ColorStretagy>(value("color-stretagy"));
|
||||
m_style_stretagy = qvariant_cast<StyleStretagy>(value("style-stretagy"));
|
||||
m_current_custom_style_name = value("custom-style").toString();
|
||||
m_custom_palette = QApplication::palette();
|
||||
readPalleteSettings();
|
||||
|
||||
QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
|
||||
watcher->addPath(fileName());
|
||||
connect(watcher, &QFileSystemWatcher::fileChanged, [=](){
|
||||
refreshData();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef APPLICATIONSTYLESETTINGS_H
|
||||
#define APPLICATIONSTYLESETTINGS_H
|
||||
|
||||
#include <QSettings>
|
||||
#include <QPalette>
|
||||
#include <QMetaEnum>
|
||||
|
||||
class QStyle;
|
||||
|
||||
/*!
|
||||
* \brief The ApplicationStyleSettings class
|
||||
* \details
|
||||
* This class is used to decide the style switch stretagies for independent application.
|
||||
* For example, you can choose the color scheme switch stretagy of an application, hold
|
||||
* the color in light or dark, or follow the system's palette.
|
||||
*
|
||||
* \note
|
||||
* This API is unstable, if possible, do not use it.
|
||||
*/
|
||||
class ApplicationStyleSettings : public QSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ColorStretagy {
|
||||
System,
|
||||
Bright,
|
||||
Dark,
|
||||
Other
|
||||
};
|
||||
Q_ENUM(ColorStretagy)
|
||||
|
||||
enum StyleStretagy {
|
||||
Default,
|
||||
Custom
|
||||
};
|
||||
Q_ENUM(StyleStretagy)
|
||||
|
||||
static ApplicationStyleSettings *getInstance();
|
||||
|
||||
ColorStretagy currentColorStretagy() {return m_color_stretagy;}
|
||||
StyleStretagy currentStyleStretagy() {return m_style_stretagy;}
|
||||
const QString currentCustomStyleName();
|
||||
|
||||
void setColor(const QPalette::ColorRole &role, const QColor &color, const QPalette::ColorGroup &group = QPalette::Active);
|
||||
const QColor getColor(const QPalette::ColorRole &role, const QPalette::ColorGroup &group = QPalette::Active);
|
||||
|
||||
QPalette getCustomPalette() {return m_custom_palette;}
|
||||
|
||||
signals:
|
||||
void colorStretageChanged(const ColorStretagy &stretagy);
|
||||
void styleStretageChanged(const StyleStretagy &stretagy);
|
||||
|
||||
public slots:
|
||||
void setColorStretagy(ColorStretagy stretagy);
|
||||
void setStyleStretagy(StyleStretagy stretagy);
|
||||
void setCustomStyle(const QString &style);
|
||||
|
||||
protected:
|
||||
void refreshData(bool forceSync = false);
|
||||
void readPalleteSettings();
|
||||
|
||||
private:
|
||||
explicit ApplicationStyleSettings(QObject *parent = nullptr);
|
||||
~ApplicationStyleSettings() {}
|
||||
|
||||
ColorStretagy m_color_stretagy;
|
||||
StyleStretagy m_style_stretagy;
|
||||
QString m_current_custom_style_name;
|
||||
QMetaEnum m_color_role_enum = QMetaEnum::fromType<QPalette::ColorRole>();
|
||||
QMetaEnum m_color_group_enum = QMetaEnum::fromType<QPalette::ColorGroup>();
|
||||
|
||||
QPalette m_custom_palette;
|
||||
};
|
||||
|
||||
#endif // APPLICATIONSTYLESETTINGS_H
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BLACKLIST_H
|
||||
#define BLACKLIST_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
static const QStringList blackAppList() {
|
||||
QStringList l;
|
||||
//l<<"ukui-control-center";
|
||||
l<<"ubuntu-kylin-software-center.py";
|
||||
// l<<"kylin-burner";
|
||||
l<<"assistant";
|
||||
l<<"sogouIme-configtool";
|
||||
l<<"Ime Setting";
|
||||
// l<<"kylin-user-guide";
|
||||
l<<"biometric-authentication";
|
||||
l<<"qtcreator";
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static const QStringList blackAppListWithBlurHelper() {
|
||||
QStringList l;
|
||||
l<<"youker-assistant";
|
||||
l<<"kylin-assistant";
|
||||
l<<"kylin-video";
|
||||
// l<<"ukui-control-center";
|
||||
l<<"ubuntu-kylin-software-center.py";
|
||||
// l<<"kylin-burner";
|
||||
l<<"ukui-clipboard";
|
||||
return l;
|
||||
}
|
||||
|
||||
static const QStringList useDarkPaletteList() {
|
||||
//use dark palette in default style.
|
||||
QStringList l;
|
||||
// l<<"ukui-menu";
|
||||
// l<<"ukui-panel";
|
||||
// l<<"ukui-sidebar";
|
||||
// l<<"ukui-volume-control-applet-qt";
|
||||
// l<<"ukui-power-manager-tray";
|
||||
// l<<"kylin-nm";
|
||||
l<<"ukui-flash-disk";
|
||||
// l<<"ukui-bluetooth";
|
||||
l<<"mktip";
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static const QStringList useDefaultPaletteList() {
|
||||
//use light palette
|
||||
QStringList l;
|
||||
// l<<"kybackup";
|
||||
// l<<"biometric-manager";
|
||||
// l<<"kylin-video";
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static const QStringList useTransparentButtonList() {
|
||||
//use transparent button
|
||||
QStringList l;
|
||||
l<<"kybackup";
|
||||
l<<"biometric-manager";
|
||||
l<<"kylin-video";
|
||||
l<<"kylin-ipmsg";
|
||||
l<<"kylin-weather";
|
||||
l<<"kylin-recorder";
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
#endif // BLACKLIST_H
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBQT5UKUISTYLE_GLOBAL_H
|
||||
#define LIBQT5UKUISTYLE_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(LIBQT5UKUISTYLE_LIBRARY)
|
||||
# define LIBQT5UKUISTYLESHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define LIBQT5UKUISTYLESHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // LIBQT5UKUISTYLE_GLOBAL_H
|
|
@ -0,0 +1,88 @@
|
|||
<schemalist>
|
||||
<schema id="org.ukui.style" path="/org/ukui/style/" gettext-domain="style">
|
||||
<key type="s" name="style-name">
|
||||
<default>"ukui-default"</default>
|
||||
<summary>Current Qt Style</summary>
|
||||
<description>Set style for UKUI desktop environment. Have ukui-dark ukui-default ukui-light</description>
|
||||
</key>
|
||||
<key type="s" name="icon-theme-name">
|
||||
<default>"ukui-icon-theme-default"</default>
|
||||
<summary>Icon Theme for Qt Applications.</summary>
|
||||
<description>Icon Theme for Qt Applications.Have ukui ukui-classical ukui-fashion</description>
|
||||
</key>
|
||||
<key type="s" name="widget-theme-name">
|
||||
<default>"default"</default>
|
||||
<summary>Current widget theme name</summary>
|
||||
<description>Set system theme. Have default,classical and fashion</description>
|
||||
</key>
|
||||
<key type="s" name="system-font">
|
||||
<default>"Noto Sans CJK SC"</default>
|
||||
<summary>System Font for Qt Applications.</summary>
|
||||
<description>System Font for Qt Applications.</description>
|
||||
</key>
|
||||
<key type="s" name="system-font-size">
|
||||
<default>"11"</default>
|
||||
<summary>System Font Size for Qt Applications.</summary>
|
||||
<description>System Font Size for Qt Applications. Use point size.</description>
|
||||
</key>
|
||||
<key type="b" name="enabled-global-blur">
|
||||
<default>true</default>
|
||||
<summary>Enable Window Blur Effects.</summary>
|
||||
<description>
|
||||
Globally enable or disable the window blur effects for transparent window.
|
||||
Setting it to "false" will disable the effects.
|
||||
</description>
|
||||
</key>
|
||||
<key type="i" name="menu-transparency">
|
||||
<default>72</default>
|
||||
<summary>Menu's transparency.</summary>
|
||||
<description>The default transparency of menu.</description>
|
||||
</key>
|
||||
<key type="i" name="peony-side-bar-transparency">
|
||||
<default>72</default>
|
||||
<summary>Peony::SideBar's transparency.</summary>
|
||||
<description>The default transparency of the peony side bar.</description>
|
||||
</key>
|
||||
<key type="s" name="blur-exception-classes">
|
||||
<default>"[]"</default>
|
||||
<summary>a list of QWidget based classes do not blur.</summary>
|
||||
<description>Example: [QWidget, QWidget1, QWidget2]</description>
|
||||
</key>
|
||||
<key type="b" name="use-system-palette">
|
||||
<default>false</default>
|
||||
<summary>Use system palette.</summary>
|
||||
<description>
|
||||
Globally enable or disable system palette provided by ukui platform.
|
||||
</description>
|
||||
</key>
|
||||
<key type="s" name="system-palette">
|
||||
<default>""</default>
|
||||
<summary>System Palette</summary>
|
||||
<description>Set default system palette for UKUI desktop environment.</description>
|
||||
</key>
|
||||
<key type="b" name="use-custom-highlight-color">
|
||||
<default>false</default>
|
||||
<summary>Use custom highlight color.</summary>
|
||||
<description>
|
||||
Globally enable or disable custom highlight color.
|
||||
</description>
|
||||
</key>
|
||||
<key type="s" name="theme-color">
|
||||
<default>"daybreakBlue"</default>
|
||||
<summary> theme color</summary>
|
||||
<description>Set theme color for UKUI desktop environment.</description>
|
||||
</key>
|
||||
<key type="b" name="cursor-blink">
|
||||
<default>true</default>
|
||||
<summary>Blink text cursor.</summary>
|
||||
<description>
|
||||
Globally enable or disable blinking text cursor.
|
||||
</description>
|
||||
</key>
|
||||
<key type="i" name="cursor-blink-time">
|
||||
<default>1200</default>
|
||||
<summary>Blink text cursor interval.</summary>
|
||||
<description>The interval of text cursor blink.</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
|
@ -0,0 +1,9 @@
|
|||
HEADERS += $$PWD/libqt5-ukui-style_global.h \
|
||||
$$PWD/ukui-style-settings.h \
|
||||
$$PWD/application-style-settings.h
|
||||
|
||||
SOURCES += $$PWD/ukui-style-settings.cpp \
|
||||
$$PWD/application-style-settings.cpp
|
||||
|
||||
INCLUDEPATH += $$PWD/..
|
||||
INCLUDEPATH += $$PWD
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ukui-style-settings.h"
|
||||
|
||||
static UKUIStyleSettings *global_instance = nullptr;
|
||||
|
||||
UKUIStyleSettings::UKUIStyleSettings() : QGSettings ("org.ukui.style", "/org/ukui/style/")
|
||||
{
|
||||
}
|
||||
|
||||
UKUIStyleSettings *UKUIStyleSettings::globalInstance()
|
||||
{
|
||||
if (!global_instance){
|
||||
global_instance = new UKUIStyleSettings;
|
||||
}
|
||||
return global_instance;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUISTYLESETTINGS_H
|
||||
#define UKUISTYLESETTINGS_H
|
||||
|
||||
#include "libqt5-ukui-style_global.h"
|
||||
#include <QGSettings>
|
||||
|
||||
/*!
|
||||
* \brief The UKUIStyleSettings class
|
||||
* \details
|
||||
* To distingust with other gsettings, I derived this class form QGSettings.
|
||||
* It just represent the specific gsettings "org.ukui.style", and
|
||||
* there is no api difference from UKUIStyleSettings to QGSettings.
|
||||
*/
|
||||
class LIBQT5UKUISTYLESHARED_EXPORT UKUIStyleSettings : public QGSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
UKUIStyleSettings();
|
||||
|
||||
static UKUIStyleSettings *globalInstance();
|
||||
};
|
||||
|
||||
#endif // UKUISTYLESETTINGS_H
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <qpa/qplatformthemeplugin.h>
|
||||
#include "qt5-ukui-platform-theme.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <syslog.h>
|
||||
|
||||
#define UKUI_PLATFORMTHEME
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Qt5UKUIPlatformThemePlugin : public QPlatformThemePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "ukui.json")
|
||||
|
||||
public:
|
||||
virtual QPlatformTheme *create(const QString &key, const QStringList ¶ms) {
|
||||
if (key.toLower() == "ukui") {
|
||||
return new Qt5UKUIPlatformTheme(params);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "main.moc"
|
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QVariant>
|
||||
#include <QStandardPaths>
|
||||
#include "qt5-ukui-platform-theme.h"
|
||||
#include "ukui-style-settings.h"
|
||||
#include "highlight-effect.h"
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QPluginLoader>
|
||||
#include <QIconEnginePlugin>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
#include <QFileInfo>
|
||||
#include <QIcon>
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
|
||||
#include <QDebug>
|
||||
#include <private/qgenericunixthemes_p.h>
|
||||
#include <private/qdbustrayicon_p.h>
|
||||
|
||||
#include <QQuickStyle>
|
||||
|
||||
#include "widget/message-box.h"
|
||||
|
||||
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
|
||||
static bool isDBusTrayAvailable() {
|
||||
static bool dbusTrayAvailable = false;
|
||||
static bool dbusTrayAvailableKnown = false;
|
||||
if (!dbusTrayAvailableKnown) {
|
||||
QDBusMenuConnection conn;
|
||||
if (conn.isStatusNotifierHostRegistered())
|
||||
dbusTrayAvailable = true;
|
||||
dbusTrayAvailableKnown = true;
|
||||
}
|
||||
return dbusTrayAvailable;
|
||||
}
|
||||
#endif
|
||||
|
||||
Qt5UKUIPlatformTheme::Qt5UKUIPlatformTheme(const QStringList &args)
|
||||
{
|
||||
//FIXME:
|
||||
Q_UNUSED(args)
|
||||
if (QGSettings::isSchemaInstalled("org.ukui.style")) {
|
||||
auto settings = UKUIStyleSettings::globalInstance();
|
||||
|
||||
//set font
|
||||
auto fontName = settings->get("systemFont").toString();
|
||||
auto fontSize = settings->get("systemFontSize").toString().toDouble();
|
||||
if (qApp->property("noChangeSystemFontSize").isValid() && qApp->property("noChangeSystemFontSize").toBool())
|
||||
fontSize = 11;
|
||||
m_system_font.setFamily(fontName);
|
||||
m_system_font.setPointSizeF(fontSize);
|
||||
|
||||
m_fixed_font.setFamily(fontName);
|
||||
m_fixed_font.setPointSizeF(fontSize*1.2);
|
||||
|
||||
/*!
|
||||
* \bug
|
||||
* if we set app font, qwizard title's font will
|
||||
* become very small. I handle the wizard title
|
||||
* in ProxyStyle::polish().
|
||||
*/
|
||||
QApplication::setFont(m_system_font);
|
||||
|
||||
connect(settings, &QGSettings::changed, this, [=](const QString &key){
|
||||
if (key == "iconThemeName") {
|
||||
QString icontheme = settings->get("icon-theme-name").toString();
|
||||
|
||||
QIcon::setThemeName(icontheme);
|
||||
|
||||
QIcon icon = qApp->windowIcon();
|
||||
qApp->setWindowIcon(QIcon::fromTheme(icon.name()));
|
||||
// update all widgets for repaint new themed icons.
|
||||
for (auto widget : QApplication::allWidgets()) {
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
if (key == "systemFont") {
|
||||
QString font = settings->get("system-font").toString();
|
||||
QFontDatabase db;
|
||||
if (db.families().contains(font)) {
|
||||
QFont oldFont = QApplication::font();
|
||||
m_system_font.setFamily(font);
|
||||
m_fixed_font.setFamily(font);
|
||||
oldFont.setFamily(font);
|
||||
QApplication::setFont(oldFont);
|
||||
}
|
||||
}
|
||||
if (key == "systemFontSize") {
|
||||
if (qApp->property("noChangeSystemFontSize").isValid() && qApp->property("noChangeSystemFontSize").toBool())
|
||||
return;
|
||||
double fontSize = settings->get("system-font-size").toString().toDouble();
|
||||
if (fontSize > 0) {
|
||||
QFont oldFont = QApplication::font();
|
||||
m_system_font.setPointSize(fontSize);
|
||||
m_fixed_font.setPointSize(fontSize*1.2);
|
||||
oldFont.setPointSizeF(fontSize);
|
||||
QApplication::setFont(oldFont);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// add qqc2 style
|
||||
if (QFile::exists(QString("%1/kf5/kirigami/org.kylin.style.so").arg(QT_PLUGIN_INSTALL_DIRS))) {
|
||||
QQuickStyle::setStyle("org.kylin.style");
|
||||
}
|
||||
}
|
||||
|
||||
Qt5UKUIPlatformTheme::~Qt5UKUIPlatformTheme()
|
||||
{
|
||||
}
|
||||
|
||||
const QPalette *Qt5UKUIPlatformTheme::palette(Palette type) const
|
||||
{
|
||||
//FIXME:
|
||||
return QPlatformTheme::palette(type);
|
||||
}
|
||||
|
||||
const QFont *Qt5UKUIPlatformTheme::font(Font type) const
|
||||
{
|
||||
//FIXME:
|
||||
if (type == FixedFont)
|
||||
return &m_fixed_font;
|
||||
return &m_system_font;
|
||||
switch (type) {
|
||||
case SystemFont:
|
||||
return &m_system_font;
|
||||
case TitleBarFont:
|
||||
case FixedFont:
|
||||
case GroupBoxTitleFont:
|
||||
return &m_fixed_font;
|
||||
default:
|
||||
return &m_system_font;
|
||||
}
|
||||
return QPlatformTheme::font(type);
|
||||
}
|
||||
|
||||
QVariant Qt5UKUIPlatformTheme::themeHint(ThemeHint hint) const
|
||||
{
|
||||
switch (hint) {
|
||||
case QPlatformTheme::StyleNames:
|
||||
return QStringList()<<"ukui";
|
||||
|
||||
case QPlatformTheme::SystemIconThemeName: {
|
||||
if (UKUIStyleSettings::isSchemaInstalled("org.ukui.style")) {
|
||||
if (auto settings = UKUIStyleSettings::globalInstance()) {
|
||||
QString icontheme = settings->get("icon-theme-name").toString();
|
||||
|
||||
return QStringList()<<icontheme;
|
||||
}
|
||||
}
|
||||
return "hicolor";
|
||||
}
|
||||
|
||||
case QPlatformTheme::SystemIconFallbackThemeName:
|
||||
return "hicolor";
|
||||
case QPlatformTheme::IconThemeSearchPaths:
|
||||
//FIXME:
|
||||
return QStringList()<<".local/share/icons"<<"/usr/share/icons"<<"/usr/local/share/icons";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QPlatformTheme::themeHint(hint);
|
||||
}
|
||||
|
||||
QIconEngine *Qt5UKUIPlatformTheme::createIconEngine(const QString &iconName) const
|
||||
{
|
||||
// QPluginLoader l(XDG_ICON_ENGINE_PATH);
|
||||
// if (l.instance()) {
|
||||
// auto p = dynamic_cast<QIconEnginePlugin *>(l.instance());
|
||||
// auto engine = p->create();
|
||||
// qDebug()<<"use my engine";
|
||||
// return engine;
|
||||
// } else {
|
||||
// qDebug()<<"use common engine";
|
||||
// return QPlatformTheme::createIconEngine(iconName);
|
||||
// }
|
||||
|
||||
// //return new XdgIconLoaderEngine(iconName);
|
||||
|
||||
return QPlatformTheme::createIconEngine(iconName);
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
bool Qt5UKUIPlatformTheme::usePlatformNativeDialog(DialogType type) const
|
||||
{
|
||||
return true;
|
||||
switch (type) {
|
||||
case QPlatformTheme::FileDialog:
|
||||
case QPlatformTheme::FontDialog:
|
||||
case QPlatformTheme::ColorDialog:
|
||||
return false;
|
||||
case QPlatformTheme::MessageDialog:
|
||||
if (qAppName() == "ukui-control-center" || qAppName() == "kybackup")
|
||||
return false;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QPlatformDialogHelper *Qt5UKUIPlatformTheme::createPlatformDialogHelper(DialogType type) const
|
||||
{
|
||||
switch (type) {
|
||||
case QPlatformTheme::FileDialog:
|
||||
case QPlatformTheme::FontDialog:
|
||||
case QPlatformTheme::ColorDialog:
|
||||
return QPlatformTheme::createPlatformDialogHelper(type);
|
||||
case QPlatformTheme::MessageDialog:
|
||||
if (qAppName() == "kybackup")
|
||||
return nullptr;
|
||||
return new MessageBoxHelper;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
QIcon Qt5UKUIPlatformTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const
|
||||
{
|
||||
//FIXME:
|
||||
return QPlatformTheme::fileIcon(fileInfo, iconOptions);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GLOBAL_MENU
|
||||
QPlatformMenuBar *Qt5UKUIPlatformTheme::createPlatformMenuBar() const
|
||||
{
|
||||
return QPlatformTheme::createPlatformMenuBar();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
|
||||
QPlatformSystemTrayIcon *Qt5UKUIPlatformTheme::createPlatformSystemTrayIcon() const
|
||||
{
|
||||
if (isDBusTrayAvailable())
|
||||
return new QDBusTrayIcon();
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QT5UKUIPLATFORMTHEME_H
|
||||
#define QT5UKUIPLATFORMTHEME_H
|
||||
|
||||
#include "qt5-ukui-platformtheme_global.h"
|
||||
#include <QObject>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <QFont>
|
||||
|
||||
#if !defined(QT_NO_DBUS) && defined(QT_DBUS_LIB)
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) && !defined(QT_NO_SYSTEMTRAYICON)
|
||||
#define DBUS_TRAY
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
|
||||
#define GLOBAL_MENU
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
class QPalette;
|
||||
#ifdef DBUS_TRAY
|
||||
class QPlatformSystemTrayIcon;
|
||||
#endif
|
||||
|
||||
#ifdef GLOBAL_MENU
|
||||
class QPlatformMenuBar;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief The Qt5UKUIPlatformTheme class
|
||||
* \details
|
||||
* In UKUI desktop environment, we have our own platform to manage the qt applications' style.
|
||||
* This class is used to take over the theme and preferences of those applications.
|
||||
* The platform theme will effect globally.
|
||||
*/
|
||||
class QT5UKUIPLATFORMTHEMESHARED_EXPORT Qt5UKUIPlatformTheme : public QObject, public QPlatformTheme
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Qt5UKUIPlatformTheme(const QStringList &args);
|
||||
~Qt5UKUIPlatformTheme();
|
||||
|
||||
virtual const QPalette *palette(Palette type = SystemPalette) const;
|
||||
virtual const QFont *font(Font type = SystemFont) const;
|
||||
virtual QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
virtual QIconEngine *createIconEngine(const QString &iconName) const;
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
virtual bool usePlatformNativeDialog(DialogType type) const;
|
||||
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
virtual QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = 0) const;
|
||||
#endif
|
||||
|
||||
#ifdef GLOBAL_MENU
|
||||
virtual QPlatformMenuBar* createPlatformMenuBar() const;
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
|
||||
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
QFont m_system_font;
|
||||
QFont m_fixed_font;
|
||||
};
|
||||
|
||||
#endif // QT5UKUIPLATFORMTHEME_H
|
|
@ -0,0 +1,59 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-12-31T14:19:01
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += widgets dbus gui-private widgets-private x11extras quick quickcontrols2
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 5)|greaterThan(QT_MINOR_VERSION, 7): \
|
||||
QT += theme_support-private
|
||||
else: \
|
||||
QT += platformsupport-private
|
||||
|
||||
TARGET = qt5-ukui-platformtheme
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
CONFIG += c++11 link_pkgconfig
|
||||
PKGCONFIG += gsettings-qt Qt5XdgIconLoader
|
||||
|
||||
include(../libqt5-ukui-style/libqt5-ukui-style.pri)
|
||||
|
||||
DEFINES += QT5UKUIPLATFORMTHEME_LIBRARY
|
||||
|
||||
XDG_ICON_ENGINE = $$[QT_INSTALL_PLUGINS]/iconengines/libQt5XdgIconPlugin.so
|
||||
DEFINES += XDG_ICON_ENGINE_PATH='\\"$${XDG_ICON_ENGINE}\\"'
|
||||
|
||||
QT_PLUGIN_INSTALL_DIRS = $$[QT_INSTALL_PLUGINS]
|
||||
DEFINES += QT_PLUGIN_INSTALL_DIRS='\\"$${QT_PLUGIN_INSTALL_DIRS}\\"'
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
#DEFINES += QT_NO_DEBUG_OUTPUT
|
||||
DEFINES += QT_MESSAGELOGCONTEXT
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
include(widget/widget.pri)
|
||||
|
||||
SOURCES += \
|
||||
qt5-ukui-platform-theme.cpp \
|
||||
main.cpp
|
||||
|
||||
HEADERS += \
|
||||
qt5-ukui-platform-theme.h \
|
||||
qt5-ukui-platformtheme_global.h
|
||||
|
||||
unix {
|
||||
target.path = $$[QT_INSTALL_PLUGINS]/platformthemes
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
ukui.json
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QT5UKUIPLATFORMTHEME_GLOBAL_H
|
||||
#define QT5UKUIPLATFORMTHEME_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(QT5UKUIPLATFORMTHEME_LIBRARY)
|
||||
# define QT5UKUIPLATFORMTHEMESHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define QT5UKUIPLATFORMTHEMESHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // QT5UKUIPLATFORMTHEME_GLOBAL_H
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"Keys": [ "ukui" ]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* KWin Style UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Ding Jing <dingjing@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MESSAGEBOX_H
|
||||
#define MESSAGEBOX_H
|
||||
|
||||
#include <QIcon>
|
||||
#include <QDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QAbstractButton>
|
||||
#include <qpa/qplatformdialoghelper.h>
|
||||
#include <QMenu>
|
||||
#include <QTextEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
|
||||
class QLabel;
|
||||
class QAbstractButton;
|
||||
class MessageBoxHelper;
|
||||
class MessageBoxPrivate;
|
||||
class MessageBoxOptionsPrivate;
|
||||
|
||||
typedef QMessageBox::Icon Icon;
|
||||
typedef QMessageBox::StandardButtons StandardButtons;
|
||||
|
||||
class MessageBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Icon mIcon READ icon WRITE setIcon)
|
||||
Q_PROPERTY(QString mText READ text WRITE setText)
|
||||
Q_PROPERTY(Qt::TextFormat textFormat READ textFormat WRITE setTextFormat)
|
||||
Q_PROPERTY(QPixmap mIconPixmap READ iconPixmap WRITE setIconPixmap)
|
||||
Q_PROPERTY(QString mInformativeText READ informativeText WRITE setInformativeText)
|
||||
Q_PROPERTY(StandardButtons mStandardButtons READ standardButtons WRITE setStandardButtons)
|
||||
Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
|
||||
friend MessageBoxHelper;
|
||||
public:
|
||||
explicit MessageBox(QWidget *parent = nullptr);
|
||||
~MessageBox();
|
||||
|
||||
void setCheckBox(QCheckBox *cb);
|
||||
QCheckBox* checkBox() const;
|
||||
|
||||
QMessageBox::Icon icon ();
|
||||
void setIcon (QMessageBox::Icon icon);
|
||||
|
||||
QPixmap iconPixmap() const;
|
||||
void setIconPixmap(const QPixmap &pixmap);
|
||||
|
||||
QString text();
|
||||
void setText (const QString& text);
|
||||
|
||||
QString informativeText() const;
|
||||
void setInformativeText(const QString &text);
|
||||
|
||||
QString detailedText() const;
|
||||
void setDetailedText(const QString &text);
|
||||
|
||||
QString buttonText(int button) const;
|
||||
void setButtonText(int button, const QString &text);
|
||||
|
||||
Qt::TextFormat textFormat() const;
|
||||
void setTextFormat(Qt::TextFormat format);
|
||||
|
||||
void setTextInteractionFlags(Qt::TextInteractionFlags flags);
|
||||
Qt::TextInteractionFlags textInteractionFlags() const;
|
||||
|
||||
void addButton(QAbstractButton *button, QMessageBox::ButtonRole role);
|
||||
QPushButton* addButton(const QString &text, QMessageBox::ButtonRole role);
|
||||
QPushButton* addButton(QMessageBox::StandardButton button);
|
||||
void removeButton(QAbstractButton *button);
|
||||
|
||||
QAbstractButton* button (QMessageBox::StandardButton which) const;
|
||||
|
||||
QList<QAbstractButton*> buttons() const;
|
||||
QMessageBox::ButtonRole buttonRole(QAbstractButton *button) const;
|
||||
|
||||
QMessageBox::StandardButtons standardButtons() const;
|
||||
void setStandardButtons(QMessageBox::StandardButtons buttons);
|
||||
QMessageBox::StandardButton standardButton(QAbstractButton *button) const;
|
||||
|
||||
QPushButton* defaultButton() const;
|
||||
void setDefaultButton(QPushButton *button);
|
||||
void setDefaultButton(QMessageBox::StandardButton button);
|
||||
|
||||
QAbstractButton* escapeButton() const;
|
||||
void setEscapeButton(QAbstractButton *button);
|
||||
void setEscapeButton(QMessageBox::StandardButton button);
|
||||
|
||||
QAbstractButton* clickedButton() const;
|
||||
|
||||
void setWindowTitle(const QString &title);
|
||||
void setWindowModality(Qt::WindowModality windowModality);
|
||||
|
||||
static QPixmap standardIcon(QMessageBox::Icon icon);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) override;
|
||||
void changeEvent(QEvent *event) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void paintEvent (QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
void initHelper(QPlatformMessageDialogHelper*);
|
||||
void setuplayout();
|
||||
|
||||
Q_SIGNALS:
|
||||
void buttonClicked(QAbstractButton* button);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(MessageBox)
|
||||
Q_DECLARE_PRIVATE(MessageBox)
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked(QAbstractButton*))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_clicked(QPlatformDialogHelper::StandardButton, QPlatformDialogHelper::ButtonRole))
|
||||
};
|
||||
|
||||
class MessageBoxHelper : public QPlatformMessageDialogHelper
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MessageBoxHelper();
|
||||
~MessageBoxHelper() override;
|
||||
|
||||
virtual void exec() override;
|
||||
virtual void hide() override;
|
||||
virtual bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
|
||||
|
||||
private:
|
||||
void initDialog ();
|
||||
|
||||
private:
|
||||
MessageBox* mMessageBox = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TextEdit : public QTextEdit
|
||||
{
|
||||
public:
|
||||
TextEdit(QWidget *parent=0) : QTextEdit(parent) { }
|
||||
void contextMenuEvent(QContextMenuEvent * e) override
|
||||
{
|
||||
QMenu *menu = createStandardContextMenu();
|
||||
menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
menu->popup(e->globalPos());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // MESSAGEBOX_H
|
||||
|
||||
#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\
|
||||
QString sq = QString::fromLatin1(qVersion()); \
|
||||
if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
|
||||
(sq.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
|
||||
sq.section(QChar::fromLatin1('.'),2,2).toInt()<(s.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
|
||||
(s.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
|
||||
s.section(QChar::fromLatin1('.'),2,2).toInt()) { \
|
||||
if (!qApp){ \
|
||||
new QApplication(argc,argv); \
|
||||
} \
|
||||
QString s = QApplication::tr("Executable '%1' requires Qt "\
|
||||
"%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
|
||||
str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
|
||||
"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal("%s", s.toLatin1().data()); }}
|
|
@ -0,0 +1,7 @@
|
|||
HEADERS += \
|
||||
$$PWD/message-box.h \
|
||||
$$PWD/xatom-helper.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/message-box.cpp \
|
||||
$$PWD/xatom-helper.cpp
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* KWin Style UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xatom-helper.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <QX11Info>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
static XAtomHelper *global_instance = nullptr;
|
||||
|
||||
XAtomHelper *XAtomHelper::getInstance()
|
||||
{
|
||||
if (!global_instance)
|
||||
global_instance = new XAtomHelper;
|
||||
return global_instance;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isFrameLessWindow(int winId)
|
||||
{
|
||||
auto hints = getInstance()->getWindowMotifHint(winId);
|
||||
if (hints.flags == MWM_HINTS_DECORATIONS && hints.functions == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isWindowDecorateBorderOnly(int winId)
|
||||
{
|
||||
return isWindowMotifHintDecorateBorderOnly(getInstance()->getWindowMotifHint(winId));
|
||||
}
|
||||
|
||||
bool XAtomHelper::isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint)
|
||||
{
|
||||
bool isDeco = false;
|
||||
if (hint.flags & MWM_HINTS_DECORATIONS && hint.flags != MWM_HINTS_DECORATIONS) {
|
||||
if (hint.decorations == MWM_DECOR_BORDER)
|
||||
isDeco = true;
|
||||
}
|
||||
return isDeco;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isUKUICsdSupported()
|
||||
{
|
||||
// fixme:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isUKUIDecorationWindow(int winId)
|
||||
{
|
||||
if (m_ukuiDecorationAtion == None)
|
||||
return false;
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
ulong nitems;
|
||||
ulong bytes_after;
|
||||
uchar *data;
|
||||
|
||||
bool isUKUIDecoration = false;
|
||||
|
||||
XGetWindowProperty(QX11Info::display(), winId, m_ukuiDecorationAtion,
|
||||
0, LONG_MAX, false,
|
||||
m_ukuiDecorationAtion, &type,
|
||||
&format, &nitems,
|
||||
&bytes_after, &data);
|
||||
|
||||
if (type == m_ukuiDecorationAtion) {
|
||||
if (nitems == 1) {
|
||||
isUKUIDecoration = data[0];
|
||||
}
|
||||
}
|
||||
|
||||
return isUKUIDecoration;
|
||||
}
|
||||
|
||||
UnityCorners XAtomHelper::getWindowBorderRadius(int winId)
|
||||
{
|
||||
UnityCorners corners;
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
ulong nitems;
|
||||
ulong bytes_after;
|
||||
uchar *data;
|
||||
|
||||
if (m_unityBorderRadiusAtom != None) {
|
||||
XGetWindowProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom,
|
||||
0, LONG_MAX, false,
|
||||
XA_CARDINAL, &type,
|
||||
&format, &nitems,
|
||||
&bytes_after, &data);
|
||||
|
||||
if (type == XA_CARDINAL) {
|
||||
if (nitems == 4) {
|
||||
corners.topLeft = static_cast<ulong>(data[0]);
|
||||
corners.topRight = static_cast<ulong>(data[1*sizeof (ulong)]);
|
||||
corners.bottomLeft = static_cast<ulong>(data[2*sizeof (ulong)]);
|
||||
corners.bottomRight = static_cast<ulong>(data[3*sizeof (ulong)]);
|
||||
}
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
void XAtomHelper::setWindowBorderRadius(int winId, const UnityCorners &data)
|
||||
{
|
||||
if (m_unityBorderRadiusAtom == None)
|
||||
return;
|
||||
|
||||
ulong corners[4] = {data.topLeft, data.topRight, data.bottomLeft, data.bottomRight};
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL,
|
||||
32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0]));
|
||||
}
|
||||
|
||||
void XAtomHelper::setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight)
|
||||
{
|
||||
if (m_unityBorderRadiusAtom == None)
|
||||
return;
|
||||
|
||||
ulong corners[4] = {(ulong)topLeft, (ulong)topRight, (ulong)bottomLeft, (ulong)bottomRight};
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL,
|
||||
32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0]));
|
||||
}
|
||||
|
||||
void XAtomHelper::setUKUIDecoraiontHint(int winId, bool set)
|
||||
{
|
||||
if (m_ukuiDecorationAtion == None)
|
||||
return;
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, m_ukuiDecorationAtion, 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &set, 1);
|
||||
}
|
||||
|
||||
void XAtomHelper::setWindowMotifHint(int winId, const MotifWmHints &hints)
|
||||
{
|
||||
if (m_unityBorderRadiusAtom == None)
|
||||
return;
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_motifWMHintsAtom, m_motifWMHintsAtom,
|
||||
32, XCB_PROP_MODE_REPLACE, (const unsigned char *)&hints, sizeof (MotifWmHints)/ sizeof (ulong));
|
||||
}
|
||||
|
||||
MotifWmHints XAtomHelper::getWindowMotifHint(int winId)
|
||||
{
|
||||
MotifWmHints hints;
|
||||
|
||||
if (m_unityBorderRadiusAtom == None)
|
||||
return hints;
|
||||
|
||||
uchar *data;
|
||||
Atom type;
|
||||
int format;
|
||||
ulong nitems;
|
||||
ulong bytes_after;
|
||||
|
||||
XGetWindowProperty(QX11Info::display(), winId, m_motifWMHintsAtom,
|
||||
0, sizeof (MotifWmHints)/sizeof (long), false, AnyPropertyType, &type,
|
||||
&format, &nitems, &bytes_after, &data);
|
||||
|
||||
if (type == None) {
|
||||
return hints;
|
||||
} else {
|
||||
hints = *(MotifWmHints *)data;
|
||||
XFree(data);
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
XAtomHelper::XAtomHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
if (!QX11Info::isPlatformX11())
|
||||
return;
|
||||
|
||||
m_motifWMHintsAtom = XInternAtom(QX11Info::display(), "_MOTIF_WM_HINTS", true);
|
||||
m_unityBorderRadiusAtom = XInternAtom(QX11Info::display(), "_UNITY_GTK_BORDER_RADIUS", false);
|
||||
m_ukuiDecorationAtion = XInternAtom(QX11Info::display(), "_KWIN_UKUI_DECORAION", false);
|
||||
}
|
||||
|
||||
Atom XAtomHelper::registerUKUICsdNetWmSupportAtom()
|
||||
{
|
||||
// fixme:
|
||||
return None;
|
||||
}
|
||||
|
||||
void XAtomHelper::unregisterUKUICsdNetWmSupportAtom()
|
||||
{
|
||||
// fixme:
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* KWin Style UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XATOMHELPER_H
|
||||
#define XATOMHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
struct UnityCorners {
|
||||
ulong topLeft = 0;
|
||||
ulong topRight = 0;
|
||||
ulong bottomLeft = 0;
|
||||
ulong bottomRight = 0;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ulong flags = 0;
|
||||
ulong functions = 0;
|
||||
ulong decorations = 0;
|
||||
long input_mode = 0;
|
||||
ulong status = 0;
|
||||
} MotifWmHints, MwmHints;
|
||||
|
||||
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
#define MWM_HINTS_INPUT_MODE (1L << 2)
|
||||
#define MWM_HINTS_STATUS (1L << 3)
|
||||
|
||||
#define MWM_FUNC_ALL (1L << 0)
|
||||
#define MWM_FUNC_RESIZE (1L << 1)
|
||||
#define MWM_FUNC_MOVE (1L << 2)
|
||||
#define MWM_FUNC_MINIMIZE (1L << 3)
|
||||
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
||||
#define MWM_FUNC_CLOSE (1L << 5)
|
||||
|
||||
#define MWM_DECOR_ALL (1L << 0)
|
||||
#define MWM_DECOR_BORDER (1L << 1)
|
||||
#define MWM_DECOR_RESIZEH (1L << 2)
|
||||
#define MWM_DECOR_TITLE (1L << 3)
|
||||
#define MWM_DECOR_MENU (1L << 4)
|
||||
#define MWM_DECOR_MINIMIZE (1L << 5)
|
||||
#define MWM_DECOR_MAXIMIZE (1L << 6)
|
||||
|
||||
#define MWM_INPUT_MODELESS 0
|
||||
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
|
||||
#define MWM_INPUT_SYSTEM_MODAL 2
|
||||
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
|
||||
#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
|
||||
|
||||
#define MWM_TEAROFF_WINDOW (1L<<0)
|
||||
|
||||
namespace UKUI {
|
||||
class Decoration;
|
||||
}
|
||||
|
||||
class XAtomHelper : public QObject
|
||||
{
|
||||
friend class UKUI::Decoration;
|
||||
Q_OBJECT
|
||||
public:
|
||||
static XAtomHelper *getInstance();
|
||||
|
||||
static bool isFrameLessWindow(int winId);
|
||||
|
||||
bool isWindowDecorateBorderOnly(int winId);
|
||||
bool isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint);
|
||||
bool isUKUICsdSupported();
|
||||
bool isUKUIDecorationWindow(int winId);
|
||||
|
||||
UnityCorners getWindowBorderRadius(int winId);
|
||||
void setWindowBorderRadius(int winId, const UnityCorners &data);
|
||||
void setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight);
|
||||
void setUKUIDecoraiontHint(int winId, bool set = true);
|
||||
|
||||
void setWindowMotifHint(int winId, const MotifWmHints &hints);
|
||||
MotifWmHints getWindowMotifHint(int winId);
|
||||
|
||||
private:
|
||||
explicit XAtomHelper(QObject *parent = nullptr);
|
||||
|
||||
ulong registerUKUICsdNetWmSupportAtom();
|
||||
void unregisterUKUICsdNetWmSupportAtom();
|
||||
|
||||
ulong m_motifWMHintsAtom = 0l;
|
||||
ulong m_unityBorderRadiusAtom = 0l;
|
||||
ulong m_ukuiDecorationAtion = 0l;
|
||||
};
|
||||
|
||||
#endif // XATOMHELPER_H
|
|
@ -0,0 +1,7 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
qt5-ukui-platformtheme \
|
||||
ukui-styles \
|
||||
libqt5-ukui-style \
|
||||
test
|
|
@ -0,0 +1,28 @@
|
|||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any Qt feature that has been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <QVector4D>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w3;
|
||||
|
||||
w3.setWindowFlag(Qt::FramelessWindowHint);
|
||||
w3.setProperty("useCustomShadow", true);
|
||||
w3.setProperty("customShadowDarkness", 1.0);
|
||||
w3.setProperty("customShadowWidth", 20);
|
||||
w3.setProperty("customShadowRadius", QVector4D(1, 1, 1, 1));
|
||||
w3.setProperty("customShadowMargins", QVector4D(20, 20, 20, 20));
|
||||
|
||||
w3.show();
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,31 @@
|
|||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any Qt feature that has been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <QListWidget>
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->comboBox->setEnabled(false);
|
||||
|
||||
menu = new QMenu(ui->pushButton);
|
||||
menu->setProperty("fillIconSymbolicColor", true);
|
||||
menu->addAction(QIcon::fromTheme("edit-find-symbolic"), "edit-find-symbolic");
|
||||
menu->addAction(QIcon::fromTheme("edit-cut-symbolic"), "edit-cut-symbolic");
|
||||
menu->addAction(QIcon::fromTheme("user-trash"), "user-trash");
|
||||
menu->addAction(QIcon::fromTheme("open-menu-symbolic"), "open-menu-symbolic");
|
||||
menu->addAction(QIcon::fromTheme("pane-hide-symbolic"), "pane-hide-symbolic");
|
||||
ui->pushButton->setMenu(menu);
|
||||
|
||||
view = new QListWidget(this);
|
||||
view->resize(300, 200);
|
||||
view->move(100, 200);
|
||||
|
||||
auto item = new QListWidgetItem(QIcon::fromTheme("window-close"), "window-close", view);
|
||||
item = new QListWidgetItem(QIcon::fromTheme("window-close-symbolic"), "window-close-symoblic", view);
|
||||
item = new QListWidgetItem(QIcon::fromTheme("user-trash"), "user-trash", view);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_checkBox_toggled(bool checked)
|
||||
{
|
||||
ui->pushButton->setProperty("useIconHighlightEffect", checked);
|
||||
ui->pushButton->update();
|
||||
ui->toolButton->setProperty("useIconHighlightEffect", checked);
|
||||
ui->toolButton->update();
|
||||
view->setProperty("useIconHighlightEffect", checked);
|
||||
view->viewport()->update();
|
||||
menu->setProperty("useIconHighlightEffect", checked);
|
||||
ui->comboBox->setEnabled(checked);
|
||||
|
||||
int mode = ui->comboBox->currentIndex();
|
||||
ui->pushButton->setProperty("iconHighlightEffectMode", mode);
|
||||
ui->pushButton->update();
|
||||
ui->toolButton->setProperty("iconHighlightEffectMode", mode);
|
||||
ui->toolButton->update();
|
||||
view->setProperty("iconHighlightEffectMode", mode);
|
||||
view->viewport()->update();
|
||||
menu->setProperty("iconHighlightEffectMode", mode);
|
||||
}
|
||||
|
||||
void MainWindow::on_comboBox_currentIndexChanged(int index)
|
||||
{
|
||||
int mode = index;
|
||||
ui->pushButton->setProperty("iconHighlightEffectMode", mode);
|
||||
ui->pushButton->update();
|
||||
ui->toolButton->setProperty("iconHighlightEffectMode", mode);
|
||||
ui->toolButton->update();
|
||||
view->setProperty("iconHighlightEffectMode", mode);
|
||||
view->viewport()->update();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class QListWidget;
|
||||
class QMenu;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void on_checkBox_toggled(bool checked);
|
||||
|
||||
void on_comboBox_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
QListWidget *view;
|
||||
QMenu *menu;
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>12</x>
|
||||
<y>12</y>
|
||||
<width>345</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="window-close-symbolic">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>36</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>use auto highlight icon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="toolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="window-close-symbolic">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>36</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>highlightOnly</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>bothDefaultAndHighlight</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>36</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,146 @@
|
|||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
qputenv("QT_QPA_PLATFORMTHEME", "ukui");
|
||||
|
||||
#if 0
|
||||
QMessageBox::information(nullptr, "title", "information text", QMessageBox::Ok);
|
||||
QMessageBox::information(nullptr, "title", "information text1 "
|
||||
"information text2 "
|
||||
"information text3 "
|
||||
"information text4 "
|
||||
"information text5 "
|
||||
"information text6 "
|
||||
"information text7 "
|
||||
"information text8 "
|
||||
"information text9 "
|
||||
"information text10 "
|
||||
"information text11 "
|
||||
"information text12 "
|
||||
"information text13 "
|
||||
"information text14 "
|
||||
"information text15 "
|
||||
"information text16 "
|
||||
"information text17 "
|
||||
"information text18 "
|
||||
"information text19 "
|
||||
"information text20 "
|
||||
"information text21 "
|
||||
"information text22 "
|
||||
"information text23 "
|
||||
"information text24 "
|
||||
"information text25 "
|
||||
"information text26 "
|
||||
"information text27 "
|
||||
"information text28 "
|
||||
"information text29 "
|
||||
"information text30 "
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text"
|
||||
"information text", QMessageBox::Ok);
|
||||
QMessageBox::information(nullptr, "title", "information text", QMessageBox::Ok | QMessageBox::Cancel | QMessageBox::Save | QMessageBox::SaveAll);
|
||||
|
||||
//
|
||||
QMessageBox::warning(nullptr, "title", "warning text", QMessageBox::Ok);
|
||||
QMessageBox::critical(nullptr, "title", "critical text", QMessageBox::Ok);
|
||||
QMessageBox::question(nullptr, "title", "question text", QMessageBox::Ok);
|
||||
|
||||
|
||||
// test button
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<QMessageBox::StandardButtons>();
|
||||
for (auto i = 0; i < metaEnum.keyCount(); ++i) {
|
||||
if (metaEnum.value(i) < QMessageBox::FirstButton
|
||||
|| metaEnum.value(i) > QMessageBox::LastButton) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int ret = QMessageBox::information(nullptr, "title", "测试按钮", metaEnum.value(i));
|
||||
|
||||
qDebug() << "is current button:" << (ret == metaEnum.value(i)) << " ret:" << ret;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
|
||||
QMessageBox m;
|
||||
m.setText("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
int ret = m.exec();
|
||||
qDebug() << (ret == QDialog::Accepted) << " --- " << ret;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
QMessageBox m;
|
||||
m.setText("这是中文测试1,中文测试2,中文测试3,中文测试4,中文测试5,中文测试6,中文测试7,中文测试8,中文测试9,中文测试10,中文测试11,中文测试12,中文测试13,中文测试14");
|
||||
int ret = m.exec();
|
||||
m.setIcon(QMessageBox::Critical);
|
||||
m.exec();
|
||||
m.setText("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
m.exec();
|
||||
qDebug() << (ret == QDialog::Accepted) << " --- " << ret;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// 一个完整的布局展示相关测试例子
|
||||
QMessageBox m;
|
||||
m.setText("<h2>测试html是否可以正常显示</h2><p>短字段</p>");
|
||||
int ret = m.exec();
|
||||
m.setText("<style type='text/css'> h1{color:red;font-size:12;} p{color:blue;font-size:10;}</style><h1>接下来要测试html是否可以正常显示</h1><p>关于HTML显示的测试例子,需要假如一些style之类的字符串来干扰其文本框大小的预估,接下来就是style段</p>");
|
||||
ret = m.exec();
|
||||
m.setIcon(QMessageBox::Critical);
|
||||
m.setText("<style>h1{color:red;}p{color:blue;}</style><h1>接下来要测试html是否可以正常显示</h1><p>关于HTML显示的测试例子,需要假如一些style之类的字符串来干扰其文本框大小的预估,接下来就是style段 + 图标</p>");
|
||||
ret = m.exec();
|
||||
m.setText("较短的纯文本汉字");
|
||||
ret = m.exec();
|
||||
m.setText("很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,");
|
||||
ret = m.exec();
|
||||
m.setText("english");
|
||||
ret = m.exec();
|
||||
m.exec();
|
||||
m.setText("long long english ... aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
m.exec();
|
||||
m.setText("中英文混合 Chinese and English mixed");
|
||||
m.exec();
|
||||
m.setText("中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合中英文混合 Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.Chinese and English mixed.");
|
||||
m.exec();
|
||||
qDebug() << (ret == QDialog::Accepted) << " --- " << ret;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// 测试 detailLabel
|
||||
QMessageBox m;
|
||||
m.setIcon(QMessageBox::Critical);
|
||||
m.setText("<style>h1{color:red;}p{color:blue;}</style><h1>接下来要测试html是否可以正常显示</h1><p>关于HTML显示的测试例子,需要假如一些style之类的字符串来干扰其文本框大小的预估,接下来就是style段 + 图标</p>");
|
||||
m.setDetailedText("很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符,很长很长的中文字符");
|
||||
m.exec();
|
||||
|
||||
m.setIcon(QMessageBox::Information);
|
||||
m.setText("<style>h1{color:red;}p{color:blue;}</style><h1>接下来要测试html是否可以正常显示</h1><p>关于HTML显示的测试例子,需要假如一些style之类的字符串来干扰其文本框大小的预估,接下来就是style段 + 图标</p>");
|
||||
m.setDetailedText("");
|
||||
m.exec();
|
||||
#endif
|
||||
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
main.cpp
|
||||
|
||||
HEADERS +=
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include "internal-styles/mps-style.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setStyle(new MPSStyle);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<widget class="QWidget" name="">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>20</y>
|
||||
<width>337</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="toolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="radioButton">
|
||||
<property name="text">
|
||||
<string>RadioButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QScrollBar" name="horizontalScrollBar">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>37</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,43 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2020-02-11T15:20:45
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = mps-style-application
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += plugin c++11 link_pkgconfig
|
||||
PKGCONFIG += gsettings-qt
|
||||
|
||||
include(../../libqt5-ukui-style/libqt5-ukui-style.pri)
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
QApplication::setStyle("ukui");
|
||||
MainWindow w;
|
||||
w.setProperty("useSystemStyleBlur", true);
|
||||
w.setWindowTitle("blur tool bar region");
|
||||
w.show();
|
||||
|
||||
QMainWindow w2;
|
||||
w2.setProperty("useSystemStyleBlur", true);
|
||||
w2.setWindowTitle("whole window blur");
|
||||
w2.setAttribute(Qt::WA_TranslucentBackground);
|
||||
w2.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QToolBar>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
m_tool_bar = new QToolBar(this);
|
||||
m_tool_bar->addAction("test1");
|
||||
m_tool_bar->addAction("test2");
|
||||
m_tool_bar->addAction("test3");
|
||||
m_tool_bar->addAction("test4");
|
||||
addToolBar(m_tool_bar);
|
||||
|
||||
m_list_view = new QListWidget(this);
|
||||
m_list_view->setAttribute(Qt::WA_TranslucentBackground);
|
||||
m_list_view->setAttribute(Qt::WA_Hover);
|
||||
m_list_view->setStyleSheet("background: transparent");
|
||||
m_list_view->addItem("test1");
|
||||
m_list_view->addItem("test2");
|
||||
m_list_view->addItem("test3");
|
||||
m_list_view->addItem("test4");
|
||||
setCentralWidget(m_list_view);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QMainWindow::resizeEvent(e);
|
||||
m_blur_region = m_tool_bar->rect();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QRegion>
|
||||
|
||||
class QListWidget;
|
||||
class QToolBar;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QRegion blurRegion READ blurRegion WRITE setBlurRegion MEMBER m_region)
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
const QRegion blurRegion() {return m_blur_region;}
|
||||
void setBlurRegion(const QRegion ®ion) {m_blur_region = region;}
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
QListWidget *m_list_view;
|
||||
QToolBar *m_tool_bar;
|
||||
|
||||
QRegion m_blur_region = QRegion();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,37 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2020-01-03T10:58:54
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = region-blur
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QDebug>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
QFontDatabase db;
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include <QDir>
|
||||
#include <QStringListModel>
|
||||
#include <QGSettings>
|
||||
#include <QFontDatabase>
|
||||
|
||||
bool init_style = false;
|
||||
bool init_icon_theme = false;
|
||||
bool init_system_font = false;
|
||||
bool init_system_font_size = false;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QGSettings settings("org.ukui.style", "/org/ukui/style/");
|
||||
auto currentStyle = settings.get("styleName").toString();
|
||||
auto currentIconTheme = settings.get("iconThemeName").toString();
|
||||
|
||||
auto styles = QStyleFactory::keys();
|
||||
styles.removeOne("ukui");
|
||||
QStringListModel *style_model = new QStringListModel(styles, this);
|
||||
ui->comboBox->setModel(style_model);
|
||||
ui->comboBox->setCurrentText(currentStyle);
|
||||
|
||||
QDir iconThemePaths = QDir("/usr/share/icons");
|
||||
auto iconThemes = iconThemePaths.entryList(QDir::Dirs);
|
||||
QStringListModel *icon_theme_model = new QStringListModel(iconThemes, this);
|
||||
ui->comboBox_2->setModel(icon_theme_model);
|
||||
ui->comboBox_2->setCurrentText(currentIconTheme);
|
||||
|
||||
QFontDatabase db;
|
||||
QStringListModel *fonts_model = new QStringListModel(db.families(), this);
|
||||
ui->comboBox_3->setModel(fonts_model);
|
||||
ui->comboBox_3->setCurrentText(settings.get("systemFont").toString());
|
||||
|
||||
ui->spinBox->setValue(settings.get("systemFontSize").toString().toDouble());
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::on_comboBox_currentIndexChanged(const QString &arg1)
|
||||
{
|
||||
if (!init_style) {
|
||||
init_style = true;
|
||||
return;
|
||||
}
|
||||
//change style
|
||||
QGSettings settings("org.ukui.style", "/org/ukui/style/");
|
||||
settings.set("styleName", arg1);
|
||||
}
|
||||
|
||||
void MainWindow::on_comboBox_2_currentIndexChanged(const QString &arg1)
|
||||
{
|
||||
if (!init_icon_theme) {
|
||||
init_icon_theme = true;
|
||||
return;
|
||||
}
|
||||
//change icon theme
|
||||
QGSettings settings("org.ukui.style", "/org/ukui/style/");
|
||||
settings.set("iconThemeName", arg1);
|
||||
}
|
||||
|
||||
void MainWindow::on_horizontalSlider_valueChanged(int value)
|
||||
{
|
||||
QGSettings settings("org.ukui.style", "/org/ukui/style/");
|
||||
settings.set("menuTransparency", value);
|
||||
}
|
||||
|
||||
void MainWindow::on_comboBox_3_currentTextChanged(const QString &arg1)
|
||||
{
|
||||
if (!init_system_font) {
|
||||
init_system_font = true;
|
||||
return;
|
||||
}
|
||||
|
||||
bool enableMenuSettings = true;
|
||||
if (arg1 != "ukui-white" || arg1 != "ukui-black") {
|
||||
enableMenuSettings = false;
|
||||
}
|
||||
|
||||
ui->horizontalSlider->setEnabled(enableMenuSettings);
|
||||
|
||||
QGSettings settings("org.ukui.style", "/org/ukui/style/");
|
||||
settings.set("systemFont", arg1);
|
||||
}
|
||||
|
||||
void MainWindow::on_spinBox_valueChanged(int arg1)
|
||||
{
|
||||
if (!init_system_font_size) {
|
||||
init_system_font_size = true;
|
||||
return;
|
||||
}
|
||||
QGSettings settings("org.ukui.style", "/org/ukui/style/");
|
||||
settings.set("systemFontSize", arg1);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void on_comboBox_currentIndexChanged(const QString &arg1);
|
||||
|
||||
void on_comboBox_2_currentIndexChanged(const QString &arg1);
|
||||
|
||||
void on_horizontalSlider_valueChanged(int value);
|
||||
|
||||
void on_comboBox_3_currentTextChanged(const QString &arg1);
|
||||
|
||||
void on_spinBox_valueChanged(int arg1);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>344</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>icon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QComboBox" name="comboBox_2"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>menu opacity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QSlider" name="horizontalSlider">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>font</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="comboBox_3"/>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<property name="value">
|
||||
<number>11</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,41 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2020-01-03T20:37:30
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = system-settings
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += c++11 link_pkgconfig
|
||||
PKGCONFIG += gsettings-qt
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "widget.h"
|
||||
#include <QApplication>
|
||||
|
||||
/// make a QTabWidget have a slide animation.
|
||||
/// This is integrated in ukui style by default.
|
||||
/// \see
|
||||
/// Qt5UKUIStyle, UKUI::TabWidget::DefaultSlideAnimator.
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
Widget w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2020-01-09T11:25:46
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = tabwidget
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
widget.cpp
|
||||
|
||||
HEADERS += \
|
||||
widget.h
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "widget.h"
|
||||
#include <QPushButton>
|
||||
|
||||
#include <QListView>
|
||||
#include <QFileSystemModel>
|
||||
#include <QTreeView>
|
||||
#include <QLabel>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
Widget::Widget(QWidget *parent)
|
||||
: QTabWidget(parent)
|
||||
{
|
||||
auto v1 = new QListView(this);
|
||||
v1->setViewMode(QListView::IconMode);
|
||||
auto m1 = new QFileSystemModel(v1);
|
||||
v1->setModel(m1);
|
||||
m1->setRootPath("/");
|
||||
v1->setRootIndex(m1->index("/"));
|
||||
addTab(v1, "view1");
|
||||
|
||||
auto v2 = new QTreeView;
|
||||
v2->setModel(m1);
|
||||
v2->setRootIndex(m1->index("/"));
|
||||
addTab(v2, "view2");
|
||||
|
||||
addTab(new QPushButton("test1", this), "test1");
|
||||
addTab(new QLabel("test2", this), "test2");
|
||||
addTab(new QPushButton("test3", this), "test3");
|
||||
addTab(new QLabel("test4", this), "test4");
|
||||
}
|
||||
|
||||
Widget::~Widget()
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Qt5-UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WIDGET_H
|
||||
#define WIDGET_H
|
||||
|
||||
#include <QTabWidget>
|
||||
|
||||
class Widget : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Widget(QWidget *parent = 0);
|
||||
~Widget();
|
||||
};
|
||||
|
||||
#endif // WIDGET_H
|
|
@ -0,0 +1,10 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
custom-shadow \
|
||||
highlighted-icon-button \
|
||||
messagebox \
|
||||
region-blur \
|
||||
system-settings \
|
||||
tabwidget \
|
||||
mps-style-application
|
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "blur-helper.h"
|
||||
#include "ukui-style-settings.h"
|
||||
#include <QWidget>
|
||||
#include <KWindowEffects>
|
||||
#include <QGSettings>
|
||||
#include <QVariant>
|
||||
#include <QEvent>
|
||||
#include <QIcon>
|
||||
#include <QPainterPath>
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include "black-list.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QX11Info>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
BlurHelper::BlurHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
if (QGSettings::isSchemaInstalled("org.ukui.control-center.personalise")) {
|
||||
QGSettings *settings = new QGSettings("org.ukui.control-center.personalise", QByteArray(), this);
|
||||
connect(settings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "effect") {
|
||||
bool enable = settings->get(key).toBool();
|
||||
this->onBlurEnableChanged(enable);
|
||||
}
|
||||
});
|
||||
bool enable = settings->get("effect").toBool();
|
||||
this->onBlurEnableChanged(enable);
|
||||
|
||||
if (!KWindowEffects::isEffectAvailable(KWindowEffects::BlurBehind))
|
||||
confirmBlurEnableDelay();
|
||||
}
|
||||
m_timer.setSingleShot(true);
|
||||
m_timer.setInterval(100);
|
||||
}
|
||||
|
||||
bool BlurHelper::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
if (!m_blur_enable)
|
||||
return false;
|
||||
|
||||
QWidget* widget = qobject_cast<QWidget*>(obj);
|
||||
|
||||
if (!widget || !widget->isWindow())
|
||||
return false;
|
||||
|
||||
//FIXME:
|
||||
//qDebug()<<e->type()<<obj;
|
||||
//qDebug()<<KWindowEffects::isEffectAvailable(KWindowEffects::BlurBehind);
|
||||
switch (e->type()) {
|
||||
case QEvent::UpdateRequest: {
|
||||
//QWidget* widget = qobject_cast<QWidget*>(obj);
|
||||
delayUpdate(widget, true);
|
||||
break;
|
||||
}
|
||||
case QEvent::LayoutRequest:
|
||||
{
|
||||
//QWidget* widget = qobject_cast<QWidget*>(obj);
|
||||
delayUpdate(widget);
|
||||
break;
|
||||
}
|
||||
case QEvent::Hide: {
|
||||
//QWidget* widget = qobject_cast<QWidget*>(obj);
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), false);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief BlurHelper::registerWidget
|
||||
* \param widget
|
||||
* \note
|
||||
*
|
||||
* we can't blur a widget before it shown, because some times
|
||||
* there might be problems about window painting.
|
||||
* this usually happend on a widget which has graphics effect.
|
||||
*
|
||||
* to avoid them, never try get winid and do a blur for that case.
|
||||
*/
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0))
|
||||
void BlurHelper::registerWidget(QWidget *widget)
|
||||
{
|
||||
// FIXME: how to blur window on wayland?
|
||||
if (!QX11Info::isPlatformX11())
|
||||
return;
|
||||
|
||||
if (!KWindowEffects::isEffectAvailable(KWindowEffects::BlurBehind))
|
||||
return;
|
||||
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
if (shouldSkip(widget))
|
||||
return;
|
||||
if (isApplicationInBlackList())
|
||||
return;
|
||||
if (widget->property("doNotBlur").toBool())
|
||||
return;
|
||||
if (!m_blur_widgets.contains(widget)) {
|
||||
m_blur_widgets<<widget;
|
||||
//qDebug()<<KWindowEffects::isEffectAvailable(KWindowEffects::BlurBehind);
|
||||
/*!
|
||||
\note
|
||||
never try enableBlurBehind when register widget.
|
||||
it might cause serious problems about paint.
|
||||
usually it happend with a widget which has graphics effect.
|
||||
*/
|
||||
// if (!widget->mask().isEmpty()) {
|
||||
// KWindowEffects::enableBlurBehind(widget->winId(), true, widget->mask());
|
||||
// } else {
|
||||
// KWindowEffects::enableBlurBehind(widget->winId(), true);
|
||||
// }
|
||||
|
||||
connect(widget, &QWidget::destroyed, this, [=]() {
|
||||
this->onWidgetDestroyed(widget);
|
||||
});
|
||||
}
|
||||
widget->removeEventFilter(this);
|
||||
widget->installEventFilter(this);
|
||||
|
||||
if (!widget->mask().isEmpty()) {
|
||||
widget->update(widget->mask());
|
||||
} else {
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void BlurHelper::unregisterWidget(QWidget *widget)
|
||||
{
|
||||
if (!QX11Info::isPlatformX11())
|
||||
return;
|
||||
|
||||
if (!KWindowEffects::isEffectAvailable(KWindowEffects::BlurBehind))
|
||||
return;
|
||||
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
if (shouldSkip(widget))
|
||||
return;
|
||||
if (isApplicationInBlackList())
|
||||
return;
|
||||
if (widget->property("doNotBlur").toBool())
|
||||
return;
|
||||
m_blur_widgets.removeOne(widget);
|
||||
widget->removeEventFilter(this);
|
||||
if (widget->winId() > 0)
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool BlurHelper::isApplicationInBlackList()
|
||||
{
|
||||
return blackList().contains(qAppName());
|
||||
}
|
||||
|
||||
const QStringList BlurHelper::blackList()
|
||||
{
|
||||
return blackAppListWithBlurHelper();
|
||||
}
|
||||
|
||||
bool BlurHelper::shouldSkip(QWidget *w)
|
||||
{
|
||||
if (w->property("useSystemStyleBlur").isValid()) {
|
||||
return !w->property("useSystemStyleBlur").toBool();
|
||||
}
|
||||
|
||||
bool skip = true;
|
||||
if (w->inherits("QComboBoxPrivateContainer"))
|
||||
return true;
|
||||
|
||||
if (w->inherits("QMenu") || w->inherits("QTipLabel")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (w->inherits("QTipLabel"))
|
||||
// return true;
|
||||
|
||||
return skip;
|
||||
}
|
||||
|
||||
void BlurHelper::onBlurEnableChanged(bool enable)
|
||||
{
|
||||
m_blur_enable = enable;
|
||||
|
||||
if (enable) {
|
||||
qApp->setProperty("blurEnable", true);
|
||||
} else {
|
||||
qApp->setProperty("blurEnable", false);
|
||||
}
|
||||
for (auto widget : qApp->allWidgets()) {
|
||||
widget->update();
|
||||
if (m_blur_widgets.contains(widget)) {
|
||||
if (widget->winId() > 0) {
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), enable);
|
||||
}
|
||||
}
|
||||
}
|
||||
// QTimer::singleShot(100, this, [=](){
|
||||
// for (auto widget : m_blur_widgets) {
|
||||
// if (!widget)
|
||||
// continue;
|
||||
// if (widget->winId() > 0)
|
||||
// KWindowEffects::enableBlurBehind(widget->winId(), enable);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
void BlurHelper::onWidgetDestroyed(QWidget *widget)
|
||||
{
|
||||
widget->removeEventFilter(this);
|
||||
m_blur_widgets.removeOne(widget);
|
||||
//unregisterWidget(widget);
|
||||
}
|
||||
|
||||
void BlurHelper::delayUpdate(QWidget *w, bool updateBlurRegionOnly)
|
||||
{
|
||||
if (w->winId() <= 0)
|
||||
return;
|
||||
|
||||
m_update_list.append(w);
|
||||
if (!m_timer.isActive()) {
|
||||
for (auto widget : m_update_list) {
|
||||
// cast to widget and check
|
||||
//KWindowEffects::enableBlurBehind(widget->winId(), false);
|
||||
|
||||
if (!widget)
|
||||
continue;
|
||||
|
||||
if (widget->winId() <= 0)
|
||||
continue;
|
||||
|
||||
bool hasMask = false;
|
||||
if (widget->mask().isNull())
|
||||
hasMask = true;
|
||||
|
||||
QVariant regionValue = widget->property("blurRegion");
|
||||
QRegion region = qvariant_cast<QRegion>(regionValue);
|
||||
|
||||
if (widget->inherits("QMenu")) {
|
||||
//skip menu which has style sheet.
|
||||
if (!widget->styleSheet().isEmpty() || qApp->styleSheet().contains("QMenu")) {
|
||||
break;
|
||||
}
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(widget->rect().adjusted(+5,+5,-5,-5), 6, 6);
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), true, path.toFillPolygon().toPolygon());
|
||||
if (!updateBlurRegionOnly)
|
||||
widget->update();
|
||||
break;
|
||||
}
|
||||
|
||||
if (widget->inherits("QTipLabel")) {
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(widget->rect().adjusted(+3,+3,-3,-3),4, 4);
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), true, path.toFillPolygon().toPolygon());
|
||||
if (!updateBlurRegionOnly)
|
||||
widget->update();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasMask && region.isEmpty())
|
||||
break;
|
||||
|
||||
//qDebug()<<regionValue<<region;
|
||||
//qDebug()<<widget->metaObject()->className()<<widget->geometry()<<widget->mask();
|
||||
if (!region.isEmpty()) {
|
||||
//qDebug()<<"blur region"<<region;
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), true, region);
|
||||
if (!updateBlurRegionOnly)
|
||||
widget->update();
|
||||
} else {
|
||||
//qDebug()<<widget->mask();
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), true, widget->mask());
|
||||
if (!updateBlurRegionOnly)
|
||||
widget->update(widget->mask());
|
||||
}
|
||||
|
||||
//NOTE: we can not setAttribute Qt::WA_TranslucentBackground here,
|
||||
//because the window is about to be shown.
|
||||
//widget->setAttribute(Qt::WA_TranslucentBackground);
|
||||
//KWindowEffects::enableBlurBehind(widget->winId(), true);
|
||||
//widget->update();
|
||||
}
|
||||
m_update_list.clear();
|
||||
} else {
|
||||
m_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void BlurHelper::confirmBlurEnableDelay()
|
||||
{
|
||||
QTimer::singleShot(3000, this, [=]() {
|
||||
bool enable = m_blur_enable;
|
||||
if (enable) {
|
||||
qApp->setProperty("blurEnable", true);
|
||||
} else {
|
||||
qApp->setProperty("blurEnable", false);
|
||||
}
|
||||
for (auto widget : qApp->allWidgets()) {
|
||||
widget->update();
|
||||
if (m_blur_widgets.contains(widget)) {
|
||||
if (widget->winId() > 0)
|
||||
KWindowEffects::enableBlurBehind(widget->winId(), enable);
|
||||
}
|
||||
}
|
||||
// QTimer::singleShot(100, this, [=](){
|
||||
// for (auto widget : m_blur_widgets) {
|
||||
// if (!widget)
|
||||
// continue;
|
||||
// if (widget->winId() > 0)
|
||||
// KWindowEffects::enableBlurBehind(widget->winId(), enable);
|
||||
// }
|
||||
// });
|
||||
});
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BLURHELPER_H
|
||||
#define BLURHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
class BlurHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BlurHelper(QObject *parent = nullptr);
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
void registerWidget(QWidget *widget);
|
||||
void unregisterWidget(QWidget *widget);
|
||||
|
||||
bool isApplicationInBlackList();
|
||||
const QStringList blackList();
|
||||
|
||||
bool shouldSkip(QWidget *w);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void onBlurEnableChanged(bool enable);
|
||||
void onWidgetDestroyed(QWidget *widget);
|
||||
void delayUpdate(QWidget *w, bool updateBlurRegionOnly = false);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief confirmBlurEnableDelay
|
||||
* \note
|
||||
* some application start before kwin, such as peony-qt-desktop.
|
||||
* we have to ensure that the blurEnable protocol not effected by
|
||||
* the case. Delay a while and check it again is a normally way to
|
||||
* confirm.
|
||||
*/
|
||||
void confirmBlurEnableDelay();
|
||||
|
||||
private:
|
||||
QList<QWidget *> m_blur_widgets;
|
||||
|
||||
QList<QWidget *> m_update_list;
|
||||
QTimer m_timer;
|
||||
|
||||
bool m_blur_enable = true;
|
||||
};
|
||||
|
||||
#endif // BLURHELPER_H
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gesture-helper.h"
|
||||
#include "ukui-two-finger-slide-gesture.h"
|
||||
#include "ukui-two-finger-zoom-gesture.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QGestureEvent>
|
||||
#include <QTapAndHoldGesture>
|
||||
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
|
||||
#include <QTouchEvent>
|
||||
|
||||
#include <QScroller>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QItemSelectionModel>
|
||||
|
||||
#include <QScroller>
|
||||
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
GestureHelper::GestureHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
// we translate event by ourselves
|
||||
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
||||
//qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
|
||||
|
||||
m_menu_popped_timer.setInterval(500);
|
||||
m_menu_popped_timer.setSingleShot(true);
|
||||
|
||||
m_pinch_operation_delayer.setInterval(200);
|
||||
m_pinch_operation_delayer.setSingleShot(true);
|
||||
|
||||
m_slider = new UKUI::TwoFingerSlideGestureRecognizer;
|
||||
m_zoomer = new UKUI::TwoFingerZoomGestureRecognizer;
|
||||
|
||||
m_slide_type = QGestureRecognizer::registerRecognizer(m_slider);
|
||||
m_zoom_type = QGestureRecognizer::registerRecognizer(m_zoomer);
|
||||
|
||||
}
|
||||
|
||||
GestureHelper::~GestureHelper()
|
||||
{
|
||||
QGestureRecognizer::unregisterRecognizer(m_slide_type);
|
||||
QGestureRecognizer::unregisterRecognizer(m_zoom_type);
|
||||
}
|
||||
|
||||
void GestureHelper::registerWidget(QWidget *widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
if (widget->contextMenuPolicy() == Qt::NoContextMenu)
|
||||
return;
|
||||
|
||||
//widget->setAttribute(Qt::WA_AcceptTouchEvents, false);
|
||||
|
||||
widget->removeEventFilter(this);
|
||||
|
||||
//widget->grabGesture(Qt::TapGesture);
|
||||
widget->grabGesture(Qt::TapAndHoldGesture);
|
||||
//widget->grabGesture(Qt::PanGesture);
|
||||
//widget->grabGesture(Qt::PinchGesture);
|
||||
//widget->grabGesture(Qt::SwipeGesture);
|
||||
//widget->grabGesture(m_slide_type);
|
||||
//widget->grabGesture(m_zoom_type);
|
||||
|
||||
widget->installEventFilter(this);
|
||||
}
|
||||
|
||||
void GestureHelper::unregisterWidget(QWidget *widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
if (widget->contextMenuPolicy() == Qt::NoContextMenu)
|
||||
return;
|
||||
|
||||
//widget->setAttribute(Qt::WA_AcceptTouchEvents, true);
|
||||
|
||||
widget->removeEventFilter(this);
|
||||
|
||||
//widget->ungrabGesture(Qt::TapGesture);
|
||||
widget->ungrabGesture(Qt::TapAndHoldGesture);
|
||||
//widget->ungrabGesture(Qt::PanGesture);
|
||||
//widget->ungrabGesture(Qt::PinchGesture);
|
||||
//widget->ungrabGesture(Qt::SwipeGesture);
|
||||
//widget->ungrabGesture(m_slide_type);
|
||||
//widget->ungrabGesture(m_zoom_type);
|
||||
}
|
||||
|
||||
bool GestureHelper::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::ActivationChange: {
|
||||
// do not grab inactive window's gesture.
|
||||
auto widget = qobject_cast<QWidget *>(watched);
|
||||
if (widget->isActiveWindow()) {
|
||||
widget->grabGesture(Qt::TapAndHoldGesture);
|
||||
} else {
|
||||
widget->ungrabGesture(Qt::TapAndHoldGesture);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case QEvent::TouchBegin: {
|
||||
m_is_touching = true;
|
||||
auto te = static_cast<QTouchEvent *>(event);
|
||||
m_touch_points = te->touchPoints();
|
||||
m_finger_count = te->touchPoints().count();
|
||||
if (m_finger_count == 1)
|
||||
m_hold_and_tap_pos = te->touchPoints().first().pos();
|
||||
else
|
||||
m_hold_and_tap_pos = QPointF();
|
||||
|
||||
if (m_touch_points.count() > 2) {
|
||||
m_menu_popped_timer.stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::TouchUpdate: {
|
||||
auto te = static_cast<QTouchEvent *>(event);
|
||||
m_touch_points = te->touchPoints();
|
||||
m_finger_count = te->touchPoints().count();
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::TouchCancel:
|
||||
case QEvent::TouchEnd: {
|
||||
m_touch_points.clear();
|
||||
m_is_touching = false;
|
||||
m_finger_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::Gesture: {
|
||||
auto e = static_cast<QGestureEvent *>(event);
|
||||
auto widget = qobject_cast<QWidget *>(watched);
|
||||
if (!widget->isActiveWindow())
|
||||
return false;
|
||||
|
||||
if (auto twoFingerSlideGesture = static_cast<UKUI::TwoFingerSlideGesture *>(e->gesture(m_slide_type))) {
|
||||
//qDebug()<<"has slide gesture";
|
||||
//qDebug()<<"slide"<<twoFingerSlideGesture->state()<<twoFingerSlideGesture->direction()<<twoFingerSlideGesture->totalDelta();
|
||||
if (twoFingerSlideGesture->state() == Qt::GestureUpdated) {
|
||||
// some view doesn't have scroller but also can scroll, such as process list view in ukui-system-monitor.
|
||||
// we send the wheel event to trigger the scroll when slide gesture updated.
|
||||
if (!QScroller::hasScroller(widget)) {
|
||||
bool isHorizal = twoFingerSlideGesture->direction() == UKUI::TwoFingerSlideGesture::Horizal;
|
||||
bool isVertical = twoFingerSlideGesture->direction() == UKUI::TwoFingerSlideGesture::Vertical;
|
||||
if (isVertical) {
|
||||
QWheelEvent we(twoFingerSlideGesture->hotSpot(), twoFingerSlideGesture->delta() * 10, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
|
||||
qApp->sendEvent(widget, &we);
|
||||
} else if (isHorizal) {
|
||||
QWheelEvent we(twoFingerSlideGesture->hotSpot(), twoFingerSlideGesture->delta() * 10, Qt::NoButton, Qt::NoModifier, Qt::Horizontal);
|
||||
qApp->sendEvent(widget, &we);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto twoFingerZoomGesture = static_cast<UKUI::TwoFingerZoomGesture *>(e->gesture(m_zoom_type))) {
|
||||
//qDebug()<<"has zoom gesture"<<twoFingerZoomGesture->state()<<twoFingerZoomGesture->zoomDirection()<<twoFingerZoomGesture->startPoints()<<twoFingerZoomGesture->lastPoints()<<twoFingerZoomGesture->currentPoints();
|
||||
switch (twoFingerZoomGesture->zoomDirection()) {
|
||||
case UKUI::TwoFingerZoomGesture::ZoomIn: {
|
||||
QWheelEvent we(twoFingerZoomGesture->hotSpot(), 100, Qt::NoButton, Qt::ControlModifier);
|
||||
qApp->sendEvent(watched, &we);
|
||||
break;
|
||||
}
|
||||
case UKUI::TwoFingerZoomGesture::ZoomOut: {
|
||||
QWheelEvent we(twoFingerZoomGesture->hotSpot(), -100, Qt::NoButton, Qt::ControlModifier);
|
||||
qApp->sendEvent(watched, &we);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto tapGesture = static_cast<QTapGesture *>(e->gesture(Qt::TapGesture))) {
|
||||
//qDebug()<<tapGesture->gestureType()<<tapGesture->position()<<tapGesture->state();
|
||||
switch (tapGesture->state()) {
|
||||
case Qt::GestureStarted:
|
||||
//mouse press event
|
||||
break;
|
||||
case Qt::GestureCanceled:
|
||||
case Qt::GestureFinished: {
|
||||
//mouse release event
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto tapAndHoldGesture = static_cast<QTapAndHoldGesture*>(e->gesture(Qt::TapAndHoldGesture))) {
|
||||
//qDebug()<<tapAndHoldGesture->gestureType()<<tapAndHoldGesture->position()<<tapAndHoldGesture->state();
|
||||
if (m_menu_popped_timer.isActive())
|
||||
return false;
|
||||
|
||||
m_hold_and_tap_pos = QPoint();
|
||||
|
||||
// check if there is a menu popped.
|
||||
// note that the right click in a widget which has context menu
|
||||
// will trigger the tap and hold gesture. I have no idea to deal
|
||||
// with this case, because i didn't find how to recognize if this
|
||||
// event is translated from mouse event.
|
||||
if (qobject_cast<QMenu *>(watched) || qobject_cast<QMenu *>(qApp->activePopupWidget())) {
|
||||
qDebug()<<"menu popped, may be right click";
|
||||
m_menu_popped = true;
|
||||
}
|
||||
|
||||
switch (tapAndHoldGesture->state()) {
|
||||
case Qt::GestureStarted: {
|
||||
if (m_menu_popped || m_is_mouse_pressed) {
|
||||
return false;
|
||||
} else {
|
||||
m_menu_popped = true;
|
||||
m_menu_popped_timer.start();
|
||||
auto pos = widget->mapFromGlobal(tapAndHoldGesture->position().toPoint());
|
||||
auto gpos = tapAndHoldGesture->position().toPoint();
|
||||
|
||||
if (m_is_native_mouse_move)
|
||||
return false;
|
||||
|
||||
QMouseEvent me(QMouseEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(widget, &me);
|
||||
QContextMenuEvent ce(QContextMenuEvent::Other, pos, gpos, Qt::NoModifier);
|
||||
qApp->sendEvent(widget, &ce);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::GestureCanceled:
|
||||
case Qt::GestureFinished: {
|
||||
m_menu_popped = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto swipeGesture = static_cast<QSwipeGesture *>(e->gesture(Qt::SwipeGesture))) {
|
||||
//qDebug()<<swipeGesture->gestureType()<<swipeGesture->state()<<swipeGesture->horizontalDirection()<<swipeGesture->verticalDirection()<<swipeGesture->swipeAngle();
|
||||
}
|
||||
|
||||
if (auto panGesture = static_cast<QPanGesture*>(e->gesture(Qt::PanGesture))) {
|
||||
//qDebug()<<panGesture->gestureType()<<panGesture->state()<<panGesture->delta()<<panGesture->hotSpot();
|
||||
switch (panGesture->state()) {
|
||||
case Qt::GestureStarted: {
|
||||
auto widget = qobject_cast<QWidget *>(watched);
|
||||
auto pos = widget->mapFromGlobal(QCursor::pos());
|
||||
QMouseEvent me(QMouseEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(widget, &me);
|
||||
if (m_is_paning) {
|
||||
return false;
|
||||
} else {
|
||||
m_is_paning = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::GestureCanceled:
|
||||
case Qt::GestureFinished: {
|
||||
m_is_paning = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::MouseMove: {
|
||||
if (m_finger_count > 1)
|
||||
return true;
|
||||
|
||||
QMouseEvent *me = static_cast<QMouseEvent *>(event);
|
||||
auto widget = static_cast<QWidget *>(watched);
|
||||
if (!widget)
|
||||
return false;
|
||||
|
||||
//qDebug()<<me->type()<<me->pos();
|
||||
|
||||
bool isTranslatedFromTouch = me->source() == Qt::MouseEventSynthesizedByQt;
|
||||
if (!isTranslatedFromTouch) {
|
||||
// do not trigger tap and hold gesture handler
|
||||
m_is_native_mouse_move = true;
|
||||
return false;
|
||||
}
|
||||
m_is_native_mouse_move = false;
|
||||
|
||||
// if we do a hold and tap gesture, we should not trigger mouse move event.
|
||||
// so we have to ignore the small offset of finger move.
|
||||
auto lastTapPoint = m_hold_and_tap_pos.toPoint();
|
||||
auto currentPoint = widget->mapTo(widget->topLevelWidget(), me->pos());
|
||||
|
||||
if (!lastTapPoint.isNull()) {
|
||||
//qDebug()<<lastTapPoint<<currentPoint<<lenthSquared;
|
||||
if (QRect(-50, -50, 100, 100).contains(lastTapPoint - currentPoint)) {
|
||||
if (qobject_cast<QAbstractScrollArea *>(widget) || qobject_cast<QAbstractScrollArea *>(widget->parent()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_is_paning) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case QEvent::DragEnter:
|
||||
case QEvent::DragMove: {
|
||||
if (m_is_paning)
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::MouseButtonPress: {
|
||||
auto me = static_cast<QMouseEvent *>(event);
|
||||
if (me->source() == Qt::MouseEventNotSynthesized)
|
||||
m_is_mouse_pressed = true;
|
||||
else
|
||||
m_is_mouse_pressed = false;
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease: {
|
||||
auto me = static_cast<QMouseEvent *>(event);
|
||||
if (me->source() == Qt::MouseEventNotSynthesized)
|
||||
m_is_mouse_pressed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GESTUREHELPER_H
|
||||
#define GESTUREHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QPointF>
|
||||
#include <QTouchEvent>
|
||||
|
||||
namespace UKUI {
|
||||
class TwoFingerSlideGestureRecognizer;
|
||||
class TwoFingerZoomGestureRecognizer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The GestureHelper class
|
||||
* \note
|
||||
* this class only handle hold and tap gesture for now.
|
||||
*/
|
||||
class GestureHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit GestureHelper(QObject *parent = nullptr);
|
||||
~GestureHelper();
|
||||
|
||||
void registerWidget(QWidget *widget);
|
||||
void unregisterWidget(QWidget *widget);
|
||||
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
bool m_is_touching = false;
|
||||
int m_finger_count = 0;
|
||||
|
||||
QList<QTouchEvent::TouchPoint> m_touch_points;
|
||||
|
||||
// hold and tap gesture
|
||||
bool m_menu_popped = false;
|
||||
QTimer m_menu_popped_timer;
|
||||
QPointF m_hold_and_tap_pos;
|
||||
bool m_is_native_mouse_move = false;
|
||||
|
||||
// pan gesture
|
||||
bool m_is_paning = false;
|
||||
QTimer m_disable_paning_flag_delayer;
|
||||
|
||||
// pinch gesture
|
||||
bool m_is_pinching = false;
|
||||
QTimer m_pinch_operation_delayer;
|
||||
|
||||
UKUI::TwoFingerSlideGestureRecognizer *m_slider;
|
||||
UKUI::TwoFingerZoomGestureRecognizer *m_zoomer;
|
||||
|
||||
Qt::GestureType m_slide_type;
|
||||
Qt::GestureType m_zoom_type;
|
||||
|
||||
bool m_is_mouse_pressed = false;
|
||||
};
|
||||
|
||||
#endif // GESTUREHELPER_H
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proxy-style-plugin.h"
|
||||
#include "proxy-style.h"
|
||||
#include "ukui-style-settings.h"
|
||||
|
||||
#include "application-style-settings.h"
|
||||
|
||||
#include "black-list.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QStyleFactory>
|
||||
#include <QWidget>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace UKUI;
|
||||
|
||||
ProxyStylePlugin::ProxyStylePlugin()
|
||||
{
|
||||
if (UKUIStyleSettings::isSchemaInstalled("org.ukui.style")) {
|
||||
auto settings = UKUIStyleSettings::globalInstance();
|
||||
connect(settings, &UKUIStyleSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "styleName" || key == "widgetThemeName") {
|
||||
if (blackList().contains(qAppName()) || qAppName() == "biometric-manager" || qAppName() == "kylin-software-center.py")
|
||||
return;
|
||||
|
||||
//We should not swich a application theme which use internal style.
|
||||
if (QApplication::style()->inherits("InternalStyle"))
|
||||
return;
|
||||
|
||||
auto appStyleSettings = ApplicationStyleSettings::getInstance();
|
||||
if (appStyleSettings->currentStyleStretagy() != ApplicationStyleSettings::Default)
|
||||
return;
|
||||
|
||||
auto styleName = settings->get("styleName").toString();
|
||||
auto themeName = settings->get("widget-theme-name").toString();
|
||||
|
||||
if (styleName == "ukui-default" || styleName == "ukui-dark" || styleName == "ukui-white"
|
||||
|| styleName == "ukui-black" || styleName == "ukui-light" || styleName == "ukui") {
|
||||
|
||||
if (styleName == "ukui")
|
||||
styleName = "ukui-default";
|
||||
else if (styleName == "ukui-black")
|
||||
styleName = "ukui-dark";
|
||||
else if (styleName == "ukui-white")
|
||||
styleName = "ukui-light";
|
||||
|
||||
} else {
|
||||
styleName = "ukui-default";
|
||||
}
|
||||
|
||||
if (themeName == "default" || themeName == "classical" || themeName == "fashion") {
|
||||
qApp->setProperty("widgetThemeName", themeName);
|
||||
} else {
|
||||
qApp->setProperty("widgetThemeName", "default");
|
||||
}
|
||||
|
||||
qApp->setStyle(new ProxyStyle(styleName));
|
||||
return;
|
||||
|
||||
// for (auto keys : QStyleFactory::keys()) {
|
||||
// if (styleName.toLower() == keys.toLower()) {
|
||||
// qApp->setStyle(new QProxyStyle(styleName));
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// qApp->setStyle(new QProxyStyle("fusion"));
|
||||
// return;
|
||||
}
|
||||
|
||||
if (key == "systemPalette") {
|
||||
onSystemPaletteChanged();
|
||||
}
|
||||
|
||||
if (key == "useSystemPalette") {
|
||||
onSystemPaletteChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
QStyle *ProxyStylePlugin::create(const QString &key)
|
||||
{
|
||||
if (blackList().contains(qAppName()))
|
||||
return new QProxyStyle("fusion");
|
||||
if (key == "ukui") {
|
||||
if (UKUIStyleSettings::isSchemaInstalled("org.ukui.style")) {
|
||||
m_current_style_name = UKUIStyleSettings::globalInstance()->get("styleName").toString();
|
||||
m_current_theme_name = UKUIStyleSettings::globalInstance()->get("widgetThemeName").toString();
|
||||
|
||||
if (m_current_style_name == "ukui-default" || m_current_style_name == "ukui-dark"
|
||||
|| m_current_style_name == "ukui-white" || m_current_style_name == "ukui-black"
|
||||
|| m_current_style_name == "ukui-light" || m_current_style_name == "ukui") {
|
||||
|
||||
if (m_current_style_name == "ukui")
|
||||
m_current_style_name = "ukui-default";
|
||||
else if (m_current_style_name == "ukui-black")
|
||||
m_current_style_name = "ukui-dark";
|
||||
else if (m_current_style_name == "ukui-white")
|
||||
m_current_style_name = "ukui-light";
|
||||
|
||||
if (m_current_theme_name == "default" ||
|
||||
m_current_theme_name == "classical" ||
|
||||
m_current_theme_name == "fashion") {
|
||||
qApp->setProperty("widgetThemeName", m_current_theme_name);
|
||||
} else {
|
||||
qApp->setProperty("widgetThemeName", "default");
|
||||
}
|
||||
|
||||
return new ProxyStyle(m_current_style_name);
|
||||
}
|
||||
|
||||
for (auto styleName : QStyleFactory::keys()) {
|
||||
if (styleName.toLower() == m_current_style_name.toLower())
|
||||
return new QProxyStyle(m_current_style_name);
|
||||
}
|
||||
}
|
||||
return new QProxyStyle("fusion");
|
||||
}
|
||||
return new QProxyStyle("fusion");
|
||||
}
|
||||
|
||||
const QStringList ProxyStylePlugin::blackList()
|
||||
{
|
||||
return blackAppList();
|
||||
}
|
||||
|
||||
void ProxyStylePlugin::onSystemPaletteChanged()
|
||||
{
|
||||
bool useSystemPalette = UKUIStyleSettings::globalInstance()->get("useSystemPalette").toBool();
|
||||
if (useSystemPalette) {
|
||||
auto data = UKUIStyleSettings::globalInstance()->get("systemPalette");
|
||||
if (data.isNull())
|
||||
return;
|
||||
auto palette = qvariant_cast<QPalette>(data);
|
||||
QApplication::setPalette(palette);
|
||||
} else {
|
||||
auto palette = QApplication::style()->standardPalette();
|
||||
QApplication::setPalette(palette);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROXYSTYLEPLUGIN_H
|
||||
#define PROXYSTYLEPLUGIN_H
|
||||
|
||||
#include <QStylePlugin>
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
class ProxyStylePlugin : public QStylePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QStyleFactoryInterface_iid FILE "ukui-style.json")
|
||||
public:
|
||||
ProxyStylePlugin();
|
||||
|
||||
QStyle *create(const QString &key) override;
|
||||
|
||||
const QStringList blackList();
|
||||
|
||||
protected:
|
||||
void onSystemPaletteChanged();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QString m_current_style_name;
|
||||
QString m_current_theme_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROXYSTYLEPLUGIN_H
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proxy-style.h"
|
||||
#include <QWidget>
|
||||
#include "blur-helper.h"
|
||||
#include "gesture-helper.h"
|
||||
#include "window-manager.h"
|
||||
#include "application-style-settings.h"
|
||||
|
||||
#include "ukui-style-settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
|
||||
#include <QWindow>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QWizardPage>
|
||||
|
||||
#include <QStyleHints>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <QLibrary>
|
||||
|
||||
using namespace UKUI;
|
||||
|
||||
ProxyStyle::ProxyStyle(const QString &key) : QProxyStyle(key == nullptr? "fusion": key)
|
||||
{
|
||||
auto settings = UKUIStyleSettings::globalInstance();
|
||||
if (settings) {
|
||||
// m_use_custom_highlight_color = settings->get("useCustomHighlightColor").toBool();
|
||||
// m_custom_highlight_color = QColor(settings->get("customHighlightColor").toString());
|
||||
m_blink_cursor = settings->get("cursorBlink").toBool();
|
||||
m_blink_cursor_time = settings->get("cursorBlinkTime").toInt();
|
||||
qApp->styleHints()->setCursorFlashTime(m_blink_cursor_time);
|
||||
connect(settings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "cursorBlink") {
|
||||
m_blink_cursor = settings->get("cursorBlink").toBool();
|
||||
if (qApp->activeWindow()) {
|
||||
qApp->activeWindow()->update();
|
||||
}
|
||||
if (qApp->activeModalWidget()) {
|
||||
qApp->activeModalWidget()->update();
|
||||
}
|
||||
if (qApp->activePopupWidget()) {
|
||||
qApp->activePopupWidget()->update();
|
||||
}
|
||||
}
|
||||
if (key == "cursorBlinkTime") {
|
||||
m_blink_cursor_time = settings->get("cursorBlinkTime").toInt();
|
||||
qApp->styleHints()->setCursorFlashTime(m_blink_cursor_time);
|
||||
}
|
||||
});
|
||||
|
||||
// connect(settings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
// if (key == "useCustomHighlightColor") {
|
||||
// m_use_custom_highlight_color = settings->get("useCustomHighlightColor").toBool();
|
||||
// }
|
||||
// if (key == "customHighlightColor") {
|
||||
// m_custom_highlight_color = QColor(settings->get("customHighlightColor").toString());
|
||||
// }
|
||||
// if (m_use_custom_highlight_color) {
|
||||
// //qApp->setStyle(new ProxyStyle(key));
|
||||
// auto pal = QApplication::palette();
|
||||
// pal.setColor(QPalette::Active, QPalette::Highlight, m_custom_highlight_color);
|
||||
// pal.setColor(QPalette::Inactive, QPalette::Highlight, m_custom_highlight_color);
|
||||
// pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::transparent);
|
||||
|
||||
// qApp->setPalette(pal);
|
||||
// qApp->paletteChanged(pal);
|
||||
// } else {
|
||||
// auto pal = qApp->style()->standardPalette();
|
||||
// qApp->setPalette(pal);
|
||||
// qApp->paletteChanged(pal);
|
||||
// }
|
||||
// });
|
||||
} else {
|
||||
qWarning("org.ukui.style is null!");
|
||||
}
|
||||
|
||||
m_blur_helper = new BlurHelper(this);
|
||||
// m_gesture_helper = new GestureHelper(this);
|
||||
m_window_manager = new WindowManager(this);
|
||||
|
||||
if (!baseStyle()->inherits("Qt5UKUIStyle")) {
|
||||
m_blur_helper->onBlurEnableChanged(false);
|
||||
}
|
||||
|
||||
m_app_style_settings = ApplicationStyleSettings::getInstance();
|
||||
if (m_app_style_settings) {
|
||||
connect(m_app_style_settings, &ApplicationStyleSettings::colorStretageChanged, [=](const ApplicationStyleSettings::ColorStretagy &stretagy) {
|
||||
/*!
|
||||
\todo implemet palette switch.
|
||||
*/
|
||||
switch (stretagy) {
|
||||
case ApplicationStyleSettings::System: {
|
||||
break;
|
||||
}
|
||||
case ApplicationStyleSettings::Bright: {
|
||||
break;
|
||||
}
|
||||
case ApplicationStyleSettings::Dark: {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
qWarning("org.ukui.style is null!");
|
||||
}
|
||||
|
||||
if (QGSettings::isSchemaInstalled("org.ukui.peripherals-mouse")) {
|
||||
QGSettings *settings = new QGSettings("org.ukui.peripherals-mouse");
|
||||
if (settings->keys().contains("doubleClick")) {
|
||||
int mouse_double_click_time = settings->get("doubleClick").toInt();
|
||||
if (mouse_double_click_time != qApp->doubleClickInterval()) {
|
||||
qApp->setDoubleClickInterval(mouse_double_click_time);
|
||||
}
|
||||
connect(settings, &QGSettings::changed, qApp, [=] (const QString &key) {
|
||||
if (key == "doubleClick") {
|
||||
int mouse_double_click_time = settings->get("doubleClick").toInt();
|
||||
if (mouse_double_click_time != qApp->doubleClickInterval()) {
|
||||
qApp->setDoubleClickInterval(mouse_double_click_time);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
qWarning("org.ukui.peripherals-mouse no doubleClick keys!");
|
||||
}
|
||||
} else {
|
||||
qWarning("org.ukui.peripherals-mouse is null!");
|
||||
}
|
||||
}
|
||||
|
||||
bool ProxyStyle::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int ProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
|
||||
{
|
||||
//FIXME:
|
||||
switch (hint) {
|
||||
case QStyle::SH_Menu_Scrollable: {
|
||||
return 1;
|
||||
}
|
||||
case QStyle::SH_BlinkCursorWhenTextSelected: {
|
||||
return m_blink_cursor;
|
||||
}
|
||||
default:
|
||||
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyStyle::polish(QWidget *widget)
|
||||
{
|
||||
QLibrary gestureLib("libqt5-gesture-extensions");
|
||||
if (widget && gestureLib.load()) {
|
||||
typedef void (*RegisterFun) (QWidget*, QObject*);
|
||||
auto fun = (RegisterFun) gestureLib.resolve("registerWidget");
|
||||
fun(widget, widget);
|
||||
}
|
||||
|
||||
if (!baseStyle()->inherits("Qt5UKUIStyle"))
|
||||
return QProxyStyle::polish(widget);
|
||||
|
||||
QProxyStyle::polish(widget);
|
||||
|
||||
if(!widget)
|
||||
return;
|
||||
if (qAppName() == "ukui-menu" && !widget->inherits("QMenu")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// m_gesture_helper->registerWidget(widget);
|
||||
|
||||
/*!
|
||||
\todo
|
||||
register transparent widget to blurhelper with better way.
|
||||
for now it will let some transparent widget show in error.
|
||||
i have to avoid them by limitting widget's class name,
|
||||
but that is no my expected.
|
||||
*/
|
||||
if (widget->testAttribute(Qt::WA_TranslucentBackground) && widget->isTopLevel()) {
|
||||
//FIXME:
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0))
|
||||
m_blur_helper->registerWidget(widget);
|
||||
#endif
|
||||
|
||||
/*
|
||||
if (QString(widget->metaObject()->className())=="QMenu" ||
|
||||
widget->inherits("Peony::DirectoryViewMenu") ||
|
||||
widget->inherits("Peony::DesktopMenu")) {
|
||||
m_blur_helper->registerWidget(widget);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (widget->isWindow()) {
|
||||
auto var = widget->property("useStyleWindowManager");
|
||||
|
||||
if (var.isNull()) {
|
||||
m_window_manager->registerWidget(widget);
|
||||
} else {
|
||||
if (var.toBool()) {
|
||||
m_window_manager->registerWidget(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
widget->installEventFilter(this);
|
||||
}
|
||||
|
||||
void ProxyStyle::unpolish(QWidget *widget)
|
||||
{
|
||||
QLibrary gestureLib("libqt5-gesture-extensions");
|
||||
if (widget && gestureLib.load()) {
|
||||
typedef void (*UnRegisterFun) (QWidget*, QObject*);
|
||||
auto fun = (UnRegisterFun) gestureLib.resolve("unregisterWidget");
|
||||
fun(widget, widget);
|
||||
}
|
||||
|
||||
if (!baseStyle()->inherits("Qt5UKUIStyle"))
|
||||
return QProxyStyle::unpolish(widget);
|
||||
|
||||
if (qAppName() == "ukui-menu" && !widget->inherits("QMenu")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// m_gesture_helper->unregisterWidget(widget);
|
||||
|
||||
//return QProxyStyle::unpolish(widget);
|
||||
widget->removeEventFilter(this);
|
||||
|
||||
//FIXME:
|
||||
if (widget->testAttribute(Qt::WA_TranslucentBackground) && widget->isTopLevel()) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0))
|
||||
m_blur_helper->unregisterWidget(widget);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (widget->isWindow()) {
|
||||
auto var = widget->property("useStyleWindowManager");
|
||||
|
||||
if (var.isNull()) {
|
||||
m_window_manager->unregisterWidget(widget);
|
||||
} else {
|
||||
if (var.toBool()) {
|
||||
m_window_manager->unregisterWidget(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QProxyStyle::unpolish(widget);
|
||||
}
|
||||
|
||||
void ProxyStyle::polish(QPalette &pal)
|
||||
{
|
||||
QProxyStyle::polish(pal);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROXYSTYLE_H
|
||||
#define PROXYSTYLE_H
|
||||
|
||||
#include "proxy-style_global.h"
|
||||
#include <QProxyStyle>
|
||||
|
||||
class BlurHelper;
|
||||
class GestureHelper;
|
||||
class WindowManager;
|
||||
|
||||
class ApplicationStyleSettings;
|
||||
|
||||
namespace UKUI {
|
||||
|
||||
/*!
|
||||
* \brief The ProxyStyle class
|
||||
* \details
|
||||
* ProxyStyle is direct UKUI platform theme style for provide style-management
|
||||
* in ukui platform.
|
||||
*
|
||||
* ProxyStyle is not a completed style, and it must be created completedly form another
|
||||
* QStyle (exclude itself), such as fusion, oxygen, etc.
|
||||
*
|
||||
* UKUI style provide a global blur effect for qt windows, but it does not mean all window
|
||||
* will be blurred. In fact, you should make your application window be transparent first.
|
||||
* If you do not want your transparent window be blurred, you should add your class to exception,
|
||||
* which cached in gsettings org.ukui.style blur-exception-classes.
|
||||
*/
|
||||
class PROXYSTYLESHARED_EXPORT ProxyStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ProxyStyle(const QString &key);
|
||||
virtual ~ProxyStyle() {}
|
||||
|
||||
//debuger
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
|
||||
int styleHint(StyleHint hint,
|
||||
const QStyleOption *option,
|
||||
const QWidget *widget,
|
||||
QStyleHintReturn *returnData) const;
|
||||
|
||||
void polish(QWidget *widget);
|
||||
void unpolish(QWidget *widget);
|
||||
|
||||
void polish(QPalette &pal);
|
||||
|
||||
private:
|
||||
BlurHelper *m_blur_helper;
|
||||
GestureHelper *m_gesture_helper;
|
||||
WindowManager *m_window_manager;
|
||||
|
||||
ApplicationStyleSettings *m_app_style_settings;
|
||||
|
||||
bool m_blink_cursor = true;
|
||||
int m_blink_cursor_time = 1200;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROXYSTYLE_H
|
|
@ -0,0 +1,53 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2020-01-02T08:39:47
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += widgets KWindowSystem x11extras KWaylandClient
|
||||
|
||||
TARGET = ukui-proxy-style
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin c++11 link_pkgconfig
|
||||
PKGCONFIG += gsettings-qt xcb
|
||||
|
||||
#include(../../libqt5-ukui-style/settings/settings.pri)
|
||||
include(../../libqt5-ukui-style/libqt5-ukui-style.pri)
|
||||
|
||||
DEFINES += PROXYSTYLE_LIBRARY
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
#DEFINES += QT_NO_DEBUG_OUTPUT
|
||||
DEFINES += QT_MESSAGELOGCONTEXT
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
gesture-helper.cpp \
|
||||
proxy-style.cpp \
|
||||
proxy-style-plugin.cpp \
|
||||
blur-helper.cpp \
|
||||
window-manager.cpp
|
||||
|
||||
HEADERS += \
|
||||
gesture-helper.h \
|
||||
proxy-style.h \
|
||||
proxy-style_global.h \
|
||||
proxy-style-plugin.h \
|
||||
blur-helper.h \
|
||||
window-manager.h
|
||||
|
||||
unix {
|
||||
target.path = $$[QT_INSTALL_PLUGINS]/styles
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
ukui-style.json
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROXYSTYLE_GLOBAL_H
|
||||
#define PROXYSTYLE_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(PROXYSTYLE_LIBRARY)
|
||||
# define PROXYSTYLESHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define PROXYSTYLESHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // PROXYSTYLE_GLOBAL_H
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"Keys": [ "ukui" ]
|
||||
}
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Qt5-UKUI's Library
|
||||
*
|
||||
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "window-manager.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <KWindowSystem>
|
||||
#include <NETWM>
|
||||
#include <QX11Info>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
WindowManager::WindowManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_timer.setTimerType(Qt::PreciseTimer);
|
||||
m_timer.setInterval(100);
|
||||
m_timer.setSingleShot(true);
|
||||
m_start_point = QPoint(0, 0);
|
||||
|
||||
qApp->installEventFilter(new AppEventFilter(this));
|
||||
|
||||
if (QX11Info::isPlatformX11())
|
||||
return;
|
||||
|
||||
using namespace KWayland::Client;
|
||||
m_connection = ConnectionThread::fromApplication(qApp);
|
||||
if (!m_connection)
|
||||
return;
|
||||
m_registry = new Registry(this);
|
||||
m_registry->create(m_connection);
|
||||
|
||||
connect(m_registry, &KWayland::Client::Registry::interfaceAnnounced, this, [=](){
|
||||
const auto interface = m_registry->interface( Registry::Interface::Seat );
|
||||
if( interface.name != 0 ) {
|
||||
m_seat = m_registry->createSeat( interface.name, interface.version, this );
|
||||
connect(m_seat, &Seat::hasPointerChanged, this, [=](bool pointerChanged){
|
||||
if (pointerChanged) {
|
||||
if (!m_pointer) {
|
||||
m_pointer = m_seat->createPointer(this);
|
||||
connect(m_pointer, &KWayland::Client::Pointer::buttonStateChanged, this, [=](int serial){
|
||||
m_serial = serial;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
delete m_pointer;
|
||||
m_pointer = nullptr;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
m_registry->setup();
|
||||
m_connection->roundtrip();
|
||||
}
|
||||
|
||||
void WindowManager::registerWidget(QWidget *w)
|
||||
{
|
||||
if (dragable = isDragable(w)) {
|
||||
w->removeEventFilter(this);
|
||||
w->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::unregisterWidget(QWidget *w)
|
||||
{
|
||||
if (dragable)
|
||||
w->removeEventFilter(this);
|
||||
}
|
||||
|
||||
bool WindowManager::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
//qDebug()<<e->type();
|
||||
switch (e->type()) {
|
||||
case QEvent::MouseButtonPress: {
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(e);
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
// If the cursor is not normal arrow cursor,
|
||||
// we should consider there is another excepted operation
|
||||
// which current widget hope do. So we won't trigger
|
||||
// the window move event.
|
||||
QWidget *w = qobject_cast<QWidget *>(obj);
|
||||
if (w->cursor().shape() != Qt::CursorShape::ArrowCursor)
|
||||
return false;
|
||||
|
||||
buttonPresseEvent(obj, event);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case QEvent::MouseMove: {
|
||||
//if (QWidget::mouseGrabber()) return false;
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(e);
|
||||
|
||||
/*! \note In x11, accuracy of the MouseEvent translated from TouchEvent is not
|
||||
* consistent with the accuracy of the native MouseEvent(TouchEvent is a decimal
|
||||
* and MouseEvent is an integer).
|
||||
* When the touch is pressed, if the mouse clicks the right button, Qt will think that
|
||||
* the positions of the two clicks are inconsistent, and will send a MouseMoveEvent,
|
||||
* the source of this MouseMoveEvent is not MouseEventSynthesizedByQt, so this MouseMoveEvent
|
||||
* will not tirgger w->grabMouse(), window will be grabbed by kwin but no TouchEndEvent is received
|
||||
* Therefore, the MouseMoveEvent is filtered out here if the moving distance is too small.
|
||||
* \return return true because some borderless windows handle window dragging separately,
|
||||
* if return false will cause these windows to behave abnormally
|
||||
* \author wangweinan@kylinos.cn
|
||||
*/
|
||||
if (qAbs(event->pos().x() - m_start_point.x()) < 2 ||
|
||||
qAbs(event->pos().y() - m_start_point.y()) < 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//move request
|
||||
mouseMoveEvent(obj, event);
|
||||
return false;
|
||||
}
|
||||
case QEvent::MouseButtonRelease: {
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(e);
|
||||
mouseReleaseEvent(obj, event);
|
||||
return false;
|
||||
}
|
||||
case QEvent::Move: {
|
||||
if (m_current_obj && m_is_dragging) {
|
||||
//qDebug()<<"drag end";
|
||||
endDrag();
|
||||
} else {
|
||||
//qDebug()<<"move";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::buttonPresseEvent(QObject *obj, QMouseEvent *e)
|
||||
{
|
||||
//qDebug()<<"mouse press event";
|
||||
endDrag();
|
||||
QWidget *w = qobject_cast<QWidget*>(obj);
|
||||
//NOTE: We have to skip the border for resize event.
|
||||
auto pos = w->mapFromGlobal(e->globalPos());
|
||||
if (!w->rect().adjusted(10, 10, -10, -10).contains(pos)) {
|
||||
//qDebug()<<"skip move event";
|
||||
return;
|
||||
}
|
||||
|
||||
m_prepared_to_drag = true;
|
||||
m_is_dragging = false;
|
||||
m_current_obj = obj;
|
||||
m_start_point = e->pos();
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
void WindowManager::mouseMoveEvent(QObject *obj, QMouseEvent *e)
|
||||
{
|
||||
//qDebug()<<"mouse move event";
|
||||
|
||||
if (!m_prepared_to_drag)
|
||||
return;
|
||||
|
||||
QWidget *w = qobject_cast<QWidget*>(obj);
|
||||
const QPoint native = e->globalPos();
|
||||
qreal dpiRatio = qApp->devicePixelRatio();
|
||||
if (QX11Info::isPlatformX11()) {
|
||||
if (m_is_dragging)
|
||||
return;
|
||||
|
||||
// qDebug()<<"x11 move start";
|
||||
auto connection = QX11Info::connection();
|
||||
xcb_ungrab_pointer(connection, XCB_TIME_CURRENT_TIME);
|
||||
NETRootInfo(connection, NET::WMMoveResize).moveResizeRequest(w->winId(), native.x() * dpiRatio, native.y() * dpiRatio, NET::Move);
|
||||
// qDebug()<<"x11 move end";
|
||||
|
||||
if (e->source() == Qt::MouseEventSynthesizedByQt) {
|
||||
if (!w->mouseGrabber()) {
|
||||
//! \note Under XI, grabMouse will grab touch devices at the same time.
|
||||
//! When the touch device grabbing changes, xserver will send TouchEndEvent
|
||||
//! to the client that monitors the touch sequence.
|
||||
//! \see qtbase QXcbConnection::xi2SetMouseGrabEnabled
|
||||
w->grabMouse();
|
||||
w->releaseMouse();
|
||||
}
|
||||
}
|
||||
|
||||
xcb_button_release_event_t* event = new xcb_button_release_event_t;
|
||||
memset(event, 0x00, sizeof(xcb_button_release_event_t));
|
||||
event->response_type = XCB_BUTTON_RELEASE;
|
||||
event->event = w->winId();
|
||||
event->time = QX11Info::getTimestamp();
|
||||
event->same_screen = 1;
|
||||
event->root = QX11Info::appRootWindow();
|
||||
event->root_x = native.x();
|
||||
event->root_y = native.y();
|
||||
event->event_x = 0;
|
||||
event->event_y = 0;
|
||||
event->child = 0;
|
||||
event->state = 0;
|
||||
event->detail = XCB_BUTTON_INDEX_1;
|
||||
|
||||
xcb_send_event(connection, false, w->winId(), XCB_EVENT_MASK_BUTTON_RELEASE, (char *) event);
|
||||
delete event;
|
||||
|
||||
xcb_flush(connection);
|
||||
|
||||
m_is_dragging = true;
|
||||
|
||||
m_timer.start();
|
||||
} else {
|
||||
auto widget = qobject_cast<QWidget *>(obj);
|
||||
auto topLevel = widget->topLevelWidget();
|
||||
|
||||
auto shellSurface = KWayland::Client::ShellSurface::fromWindow(topLevel->windowHandle());
|
||||
if (!shellSurface)
|
||||
return;
|
||||
shellSurface->requestMove(m_seat, m_serial);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void WindowManager::mouseReleaseEvent(QObject *obj, QMouseEvent *e)
|
||||
{
|
||||
//qDebug()<<"mouse release event";
|
||||
endDrag();
|
||||
}
|
||||
|
||||
void WindowManager::endDrag()
|
||||
{
|
||||
m_is_dragging = false;
|
||||
m_current_obj = nullptr;
|
||||
m_start_point = QPoint(0, 0);
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
bool WindowManager::isDragable(QWidget *widget)
|
||||
{
|
||||
if (widget && widget->isWindow()) {
|
||||
if ((widget->windowFlags() & Qt::Popup) == Qt::Popup) {
|
||||
if ((widget->windowFlags() & Qt::Tool) == Qt::Tool)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AppEventFilter
|
||||
AppEventFilter::AppEventFilter(WindowManager *parent) : QObject(parent)
|
||||
{
|
||||
m_wm = parent;
|
||||
}
|
||||
|
||||
bool AppEventFilter::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::MouseButtonRelease) {
|
||||
m_wm->m_prepared_to_drag = false;
|
||||
m_wm->m_is_dragging = false;
|
||||
m_wm->m_current_obj = nullptr;
|
||||
m_wm->m_timer.stop();
|
||||
m_wm->m_start_point = QPoint();
|
||||
}
|
||||
|
||||
// if (m_wm->m_is_dragging && m_wm->m_current_obj && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseMove)) {
|
||||
// QMouseEvent mouseEvent(QEvent::MouseButtonRelease,
|
||||
// m_wm->m_start_point,
|
||||
// Qt::LeftButton,
|
||||
// Qt::LeftButton,
|
||||
// Qt::NoModifier);
|
||||
// qApp->sendEvent(m_wm->m_current_obj, &mouseEvent);
|
||||
// }
|
||||
return false;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue