├── .gitignore
├── ContentList.qml
├── InputPage.qml
├── LICENSE
├── LeftSidebar.qml
├── PageManager.qml
├── README.md
├── WindowEntry.qml
├── WindowTilte.qml
├── common
├── Backed
│ ├── Backed.cpp
│ ├── Backed.h
│ └── Backed.pri
├── BaseButton.qml
├── BaseCheckBox.qml
├── BaseSlider.qml
├── BaseTextField.qml
├── BaseToolTip.qml
├── DropPopup.qml
├── Frameless
│ ├── frameless.cpp
│ ├── frameless.h
│ ├── frameless.pri
│ ├── frameless.pro
│ └── qml.qrc
├── ImageButton.qml
├── ScaleImageButton.qml
├── Sidebar.qml
├── SkinBaseButton.qml
├── SkinBaseButton2.qml
├── SkinImageButton.qml
├── SkinModel.qml
├── SkinPopup.qml
├── YaheiText.qml
├── qmlQianDialog
│ ├── BlogDialog.qml
│ ├── SkinQianDialog.qml
│ ├── error.png
│ ├── info.png
│ ├── ok.png
│ └── question.png
├── qmlQianHints
│ ├── Message.qml
│ ├── QianQuestionMark.qml
│ ├── error.png
│ ├── questionMark.png
│ ├── questionMarkDarker.png
│ ├── remind.png
│ └── true.png
└── qmlQianStretchList
│ ├── QianStretchDalegate.qml
│ ├── QianStretchEntry.qml
│ └── icons
│ └── indicator_right.png
├── main.cpp
├── main.qml
├── pages
├── BaseControlPage.qml
├── BaseOtherControlPage.qml
├── HintPage.qml
└── QianProjectPages
│ ├── QianDragViewPage
│ ├── QianDragDelegate.qml
│ ├── QianDragDelegateInformation.qml
│ ├── QianDragView.qml
│ ├── QianDragViewPage.qml
│ ├── qiandrageventcatch.cpp
│ ├── qiandrageventcatch.h
│ └── remove.png
│ ├── QianMergeWatermelonPage
│ ├── Ball.qml
│ ├── BallRun.js
│ ├── FinishWindow.qml
│ ├── GameCanvas.qml
│ ├── MergeAnimal.qml
│ ├── QianMergeWatermelonPage.qml
│ ├── ScoreNumber.qml
│ ├── audio
│ │ ├── d2cb5a4f-1334-4eab-8578-a76aa028644e.mp3
│ │ ├── down.mp3
│ │ ├── down.wav
│ │ ├── finish.mp3
│ │ ├── finish.wav
│ │ ├── merge1.mp3
│ │ ├── merge1.wav
│ │ ├── merge2.mp3
│ │ └── merge2.wav
│ ├── icon
│ │ ├── 1.png
│ │ ├── ball1.png
│ │ ├── ball10.png
│ │ ├── ball11.png
│ │ ├── ball2.png
│ │ ├── ball3.png
│ │ ├── ball4.png
│ │ ├── ball5.png
│ │ ├── ball6.png
│ │ ├── ball7.png
│ │ ├── ball8.png
│ │ ├── ball9.png
│ │ ├── bottomBack.png
│ │ ├── finish.png
│ │ ├── merge10.png
│ │ ├── merge11 - 副本.png
│ │ ├── merge11.png
│ │ ├── merge2.png
│ │ ├── merge3.png
│ │ ├── merge4.png
│ │ ├── merge5.png
│ │ ├── merge6.png
│ │ ├── merge7.png
│ │ ├── merge8.png
│ │ ├── merge9.png
│ │ └── number1.png
│ └── 介绍.png
│ └── QianPhotoPage.qml
├── preview
├── linux.png
└── windwos.png
├── qianWindow.pro
├── qml.qrc
└── windowRes
├── Icon.rc
├── close.png
├── close2.png
├── close_hover.png
├── icon.ico
├── icon.png
├── max.png
├── minimize.png
├── normal.png
└── skin.png
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pro.user
2 | *.pro.user.*
3 | *.qbs.user
4 | *.qbs.user.*
5 | *.moc
6 | moc_*.cpp
7 | moc_*.h
8 | qrc_*.cpp
9 | ui_*.h
10 | /.qmake.cache
11 | /.qmake.stash
12 | build
13 | *.user
14 |
--------------------------------------------------------------------------------
/ContentList.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Layouts 1.12
3 | import QtQuick.Controls 2.14
4 | import QtCharts 2.14
5 | import QtQuick.Controls.Material 2.12
6 | import Qt.Singleton 1.0
7 | import QtGraphicalEffects 1.14
8 | import "qrc:/common"
9 | Rectangle {
10 | id: contentList
11 |
12 | color: mainColor
13 |
14 | RowLayout {
15 | anchors.fill: parent
16 | anchors.rightMargin: 14
17 | anchors.leftMargin: leftSidebar.isOpen ? 14 : 0
18 | anchors.topMargin: 14
19 | anchors.bottomMargin: 14
20 |
21 | Behavior on anchors.leftMargin {
22 | NumberAnimation { duration: 100 }
23 | }
24 |
25 | spacing: 20
26 | LeftSidebar {
27 | id: leftSidebar
28 | Layout.fillHeight: true
29 | layoutPreferredWidth: skin.gradSupport ? 175 : 198
30 | bckColor: !skin.gradSupport && !skin.imageSupport ? skin.contentBackColor:
31 | !skin.light ? Qt.rgba(0,0,0, 0.7 - setting.skinOpacity * 0.38) : Qt.rgba(1,1,1, 0.20 + setting.skinOpacity * 0.68)
32 |
33 | }
34 |
35 | Rectangle {
36 | Layout.leftMargin: -leftSidebar.tailWidth
37 | Layout.fillHeight: true
38 | Layout.fillWidth: true
39 |
40 | radius: skin.gradSupport || skin.imageSupport ? 14 : 8
41 | color: !skin.gradSupport && !skin.imageSupport ? skin.contentBackColor :
42 | !skin.light ? Qt.rgba(0,0,0, 0.7 - setting.skinOpacity * 0.38) : Qt.rgba(1,1,1, 0.10 + setting.skinOpacity * 0.88)
43 |
44 |
45 | layer.enabled: skin.shadow
46 | layer.effect: DropShadow {
47 | color: !skin.gradSupport && !skin.imageSupport ? "#36000000" : "#36FFFFFF"
48 | radius: 8
49 | samples: 17
50 | }
51 |
52 | PageManager {
53 | id: pages
54 | anchors.fill: parent
55 |
56 |
57 | }
58 | }
59 |
60 | }
61 |
62 | Connections {
63 | target: leftSidebar.stretchEntry
64 | onSwitchPage: pages.switchPage(name)
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/InputPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Layouts 1.12
3 | import QtQuick.Controls 2.14
4 | import QtQuick.Controls.Material 2.12
5 | import QtQuick.Dialogs 1.3
6 | import "qrc:/common"
7 |
8 | Item {
9 |
10 | FileDialog {
11 | id: _file
12 | title: "打开文件"
13 | selectMultiple: true
14 | selectFolder: false
15 | nameFilters: ["all files (*.png *.jpg *.mp3 *.mp4 *.avi *.wav)"]
16 | onAccepted: {
17 | for(let i = 0; i < fileUrls.length; i++) {
18 |
19 |
20 | appendFile(fileUrls[i])
21 | }
22 |
23 | }
24 | }
25 |
26 | ListModel {
27 | id: fileModel
28 | }
29 |
30 | function appendFile(fileLocal) {
31 |
32 | let arr = fileLocal.split("/")
33 |
34 | fileModel.append({"fileLocal": fileLocal, "name":arr[arr.length-1]})
35 |
36 | }
37 |
38 | Component {
39 | id: _contentDelegate
40 | Item {
41 | id: block
42 | width: _content.cellWidth; height: _content.cellHeight
43 | clip: true
44 | ColumnLayout {
45 | anchors.fill: parent
46 | anchors.margins: 10
47 | spacing: 6
48 | Rectangle {
49 | Layout.fillWidth: true
50 | Layout.fillHeight: true
51 | radius: 5
52 | color: "#070709"
53 | Image {
54 | anchors.fill: parent
55 | anchors.margins: 4
56 | source: fileLocal
57 | fillMode: Image.PreserveAspectCrop
58 | }
59 | }
60 | YaheiText {
61 | text: name
62 | Layout.fillWidth: true
63 | elide: Text.ElideMiddle
64 | clip: true
65 | font.pixelSize: 14
66 | color: "#888"
67 | }
68 | }
69 | MouseArea {
70 | anchors.fill: parent
71 | onClicked: {
72 | _content.currentIndex = index;
73 | }
74 | }
75 | }
76 | }
77 |
78 |
79 | ColumnLayout {
80 | visible: fileModel.count
81 | anchors.fill: parent
82 | anchors.margins: 8
83 | SkinBaseButton {
84 | onClicked: _file.open()
85 | Layout.preferredHeight: 36
86 | Layout.preferredWidth: 88
87 | backRadius: 4
88 |
89 | contentItem: Item {
90 | RowLayout {
91 | anchors.centerIn: parent
92 | Rectangle {
93 | Layout.preferredHeight: 18
94 | Layout.preferredWidth: 18
95 | radius: 9
96 | color: "#00C1CD"
97 | YaheiText {
98 | text: "+"
99 | font.pixelSize: 14
100 | anchors.centerIn: parent
101 | anchors.verticalCenterOffset: -1
102 | color: "#FFF"
103 | }
104 | }
105 |
106 | YaheiText {
107 | text: "导入"
108 | font.pixelSize: 16
109 | color: "#fff"
110 | horizontalAlignment: Text.AlignHCenter
111 | verticalAlignment: Text.AlignVCenter
112 | }
113 |
114 | }
115 |
116 |
117 | }
118 | }
119 |
120 | GridView {
121 | id: _content
122 | Layout.fillHeight: true
123 | Layout.fillWidth: true
124 | model: fileModel
125 | cellWidth: parent.width/4
126 | cellHeight: cellWidth - 20
127 | delegate: _contentDelegate
128 | clip: true
129 | currentIndex: -1
130 | highlight: Rectangle { color:"transparent"; border.width: 3; border.color: "#00C1CD"; radius: 3 }
131 | }
132 |
133 | }
134 |
135 |
136 |
137 | SkinBaseButton {
138 | visible: !fileModel.count
139 |
140 | width: 260
141 | height: 180
142 | text: ""
143 |
144 | anchors.centerIn: parent
145 |
146 | onClicked: _file.open()
147 |
148 | ColumnLayout {
149 | anchors.centerIn: parent
150 |
151 | RowLayout {
152 | Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
153 |
154 | Rectangle {
155 | Layout.preferredHeight: 18
156 | Layout.preferredWidth: 18
157 | radius: 9
158 |
159 | color: "#00C1CD"
160 |
161 | YaheiText {
162 | text: "+"
163 | font.pixelSize: 14
164 | anchors.centerIn: parent
165 | anchors.verticalCenterOffset: -1
166 | color: "#FFF"
167 | }
168 | }
169 |
170 | YaheiText {
171 | text: "导入"
172 | font.pixelSize: 18
173 | color: "#F5F5F5"
174 | }
175 |
176 | }
177 | YaheiText {
178 | text: "视频、音频、图片"
179 | font.pixelSize: 15
180 | color: "#33ffffff"
181 | }
182 |
183 | }
184 |
185 |
186 |
187 | }
188 |
189 |
190 |
191 | }
192 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 nuoqian
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LeftSidebar.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Layouts 1.14
3 | import QtQuick.Controls.Material 2.12
4 | import QtQuick.Controls 2.14
5 | import "qrc:/common"
6 | import "qrc:/common/qmlQianStretchList"
7 | Sidebar {
8 | z:100
9 | height: parent.height
10 | horizontalPosBase: Sidebar.PosToLeft
11 | property alias stretchEntry: _stretchEntry
12 |
13 | QianStretchEntry {
14 | id: _stretchEntry
15 | anchors.fill: contentObj
16 | clip: true
17 |
18 | }
19 |
20 |
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/PageManager.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Layouts 1.12
3 | import QtQuick.Controls 2.14
4 | import "qrc:/common"
5 | import "qrc:/pages"
6 | import "qrc:/pages/QianProjectPages"
7 | import "qrc:/pages/QianProjectPages/QianMergeWatermelonPage"
8 | import "qrc:/pages/QianProjectPages/QianDragViewPage"
9 |
10 | StackLayout {
11 | id: stack
12 | clip: true
13 | function switchPage(name) {
14 | for (var i = 0; i < stack.data.length; i++) {
15 | if (stack.data[i].name == name) {
16 | stack.currentIndex = i;
17 | break;
18 | }
19 | }
20 | }
21 |
22 | BaseControlPage {
23 | property string name: "Buttons"
24 | width: stack.width
25 | height: stack.height
26 |
27 | }
28 | BaseOtherControlPage {
29 | property string name: "Other"
30 | width: stack.width
31 | height: stack.height
32 | }
33 | HintPage{
34 | property string name: "提示"
35 | width: stack.width
36 | height: stack.height
37 | }
38 |
39 | QianPhotoPage {
40 | property string name: "图片预览器"
41 | width: stack.width
42 | height: stack.height
43 | }
44 |
45 | QianMergeWatermelonPage {
46 | property string name: "合成大西瓜"
47 | width: stack.width
48 | height: stack.height
49 | }
50 |
51 | QianDragViewPage {
52 | property string name: "DragView"
53 | width: stack.width
54 | height: stack.height
55 | }
56 |
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # QianWindow
2 |
使用Qt5.14.2编译 or Qt5.15一键编译
3 |
已经测试windows/linux多平台编译完成
4 |
最新版本视频地址: B站演示入口
5 |
6 | ## Linux编译部分截图
7 | 
8 |
9 | ## Windows编译部分截图
10 | 
11 |
--------------------------------------------------------------------------------
/WindowEntry.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtGraphicalEffects 1.12
3 | import QtQuick.Layouts 1.12
4 | import QtQuick.Controls 2.14
5 | import Qt.Singleton 1.0
6 | import "qrc:/common"
7 | import "qrc:/common/qmlQianDialog"
8 | import "qrc:/common/qmlQianHints"
9 | Rectangle {
10 | id: windowEntry
11 |
12 | color: skin.mainColor
13 | gradient: skin.gradient
14 |
15 |
16 |
17 | Message{
18 | id:messageTip
19 | z: 1
20 | parent: Overlay.overlay
21 | }
22 |
23 | function message(type, message) {
24 | if(type!=='success'&&type!=='error'&&type!=='info'){
25 | return false
26 | }
27 | messageTip.open(type, message)
28 | }
29 |
30 |
31 | BlogDialog {
32 | id: skinQianDialog
33 | backParent: windowEntry
34 | parent: Overlay.overlay
35 | onAccept: {
36 | message('success', "You clicked the accept button!")
37 | skinQianDialog.close();
38 | }
39 | }
40 |
41 | Component.onCompleted: {
42 | skinQianDialog.dialogOpen()
43 | }
44 |
45 |
46 |
47 | layer.enabled: skin.windowShadow && !appStartAnimation.running && !rootWindow.maximized? true : false
48 | layer.effect: DropShadow {
49 | color: "#000000"
50 | }
51 |
52 | ColumnLayout {
53 | anchors.fill: parent
54 | spacing: 0
55 | WindowTilte {
56 | color: skin.titleColor
57 | Layout.fillWidth: true
58 | Layout.preferredHeight: contentList.fullscreen ? 0 : 42
59 | Layout.alignment: Qt.AlignTop
60 | Behavior on Layout.preferredHeight {
61 | NumberAnimation { duration: 300 }
62 | }
63 | clip: true
64 |
65 | }
66 | ContentList {
67 | id: contentList
68 | Layout.fillHeight: true
69 | Layout.fillWidth: true
70 | }
71 | }
72 |
73 | SequentialAnimation {
74 | id: appStartAnimation
75 | running: true
76 | NumberAnimation { target: windowEntry;
77 | properties: "scale"; from: 0.3; to: 1.0; easing.type: Easing.InOutQuad; duration: 200 }
78 |
79 | }
80 |
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/WindowTilte.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Layouts 1.12
3 | import QtQuick.Controls 2.14
4 | import QtQuick.Controls.Material 2.12
5 | import Qt.Singleton 1.0
6 | import "qrc:/common"
7 |
8 | Rectangle {
9 | id: windowtitle
10 |
11 | MouseArea {
12 | anchors.fill: parent
13 | onDoubleClicked: {
14 | scaleInput.clicked();
15 | }
16 | }
17 |
18 | RowLayout {
19 | z: 2
20 | anchors.fill: parent
21 | anchors.leftMargin: 8
22 | anchors.margins: 0
23 | Layout.margins: 0
24 | spacing: 0
25 |
26 |
27 | Image {
28 | antialiasing: true
29 | source: "qrc:/windowRes/icon.png"
30 | Layout.preferredWidth: 30
31 | Layout.preferredHeight: 30
32 | fillMode: Image.PreserveAspectFit
33 | }
34 |
35 | YaheiText {
36 | text: rootWindow.title
37 | font.pixelSize: 17
38 | color: "#FFF"
39 | Layout.fillWidth: true
40 | Layout.leftMargin: 3
41 | }
42 |
43 |
44 | ImageButton {
45 | imageSrc: "qrc:/windowRes/skin.png"
46 | Layout.alignment: Qt.AlignTop | Qt.AlignRight
47 | backHoverColor: "#22FFFFFF"
48 | BaseToolTip {
49 | visible: parent.hovered
50 | text: "主题"
51 | font.pixelSize: 12
52 | delay: 1000
53 |
54 | }
55 | onClicked: {
56 | skin_popup.open()
57 | }
58 | padding: 3
59 |
60 | }
61 |
62 |
63 | ImageButton {
64 | imageSrc: "qrc:/windowRes/minimize.png"
65 | Layout.alignment: Qt.AlignTop | Qt.AlignRight
66 | backHoverColor: "#22FFFFFF"
67 |
68 |
69 | BaseToolTip {
70 | visible: parent.hovered
71 | text: "最小化"
72 | font.pixelSize: 12
73 | delay: 1000
74 |
75 | }
76 | onClicked: {
77 | showMinimized()
78 | }
79 | padding: 1
80 | }
81 | ScaleImageButton {
82 | id: scaleInput
83 | backHoverColor:"#22FFFFFF"
84 | normalImage: "qrc:/windowRes/normal.png"
85 | maxImage: "qrc:/windowRes/max.png"
86 |
87 | BaseToolTip {
88 | visible: parent.hovered
89 | text: scaleInput.shrink ? "最大化" : "恢复"
90 | font.pixelSize: 12
91 | delay: 1000
92 |
93 | }
94 |
95 | Layout.alignment : Qt.AlignTop | Qt.AlignRight
96 | focusPolicy: Qt.NoFocus
97 | onShrinkChanged: {
98 | rootWindow.maximized = !shrink
99 | rootWindow.update();
100 | }
101 | padding: 3
102 |
103 | }
104 | ImageButton {
105 | imageSrc: "qrc:/windowRes/close.png"
106 | //hoverimageSrc:"qrc:/windowRes/close_hover.png"
107 | Layout.alignment: Qt.AlignTop | Qt.AlignRight
108 | backHoverColor: "#FA5151"
109 |
110 | BaseToolTip {
111 | visible: parent.hovered
112 | text: "关闭"
113 | font.pixelSize: 12
114 | delay: 1000
115 |
116 | }
117 | onClicked: rootWindow.closeFunc()
118 | padding: 3
119 | }
120 | }
121 |
122 | SkinPopup {
123 | id: skin_popup
124 | }
125 |
126 |
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/common/Backed/Backed.cpp:
--------------------------------------------------------------------------------
1 | #include "Backed.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | Backed* Backed::m_instance = NULL;
10 | //-----------------------------------------------------------------------------
11 | Backed::Backed( QObject *parent)
12 | : QObject(parent)
13 | {
14 |
15 |
16 | }
17 |
18 |
19 |
20 |
21 | bool Backed::saveFile(QString path, const QString& data)
22 | {
23 |
24 |
25 | QFile file(path.remove("file:///"));
26 |
27 | if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
28 | qWarning()<<"Backed::saveFile err:"<
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace HttpApi
11 | {
12 |
13 | };
14 | // 后端通用类,负责与后端和前端交互
15 | // 诺谦 2022-08-20
16 | class Backed : public QObject
17 | {
18 | Q_OBJECT
19 |
20 | public:
21 |
22 | Q_INVOKABLE bool saveFile(QString path, const QString& data);
23 | Q_INVOKABLE bool copyFile(QString path, QString newPath);
24 | Q_INVOKABLE QString importFile(QString path);
25 | Q_INVOKABLE bool fileExists(QString path);
26 |
27 |
28 |
29 | Backed(QObject *parent = 0);
30 | static Backed* instance()
31 | {
32 | if(m_instance==NULL) {
33 | m_instance = new Backed();
34 | }
35 | return m_instance;
36 | }
37 |
38 | signals:
39 | // 消息提示窗口提示
40 | void errorMessage(QString msg);
41 | void successMessage(QString msg);
42 | void infoMessage(QString msg);
43 | void modalMessage(QString msg, int msec = 2000);
44 | void message(QString msg, int msec = 2000);
45 |
46 |
47 | private slots:
48 |
49 | protected:
50 |
51 |
52 | private:
53 | static Backed *m_instance; // 阻塞实例
54 | };
55 |
56 | // 定义一个回调类指针,用于接收回调.
57 | static QObject *Backed_qobject_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
58 | {
59 | //Q_UNUSED: 向编译器指示参数未在函数的主体中使用。这可用于抑制编译器警告
60 | Q_UNUSED(engine)
61 | Q_UNUSED(scriptEngine)
62 |
63 | return Backed::instance();
64 | }
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/common/Backed/Backed.pri:
--------------------------------------------------------------------------------
1 | INCLUDEPATH += $$PWD
2 | DEPENDPATH += $$PWD
3 |
4 |
5 | HEADERS += $$PWD/Backed.h \
6 |
7 | SOURCES += $$PWD/Backed.cpp \
8 |
--------------------------------------------------------------------------------
/common/BaseButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtGraphicalEffects 1.12
4 | Button {
5 | id: container
6 | property string bckcolor: "#1AAD19"
7 | property string bckHoverColor: Qt.lighter(bckcolor, 0.8)
8 | property int backRadius: 2
9 |
10 | font.family: "Microsoft Yahei"
11 | font.pixelSize: 20
12 | implicitWidth: text.contentWidth + 24
13 | implicitHeight: text.contentHeight + 8
14 | contentItem: Text {
15 | id: text
16 | text: container.text
17 | font: container.font
18 | color: "#fff"
19 | horizontalAlignment: Text.AlignHCenter
20 | verticalAlignment: Text.AlignVCenter
21 | }
22 | background: Rectangle {
23 | anchors.fill: parent
24 | radius: backRadius
25 | color: container.down ? bckcolor :
26 | container.hovered ? bckHoverColor : bckcolor
27 |
28 | layer.enabled: true
29 | layer.effect: DropShadow {
30 | color: bckcolor
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/common/BaseCheckBox.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtQuick.Controls.Material 2.12
4 | CheckBox {
5 | indicator.width: 18
6 | indicator.height: 18
7 | font.family: "Microsoft Yahei"
8 | Material.accent: accentContrlColor
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/common/BaseSlider.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtGraphicalEffects 1.12
4 | Slider {
5 | id: _slider
6 | anchors.verticalCenter: parent.verticalCenter
7 | background: Rectangle {
8 | x: _slider.leftPadding
9 | y: _slider.topPadding + _slider.availableHeight / 2 - height / 2
10 | implicitWidth: 120
11 | implicitHeight: 5
12 | width: _slider.availableWidth
13 | height: implicitHeight
14 | radius: 2
15 | color: "#bdbebf"
16 | gradient: Gradient {
17 | orientation: Gradient.Horizontal;
18 | GradientStop { position: 0.0; color: accentContrlColor }
19 | GradientStop { position: 1.0; color: "#FFFFFF" }
20 |
21 | }
22 | }
23 |
24 | handle: Rectangle {
25 | x: _slider.leftPadding + _slider.visualPosition * (_slider.availableWidth - width)
26 | y: _slider.topPadding + _slider.availableHeight / 2 - height / 2
27 | implicitWidth: 14
28 | implicitHeight: 14
29 | radius: 7
30 | color: "#FFF"
31 | layer.enabled: true
32 | layer.effect: DropShadow {
33 | color: accentContrlColor
34 | }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/common/BaseTextField.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtQuick.Controls.Material 2.12
4 | TextField {
5 | id: textfield
6 | selectByMouse: true
7 | font.family: "Microsoft Yahei"
8 | font.pixelSize: 16
9 | property color backColor: skin.light ? "#77FFFFFF" : "11000000"
10 | property color focusColor: Material.accent
11 | property color normalColor: Material.foreground
12 |
13 | topPadding: 3
14 | bottomPadding: 3
15 | leftPadding: 2
16 | rightPadding: 2
17 |
18 | background: Rectangle {
19 | implicitWidth: 200
20 | implicitHeight: 30
21 | color: backColor
22 |
23 | Rectangle {
24 | anchors.bottom: parent.bottom
25 | width: parent.width
26 | height: (textfield.hovered||textfield.focus) ? 2 :1
27 | color: textfield.focus ? focusColor : normalColor
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/common/BaseToolTip.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls.Material 2.12
3 | import QtQuick.Controls 2.12
4 |
5 | ToolTip {
6 | y: parent.height + 3
7 | leftMargin: 0
8 | rightMargin: 0
9 | topPadding: Qt.platform.os === "linux" ? 11 : 9
10 | leftPadding: 3
11 | rightPadding: 3
12 | Material.foreground: "#EEE"
13 |
14 | font.family: "Microsoft Yahei"
15 | delay: 1000
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/common/DropPopup.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.12
3 | import QtQuick.Layouts 1.12
4 | import QtGraphicalEffects 1.12
5 | Popup {
6 | id: _popup
7 | property int bckRadius: 1
8 |
9 | property var backParent: undefined
10 | signal accept();
11 | signal reject();
12 | property alias acceptText: acceptBtn.text
13 | property alias rejectText: rejectBtn.text
14 | property bool acceptVisible: true
15 | property bool rejectVisible: true
16 |
17 | property bool bottomBtnsVisible: true
18 |
19 |
20 | implicitWidth: 300
21 | implicitHeight: 300
22 |
23 | background: Rectangle {
24 | id: back
25 | anchors.fill: parent
26 | radius: bckRadius
27 | color:skin.light ? "#fff" : "#171717"
28 |
29 |
30 | }
31 | padding: 0
32 |
33 | RowLayout {
34 | id: btns
35 | visible: bottomBtnsVisible
36 | parent: background
37 | anchors.bottom: parent.bottom
38 | anchors.bottomMargin: 12
39 | anchors.rightMargin: 20
40 | anchors.right: parent.right
41 | height: 24
42 |
43 | BaseButton {
44 | id: rejectBtn
45 | text: "取消"
46 | Layout.preferredHeight: 26
47 | Layout.preferredWidth: 68
48 | font.pixelSize: 13
49 | bckcolor: "#eeF65924"
50 | visible: rejectVisible
51 | backRadius: 2
52 | onClicked: {
53 | reject();
54 | close();
55 | }
56 | }
57 |
58 | SkinBaseButton {
59 | id: acceptBtn
60 | text: "确定"
61 | Layout.preferredHeight: 26
62 | Layout.preferredWidth: 68
63 | font.pixelSize: 13
64 | backRadius: 2
65 | visible: acceptVisible
66 | onClicked: {
67 | accept()
68 | }
69 | }
70 | }
71 |
72 | modal: true
73 | dim: false
74 | parent: Overlay.overlay
75 | Rectangle {
76 | visible: backParent == undefined ? false : _popup.visible
77 | opacity: _popup.opacity
78 | parent: backParent == undefined ? background : backParent
79 | anchors.fill: parent
80 | color: "#56000000"
81 | z:99999
82 | }
83 |
84 |
85 | x : Math.round((parent.width - _popup.width) / 2)
86 | y : Math.round((parent.height -_popup.height) / 2)
87 |
88 | focus: true
89 | closePolicy: Popup.CloseOnEscape
90 |
91 | enter: Transition {
92 | id: _enterAnima
93 |
94 | ScriptAction {
95 | script: {
96 |
97 | }
98 | }
99 | NumberAnimation { property: "opacity"; from: 0.3; to:1.0; duration: 300; }
100 | NumberAnimation { property: "y"; from: Math.round((_popup.parent.height - height) / 5); to: Math.round((_popup.parent.height - height) / 2); duration: 300; }
101 | ScriptAction {
102 |
103 | script: {
104 | if(contentChildren.length>0)
105 | btns.parent = contentChildren[0]
106 | }
107 | }
108 | }
109 |
110 | exit: Transition {
111 | id: _exitAnima
112 |
113 | NumberAnimation { target:_popup; property: "opacity"; from: 1.0; to: 0.3; duration: 300; }
114 | NumberAnimation { target:_popup; property: "y"; to: Math.round((_popup.parent.height - height) / 5); duration: 300; }
115 |
116 | // ScriptAction {
117 | // script: acceptFlg ? accept() : reject();
118 | // }
119 | }
120 |
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/common/Frameless/frameless.cpp:
--------------------------------------------------------------------------------
1 | #include "frameless.h"
2 | #include
3 | #include
4 |
5 | FramelessWindow::FramelessWindow(QWindow *parent)
6 | : QQuickWindow (parent),
7 | m_resizable(true),
8 | m_event(Mouse_None)
9 | {
10 | setFlags(Qt::Window | Qt::FramelessWindowHint);
11 | QCoreApplication::instance()->installEventFilter(this); // 给自己加事件过滤器,用来实现拖动窗口
12 |
13 |
14 | m_monitorKeys.clear();
15 | foreach(const auto& key, m_monitorKeysList) {
16 | m_monitorKeys[key._key] = key;
17 | }
18 |
19 | }
20 |
21 | bool FramelessWindow::maximized()
22 | {
23 | return windowStates() == Qt::WindowMaximized ? true : false;
24 | }
25 |
26 | void FramelessWindow::setMaximized(bool max)
27 | {
28 | if (!max)
29 | showNormal();
30 | else
31 | showMaximized();
32 | emit maximizedChanged();
33 | emit resizeUpdate(this->size());
34 | }
35 |
36 | bool FramelessWindow::eventFilter(QObject *obj, QEvent *evt)
37 | {
38 | QMouseEvent *mouse = dynamic_cast(evt);
39 |
40 | if(m_event != Mouse_None && evt->type() == QEvent::WindowStateChange) {
41 | unsetCursor();
42 | m_event = Mouse_None;
43 | } else if(obj == this && mouse && windowStates() != Qt::WindowMaximized) {
44 | if(mouse->button() == Qt::LeftButton && mouse->type() == QEvent::MouseButtonPress) { //按下
45 | m_globalPressPos = mouse->globalPos();
46 | m_pressPos = position();
47 | m_preSize = size();
48 | setCursorEvent(getMousePressEvent(mouse->pos()));
49 | } else if (m_event != Mouse_None && mouse->buttons() == Qt::LeftButton &&
50 | mouse->type() == QEvent::MouseMove) {
51 | if (m_event == Mouse_Move) { // 按下鼠标移动中
52 | setPosition(m_pressPos + mouse->globalPos() - m_globalPressPos);
53 | } else if (m_event != Mouse_Move && m_resizable) {
54 | setCursorEvent(m_event); // 按下鼠标设置窗口大小中
55 | setWindowGeometry(mouse->globalPos());
56 | }
57 | } else if(m_event != Mouse_None && mouse->button() == Qt::LeftButton && mouse->type() ==QEvent::MouseButtonRelease) {
58 | unsetCursor();
59 | m_event = Mouse_None;
60 | } else if (m_event == Mouse_None && mouse->type() == QEvent::MouseMove) { // 鼠标徘徊
61 | MouseEvent currentEven = getResizeArea(mouse->pos());
62 | setCursorEvent(currentEven, false);
63 | }
64 | } else if (m_monitorEnable && evt->type() == QEvent::KeyRelease) {
65 | checkMonitorKeys(obj, evt);
66 | }
67 |
68 | return QQuickWindow::eventFilter(obj,evt);
69 | }
70 |
71 |
72 | FramelessWindow::MouseEvent FramelessWindow::getMousePressEvent(const QPoint &pos)
73 | {
74 | int x = pos.x();
75 | int y = pos.y();
76 | int w = width();
77 | int h = height();
78 | int i;
79 |
80 | if (x <= 8 && y <= 8) {
81 | return Mouse_TopLeft;
82 | } else if (x >=(w - 8) && y <= 8) {
83 | return Mouse_TopRight;
84 | } else if (x <= 8 && y >= (h - 8)) {
85 | return Mouse_BottomLeft;
86 | } else if (x >=(w - 8) && y >= (h - 8)) {
87 | return Mouse_BottomRight;
88 | } else if (y <= 8) {
89 | return Mouse_Top;
90 | } else if (x <= 8 ) {
91 | return Mouse_Left;
92 | } else if (x >=(w - 8) ) {
93 | return Mouse_Right;
94 | } else if (y >= (h - 8)) {
95 | return Mouse_Bottom;
96 | } else {
97 | for (i = 0; i < m_moveArea.length(); i ++) {
98 | if (m_moveArea[i].contains(x, y))
99 | return Mouse_Move;
100 | }
101 | return Mouse_None;
102 | }
103 | }
104 |
105 | FramelessWindow::MouseEvent FramelessWindow::getResizeArea(const QPoint &pos)
106 | {
107 | int x = pos.x();
108 | int y = pos.y();
109 | int w = width();
110 | int h = height();
111 |
112 | if (x <= 8 && y <= 8) {
113 | return Mouse_TopLeft;
114 | } else if (x >=(w - 8) && y <= 8) {
115 | return Mouse_TopRight;
116 | } else if (x <= 8 && y >= (h - 8)) {
117 | return Mouse_BottomLeft;
118 | } else if (x >=(w - 8) && y >= (h - 8)) {
119 | return Mouse_BottomRight;
120 | } else if (y <= 8) {
121 | return Mouse_Top;
122 | } else if (x <= 8 ) {
123 | return Mouse_Left;
124 | } else if (x >=(w - 8) ) {
125 | return Mouse_Right;
126 | } else if (y >= (h - 8)) {
127 | return Mouse_Bottom;
128 | } else {
129 | return Mouse_None;
130 | }
131 | }
132 |
133 | // 改变大小
134 | void FramelessWindow::setWindowGeometry(const QPoint &pos)
135 | {
136 | QPoint offset = m_globalPressPos - pos;
137 |
138 | if (m_globalPressPos == pos)
139 | return;
140 |
141 |
142 | switch (m_event) {
143 | case Mouse_TopLeft:
144 | setGeometryCalc(m_preSize + QSize(offset.x(), offset.y()), m_pressPos - offset);
145 | break;
146 | case Mouse_Top:
147 | setGeometryCalc(m_preSize + QSize(0, offset.y()), m_pressPos - QPoint(0, offset.y()));
148 | break;
149 | case Mouse_TopRight:
150 | setGeometryCalc(m_preSize - QSize(offset.x(), -offset.y()), m_pressPos - QPoint(0, offset.y()));
151 | break;
152 | case Mouse_Left:
153 | setGeometryCalc(m_preSize + QSize(offset.x(), 0), m_pressPos - QPoint(offset.x(), 0));;
154 | break;
155 | case Mouse_Right:
156 | setGeometryCalc(m_preSize - QSize(offset.x(), 0), position());
157 | break;
158 | case Mouse_BottomLeft:
159 | setGeometryCalc(m_preSize + QSize(offset.x(), -offset.y()), m_pressPos - QPoint(offset.x(), 0));
160 | break;
161 | case Mouse_Bottom:
162 | setGeometryCalc(m_preSize + QSize(0, -offset.y()), position());
163 | break;
164 | case Mouse_BottomRight:
165 | setGeometryCalc(m_preSize - QSize(offset.x(), offset.y()), position());
166 | break;
167 | default:
168 | break;
169 | }
170 |
171 | }
172 |
173 | void FramelessWindow::setGeometryCalc(const QSize &size, const QPoint &pos)
174 | {
175 | QPoint endPos = m_pressPos;
176 | QSize endSize = minimumSize();
177 | if (size.width() > minimumWidth()) {
178 | endPos.setX(pos.x());
179 | endSize.setWidth(size.width());
180 | } else if (pos.x() != endPos.x()) {
181 | endPos.setX(m_pressPos.x() + m_preSize.width() - minimumWidth());
182 | }
183 |
184 | if (size.height() > minimumHeight()) {
185 | endPos.setY(pos.y());
186 | endSize.setHeight(size.height());
187 | } else if (pos.y() != endPos.y()) {
188 | endPos.setY(m_pressPos.y() + m_preSize.height() - minimumHeight());
189 | }
190 | setGeometry(QRect(endPos, endSize));
191 | emit resizeUpdate(endSize);
192 |
193 | }
194 |
195 |
196 | void FramelessWindow::setCursorDrag(bool dragging)
197 | {
198 | setCursor(dragging ? Qt::OpenHandCursor : Qt::ArrowCursor);
199 | }
200 |
201 |
202 | void FramelessWindow::setCursorEvent(MouseEvent event, bool isRefrensh)
203 | {
204 |
205 | switch (event) {
206 | case Mouse_TopLeft:
207 | case Mouse_BottomRight:
208 | setCursor(Qt::SizeFDiagCursor);
209 | break;
210 | case Mouse_Top:
211 | case Mouse_Bottom:
212 | setCursor(Qt::SizeVerCursor);
213 | break;
214 | case Mouse_TopRight:
215 | case Mouse_BottomLeft:
216 | setCursor(Qt::SizeBDiagCursor);
217 | break;
218 | case Mouse_Left:
219 | case Mouse_Right:
220 | setCursor(Qt::SizeHorCursor);
221 | break;
222 | default :
223 | if(m_event != event)
224 | unsetCursor();
225 | break;
226 | }
227 | if(isRefrensh)
228 | m_event = event;
229 | }
230 |
231 |
232 | void FramelessWindow::checkMonitorKeys(QObject *obj, QEvent *evt)
233 | {
234 |
235 | QKeyEvent *key = dynamic_cast(evt);
236 | if(!key) return;
237 |
238 | if(m_monitorKeys.contains((Qt::Key)key->key()) && obj == this) {
239 |
240 | bool modifiersCtrl = m_monitorKeys[(Qt::Key)key->key()]._modifiersCtrl;
241 |
242 | if(!modifiersCtrl && key->modifiers() == Qt::NoModifier) {
243 | emit monitorKeyPress((Qt::Key)key->key());
244 |
245 | } else if(modifiersCtrl && key->modifiers() == Qt::ControlModifier) {
246 | emit monitorKeyPress((Qt::Key)key->key());
247 |
248 | }
249 | }
250 |
251 | }
252 |
--------------------------------------------------------------------------------
/common/Frameless/frameless.h:
--------------------------------------------------------------------------------
1 | #ifndef FRAMELESSWINDOW_H
2 | #define FRAMELESSWINDOW_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | class MonitorKey
11 | {
12 | public:
13 | MonitorKey() {}
14 |
15 | MonitorKey (Qt::Key key, bool modifiersCtrl) : _key(key), _modifiersCtrl(modifiersCtrl)
16 | { }
17 |
18 | Qt::Key _key;
19 | bool _modifiersCtrl;
20 |
21 | };
22 |
23 |
24 | class FramelessWindow : public QQuickWindow
25 | {
26 | Q_OBJECT
27 | Q_PROPERTY(bool monitorEnable MEMBER m_monitorEnable)
28 | Q_PROPERTY(bool resizable MEMBER m_resizable)
29 | Q_PROPERTY(QList moveArea MEMBER m_moveArea)
30 | Q_PROPERTY(bool maximized READ maximized WRITE setMaximized NOTIFY maximizedChanged)
31 |
32 | enum MouseEvent {
33 | Mouse_None = 0,
34 | Mouse_Pressed ,
35 | Mouse_TopLeft ,
36 | Mouse_Top,
37 | Mouse_TopRight,
38 | Mouse_Left,
39 | Mouse_Move,
40 | Mouse_Right,
41 | Mouse_BottomLeft,
42 | Mouse_Bottom,
43 | Mouse_BottomRight,
44 | };
45 |
46 | public:
47 | explicit FramelessWindow(QWindow *parent = nullptr);
48 | bool maximized();
49 | void setMaximized(bool max);
50 |
51 | Q_INVOKABLE void setCursorDrag(bool dragging);
52 |
53 | protected:
54 | bool eventFilter(QObject *obj, QEvent *evt) override;
55 |
56 | void checkMonitorKeys(QObject *obj, QEvent *evt);
57 |
58 | signals:
59 | void resizeUpdate(QSize size);
60 | void maximizedChanged();
61 | void monitorKeyPress(Qt::Key key);
62 |
63 | private:
64 | MouseEvent getMousePressEvent(const QPoint &pos);
65 | MouseEvent getResizeArea(const QPoint &pos);
66 | void setWindowGeometry(const QPoint &pos);
67 | void setCursorEvent(MouseEvent event, bool isRefrensh = true);
68 | void setGeometryCalc(const QSize &size, const QPoint &pos);
69 |
70 | bool m_resizable;
71 | MouseEvent m_event;
72 | QPoint m_globalPressPos; // 鼠标按下的全局坐标
73 | QPoint m_pressPos; // 鼠标按下的应用程序内的坐标
74 | bool m_move;
75 | QSize m_preSize;
76 | QList m_moveArea;
77 |
78 | bool m_monitorEnable{true};
79 |
80 | QList m_monitorKeysList{};
81 | QHash m_monitorKeys;
82 | };
83 |
84 | #endif
85 |
--------------------------------------------------------------------------------
/common/Frameless/frameless.pri:
--------------------------------------------------------------------------------
1 | INCLUDEPATH += $$PWD
2 | DEPENDPATH += $$PWD
3 |
4 |
5 | HEADERS += $$PWD/frameless.h \
6 |
7 | SOURCES += $$PWD/frameless.cpp \
8 |
--------------------------------------------------------------------------------
/common/Frameless/frameless.pro:
--------------------------------------------------------------------------------
1 | QT += quick
2 |
3 | CONFIG += c++11
4 |
5 | # The following define makes your compiler emit warnings if you use
6 | # any Qt feature that has been marked deprecated (the exact warnings
7 | # depend on your compiler). Refer to the documentation for the
8 | # deprecated API to know how to port your code away from it.
9 | DEFINES += QT_DEPRECATED_WARNINGS
10 |
11 | # You can also make your code fail to compile if it uses deprecated APIs.
12 | # In order to do so, uncomment the following line.
13 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
14 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
15 |
16 | SOURCES += \
17 | framelesswindow.cpp \
18 | main.cpp
19 |
20 | RESOURCES += qml.qrc
21 |
22 | # Additional import path used to resolve QML modules in Qt Creator's code model
23 | QML_IMPORT_PATH =
24 |
25 | # Additional import path used to resolve QML modules just for Qt Quick Designer
26 | QML_DESIGNER_IMPORT_PATH =
27 |
28 | # Default rules for deployment.
29 | qnx: target.path = /tmp/$${TARGET}/bin
30 | else: unix:!android: target.path = /opt/$${TARGET}/bin
31 | !isEmpty(target.path): INSTALLS += target
32 |
33 | HEADERS += \
34 | framelesswindow.h
35 |
--------------------------------------------------------------------------------
/common/Frameless/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | main.qml
4 |
5 |
6 |
--------------------------------------------------------------------------------
/common/ImageButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 |
4 | Button {
5 | id: container
6 | implicitWidth: 38
7 | implicitHeight: 24
8 | property var imageSrc: ''
9 | property var hoverimageSrc: null
10 | property var backHoverColor: 'transparent'
11 | property var backColor: 'transparent'
12 | property alias radius: back.radius
13 |
14 | clip: true
15 | padding: 0
16 | background: Rectangle {
17 | id: back
18 | anchors.fill: parent
19 | color: container.hovered ? backHoverColor : backColor
20 | Image {
21 | anchors.centerIn: parent
22 | antialiasing: true
23 | source: container.hovered ? (hoverimageSrc == null? imageSrc : hoverimageSrc)
24 | : imageSrc
25 | fillMode: Image.PreserveAspectFit
26 |
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/common/ScaleImageButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.12
3 |
4 | Button {
5 | id: container
6 | implicitWidth: 38
7 | implicitHeight: 24
8 | property bool shrink: true
9 | property var normalImage: 'qrc:/res/scale1.png'
10 | property var maxImage: 'qrc:/res/scale0.png'
11 |
12 | property var backHoverColor: '#20334455'
13 | property var backColor: 'transparent'
14 |
15 | clip: true
16 | padding: 0
17 | background: Rectangle {
18 | anchors.fill: parent
19 | color: container.hovered ? backHoverColor : backColor
20 | Image {
21 | anchors.fill: parent
22 | anchors.margins: container.padding
23 | antialiasing: true
24 | source: shrink ? normalImage : maxImage
25 | fillMode: Image.PreserveAspectFit
26 | }
27 | }
28 |
29 | onClicked: {
30 | shrink = !shrink
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/common/Sidebar.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtGraphicalEffects 1.12
4 | import QtQml 2.14
5 | import QtGraphicalEffects 1.12
6 | import QtQuick.Layouts 1.12
7 | Item {
8 | id: container
9 |
10 | enum HorizontalPosBase {
11 | PosToLeft,
12 | PosToRight
13 | }
14 |
15 |
16 | property int horizontalPosBase: Sidebar.PosToLeft
17 |
18 |
19 | property int tailHeight: container.height*0.25
20 | property int tailSlopeHeight: container.height*0.008
21 |
22 | property bool enbale: true
23 |
24 | property bool isOpen: true
25 |
26 |
27 | property alias backOpacity : content.opacity
28 | property color bckColor: "#fff"
29 | property color btnColor : "#666"
30 | property var contentObj : content
31 |
32 | property real layoutPreferredWidth: 0
33 |
34 | property int tailWidth: layoutPreferredWidth ? layoutPreferredWidth*0.083 : container.width*0.083
35 |
36 | x: horizontalPosBase === Sidebar.PosToLeft ? isOpen ? 0 : -content.width
37 | : isOpen ? parent.width-width : parent.width-tailWidth
38 | Layout.preferredWidth: isOpen ? layoutPreferredWidth : tailWidth
39 |
40 | Behavior on x {
41 | NumberAnimation { duration:100 }
42 | }
43 |
44 | Behavior on Layout.preferredWidth {
45 | NumberAnimation { duration:100 }
46 | }
47 |
48 | MouseArea {
49 | id: bottomMouse
50 | anchors.fill: parent
51 | hoverEnabled: container.enbale
52 |
53 | }
54 |
55 | Rectangle {
56 | id: content
57 | width: parent.width-tailWidth
58 | height: parent.height
59 | x: horizontalPosBase === Sidebar.PosToLeft ? 0 : tailWidth
60 | color: bckColor
61 | visible: horizontalPosBase === Sidebar.PosToLeft ? (container.x == -content.width ? false : true ) :
62 | (container.x == parent.width-tailWidth ? false : true)
63 | radius: skin.gradSupport || skin.imageSupport ? 14 : 8
64 | clip: true
65 | onVisibleChanged: {
66 | canvas.requestPaint()
67 | }
68 |
69 | layer.enabled: skin.shadow
70 | layer.effect: DropShadow {
71 | color: !skin.gradSupport && !skin.imageSupport ? "#36000000" : "#36FFFFFF"
72 | radius: 8
73 | samples: 17
74 |
75 | }
76 |
77 | onColorChanged: canvas.requestPaint()
78 | }
79 |
80 | Canvas {
81 | id: canvas
82 | width: tailWidth
83 | height: tailHeight
84 | y: container.height/2 -height/2
85 | x: horizontalPosBase === Sidebar.PosToLeft ? parent.width-tailWidth : 0
86 | antialiasing: true
87 | smooth: true
88 | rotation: horizontalPosBase === Sidebar.PosToLeft ? 0 : 180
89 | opacity: !isOpen ? 1.0 : (isOpen && !(bottomMouse.containsMouse || mouse.containsMouse)) ? 0.0 : 1.0
90 | onPaint: {
91 | var ctx = getContext("2d");
92 | ctx.clearRect(0,0, canvas.width, canvas.height);
93 |
94 |
95 | ctx.shadowBlur = skin.shadow
96 | ctx.shadowColor = !skin.gradSupport && !skin.imageSupport ? "#36000000" : "#36FFFFFF"
97 |
98 | ctx.fillStyle = bckColor;
99 | ctx.strokeStyle = mouse.containsMouse ? skin.accentColor : !skin.gradSupport && !skin.imageSupport ? "#36000000" : "#36FFFFFF"
100 | ctx.beginPath()
101 |
102 | ctx.moveTo(0,0)
103 | ctx.lineTo(canvas.width-2, tailSlopeHeight)
104 | ctx.lineTo(canvas.width-2, canvas.height - tailSlopeHeight)
105 | ctx.lineTo(0, canvas.height)
106 | ctx.closePath()
107 | ctx.stroke()
108 | ctx.fill()
109 |
110 | ctx.shadowBlur = 0
111 |
112 | ctx.fillStyle = skin.stretchColor
113 |
114 | ctx.beginPath()
115 | var arrowMargin = tailWidth*0.35
116 | var arrowHalfHeight = tailHeight*0.04
117 |
118 | if (isOpen) {
119 | context.moveTo(tailWidth-arrowMargin*1.2, height/2-arrowHalfHeight);
120 | context.lineTo(tailWidth-arrowMargin*1.2, height/2+arrowHalfHeight);
121 | context.lineTo(arrowMargin*0.7, height/2);
122 | } else {
123 | context.moveTo(arrowMargin*0.7, height/2-arrowHalfHeight);
124 | context.lineTo(arrowMargin*0.7, height/2+arrowHalfHeight);
125 | context.lineTo(tailWidth-arrowMargin*1.1, height/2);
126 |
127 | }
128 | context.closePath();
129 | context.fill();
130 | }
131 | MouseArea {
132 | id: mouse
133 | anchors.fill: parent
134 | hoverEnabled: container.enbale
135 | onContainsMouseChanged: canvas.requestPaint()
136 | onClicked: {
137 | isOpen = !isOpen
138 | canvas.requestPaint()
139 | }
140 | }
141 |
142 | Behavior on opacity {
143 | NumberAnimation { duration: 300 }
144 | }
145 | }
146 |
147 |
148 |
149 | }
150 |
151 |
--------------------------------------------------------------------------------
/common/SkinBaseButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtGraphicalEffects 1.12
4 | Button {
5 | id: container
6 | property color bckcolor: accentContrlColor
7 | property string bckHoverColor: Qt.lighter(bckcolor, 0.8)
8 | property color textcolor: skin.light ? "#fff" : "#eee"
9 | property int backRadius: 3
10 |
11 | font.family: "Microsoft Yahei"
12 | font.pixelSize: 20
13 | implicitWidth: text.contentWidth + 24
14 | implicitHeight: text.contentHeight + 8
15 |
16 | contentItem: Text {
17 | id: text
18 | anchors.centerIn: parent
19 | text: container.text
20 | font: container.font
21 | color: textcolor
22 | horizontalAlignment: Text.AlignHCenter
23 | verticalAlignment: Text.AlignVCenter
24 | }
25 | background: Rectangle {
26 | anchors.fill: parent
27 | radius: backRadius
28 | color: bckcolor
29 | gradient: container.hovered ? skin.gradient : undefined
30 | Rectangle {
31 | anchors.fill: parent
32 | color: "#11000000"
33 | visible: container.hovered
34 | }
35 | layer.enabled: true
36 | layer.effect: DropShadow {
37 | color: bckcolor
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/common/SkinBaseButton2.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import QtGraphicalEffects 1.12
4 | import Qt.Singleton 1.0
5 | Button {
6 | id: container
7 | property color bckcolor: skin.light ? accentContrlColor : "#eee"
8 | property int backRadius: 3
9 |
10 | font.family: "Microsoft Yahei"
11 | font.pixelSize: 20
12 | implicitWidth: text.contentWidth + 24
13 | implicitHeight: text.contentHeight + 8
14 | contentItem: Text {
15 | id: text
16 | anchors.centerIn: parent
17 | text: container.text
18 | font: container.font
19 | color: bckcolor
20 | horizontalAlignment: Text.AlignHCenter
21 | verticalAlignment: Text.AlignVCenter
22 | }
23 | background: Rectangle {
24 | anchors.fill: parent
25 | radius: backRadius
26 | color: skin.light ? "#33FFFFFF" : "transparent"
27 | border.width: container.checked ? 3 : container.hovered ? 2 : 1
28 | border.color: container.checked ? Qt.lighter(bckcolor, 0.80) : container.hovered ? Qt.lighter(bckcolor, 0.88) : bckcolor
29 |
30 | layer.enabled: true
31 | layer.effect: DropShadow {
32 | color: bckcolor
33 | }
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/common/SkinImageButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.12
3 | import Qt.Singleton 1.0
4 |
5 | Button {
6 | id: container
7 | property int radius: 3
8 | property var imageSrc: ''
9 | implicitWidth: 21
10 | implicitHeight: 21
11 | clip: true
12 |
13 | background: Rectangle {
14 | id: back
15 | anchors.fill: container
16 | radius: container.radius
17 | // gradient: SkinSingleton.skins[setting.skinIndex]
18 | Image {
19 | anchors.fill: parent
20 | anchors.margins: container.radius
21 | source: imageSrc
22 | }
23 | Rectangle {
24 | anchors.fill: parent
25 | radius: container.radius
26 | color: !container.hovered? "#11000000" : "#11ffffff"
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/common/SkinModel.qml:
--------------------------------------------------------------------------------
1 | pragma Singleton
2 | import QtQuick 2.12
3 | import QtQml.Models 2.12
4 | import QtQuick.Layouts 1.14
5 | import Qt.labs.settings 1.0
6 |
7 | Item {
8 | property alias exteriorComponent: _exteriorComponent
9 | property int skinCustomIdx: skins.length-1
10 | property bool skinCustomUpdate: false
11 |
12 |
13 | property list- skins : [
14 | Item {
15 | property string name : "简约白色"
16 | property bool windowShadow: true
17 | property bool shadow: true
18 | property string mainColor: "#f0f0f0"
19 | property string titleColor : "#4785FF"
20 | property string contentBackColor : "#FFF"
21 |
22 | property string accentColor : "#4785FF"
23 | property string accentContrlColor : "#4785FF"
24 |
25 | property string stretchColor : "#4785FF"
26 | property string stretchBackHoverColor : "#444785FF"
27 | property string stretchSelectColor: "#fff"
28 | property string stretchBackColor: "#F6F6F6"
29 | property string stretchSelectBackColor: "#4785FF"
30 |
31 | property string stretchFoldSelectColor: "#4785FF"
32 | property string stretchFoldBackColor: "transparent"
33 |
34 |
35 | property bool light : true
36 |
37 | property bool gradSupport: false
38 | property bool imageSupport: false
39 |
40 |
41 | },
42 |
43 | Item{
44 | property string name : "暗黑风格"
45 | property bool shadow: false
46 | property string mainColor: "#000"
47 | property string titleColor: "#070709"
48 | property string contentBackColor: "#252528"
49 |
50 | property string accentColor: "#eee"
51 | property string accentContrlColor: "#22ffffff"
52 |
53 |
54 | property string stretchColor : "#eee"
55 | property string stretchBackHoverColor : "#05ffffff"
56 | property string stretchSelectColor: "#00C1CD"
57 | property string stretchBackColor: "transparent"
58 |
59 | property string stretchSelectBackColor: "#11ffffff"
60 |
61 |
62 | property string stretchFoldSelectColor: "#00C1CD"
63 | property string stretchFoldBackColor: "#252528"
64 | property string stretchFoldBackSelectColor: "#343337"
65 |
66 | property bool light : false
67 | property bool gradSupport: false
68 | property bool imageSupport: false
69 |
70 |
71 | },
72 | Item {
73 | property string name : "午夜巴黎"
74 | property bool windowShadow: true
75 | property bool shadow: true
76 | property string mainColor: "#44ffffff"
77 | property string titleColor : "transparent"
78 | property string contentBackColor : "#FFF"
79 | property string accentColor : "#7C56FF"
80 | property string accentContrlColor : "#7C56FF"
81 |
82 | property string stretchColor : "#4785FF"
83 | property string stretchBackHoverColor : "#11ffffff"
84 | property string stretchSelectColor: "#fff"
85 | property string stretchBackColor: "transparent"
86 | property string stretchSelectBackColor: "#ee6BB1FF"
87 |
88 | property string stretchFoldSelectColor: "#4785FF"
89 | property string stretchFoldBackColor: "transparent"
90 |
91 |
92 | property bool light : true
93 | property bool gradSupport: true
94 | property alias gradient: _gradient
95 | property bool imageSupport: false
96 | property real gradMainOpacity: 0.01
97 |
98 |
99 |
100 | Gradient {
101 | id: _gradient
102 | orientation: Gradient.Horizontal;
103 | GradientStop { position: 0.0; color: "#12B4FF" }
104 | GradientStop { position: 0.15; color: "#3297FF" }
105 | GradientStop { position: 1.0; color: "#B822FF" }
106 | }
107 |
108 |
109 | },
110 |
111 | Item {
112 | property string name : "秋日暖阳"
113 | property bool windowShadow: true
114 | property bool shadow: true
115 | property string mainColor: "#44ffffff"
116 | property string titleColor : "transparent"
117 | property string contentBackColor : "#FFF"
118 | property string accentColor : "#FF5245"
119 | property string accentContrlColor : "#FF5245"
120 |
121 | // 伸展
122 | property string stretchColor : "#FF5146"
123 | property string stretchBackHoverColor : "#11ffffff"
124 | property string stretchSelectColor: "#fff"
125 | property string stretchBackColor: "transparent"
126 | property string stretchSelectBackColor: "#eeFF8A6D"
127 |
128 | property string stretchFoldSelectColor: "#FF5146"
129 | property string stretchFoldBackColor: "transparent"
130 |
131 |
132 | property bool light : true
133 | property bool gradSupport: true
134 | property alias gradient: _gradient2
135 | property bool imageSupport: false
136 | property real gradMainOpacity: 0.01
137 |
138 |
139 |
140 | Gradient {
141 | id: _gradient2
142 | orientation: Gradient.Horizontal;
143 | GradientStop { position: 0.0; color: "#FF7C20" }
144 | GradientStop { position: 0.3; color: "#FF4750" }
145 | GradientStop { position: 0.7; color: "#FF177A" }
146 | GradientStop { position: 1.0; color: "#FF0090" }
147 | }
148 | },
149 | Item {
150 | property string name : "午夜巴黎(透明)"
151 | property bool windowShadow: false
152 | property bool shadow: false
153 | property string mainColor: "#44ffffff"
154 | property string titleColor : "transparent"
155 | property string contentBackColor : "#FFF"
156 | property string accentColor : "#7C56FF"
157 | property string accentContrlColor : "#7C56FF"
158 |
159 | // 伸展
160 | property string stretchColor : "#4785FF"
161 | property string stretchBackHoverColor : "#446BB1FF"
162 | property string stretchSelectColor: "#fff"
163 | property string stretchBackColor: "transparent"
164 | property string stretchSelectBackColor: "#886BB1FF"
165 |
166 | property string stretchFoldSelectColor: "#4785FF"
167 | property string stretchFoldBackColor: "transparent"
168 |
169 |
170 | property bool light : true
171 | property bool gradSupport: true
172 | property bool imageSupport: false
173 | property real gradMainOpacity: 0.01
174 |
175 |
176 |
177 | property alias gradient: _gradient3
178 |
179 |
180 | Gradient {
181 | id: _gradient3
182 | orientation: Gradient.Horizontal;
183 | GradientStop { position: 0.0; color: "#AA12B4FF" }
184 | GradientStop { position: 0.15; color: "#AA3297FF" }
185 | GradientStop { position: 1.0; color: "#AAB822FF" }
186 | }
187 |
188 |
189 | },
190 |
191 | Item {
192 | property string name : "简约白色(透明)"
193 | property bool windowShadow: false
194 | property bool shadow: false
195 | property string mainColor: "#66FFFFFF"
196 | property string titleColor : "#aa4785FF"
197 | property string contentBackColor : "#baFFFFFF"
198 |
199 | property string accentColor : "#4785FF"
200 | property string accentContrlColor : "#4785FF"
201 |
202 | // 伸展
203 | property string stretchColor : "#4785FF"
204 | property string stretchBackHoverColor : "#11ffffff"
205 | property string stretchSelectColor: "#fff"
206 | property string stretchBackColor: "#AAF6F6F6"
207 | property string stretchSelectBackColor: "#AA4785FF"
208 |
209 | property string stretchFoldSelectColor: "#4785FF"
210 | property string stretchFoldBackColor: "transparent"
211 |
212 |
213 | property bool light : true
214 |
215 | property bool gradSupport: false
216 | property bool imageSupport: false
217 |
218 |
219 |
220 | },
221 |
222 | Item {
223 | property string name : "蓝灰色"
224 | property bool windowShadow: true
225 | property bool shadow: true
226 | property string mainColor: "#77ffffff"
227 | property string titleColor : "transparent"
228 | property string contentBackColor : "#FFF"
229 | property string accentColor : "#507EA4"
230 | property string accentContrlColor : "#507EA4"
231 |
232 | property string stretchColor : "#507EA4"
233 | property string stretchBackHoverColor : "#11ffffff"
234 | property string stretchSelectColor: "#fff"
235 | property string stretchBackColor: "transparent"
236 | property string stretchSelectBackColor: "#C2D2DF"
237 |
238 | property string stretchFoldSelectColor: "#507EA4"
239 | property string stretchFoldBackColor: "transparent"
240 |
241 |
242 | property bool light : true
243 | property bool gradSupport: true
244 | property alias gradient: _gradient4
245 | property bool imageSupport: false
246 | property real gradMainOpacity: 0.51
247 |
248 |
249 | Gradient {
250 | id: _gradient4
251 | orientation: Gradient.Horizontal;
252 | GradientStop { position: 0.0; color: "#507EA4" }
253 | }
254 | }
255 | ]
256 |
257 | Component {
258 | id: _exteriorComponent
259 | Item {
260 | id: content
261 | property var skinTarget
262 | width: content.GridView.view.cellWidth; height: content.GridView.view.cellHeight
263 | clip: true
264 | Column {
265 | anchors.fill: parent
266 | spacing: 6
267 | anchors.topMargin: 10
268 | Rectangle {
269 | implicitWidth: content.width - 20
270 | implicitHeight: implicitWidth - 30
271 | anchors.horizontalCenter: parent.horizontalCenter
272 | color: skins[index].mainColor
273 | gradient: skins[index].gradient
274 |
275 | Image {
276 | visible: skins[index].imageSupport
277 | anchors.fill: parent
278 | source: !skins[index].imageSupport ? "" : skins[index].imageUrl
279 | fillMode: Image.PreserveAspectCrop
280 | mipmap: true
281 | }
282 |
283 |
284 | ColumnLayout {
285 | anchors.fill: parent
286 | spacing: 0
287 | z: 1
288 | Rectangle {
289 | Layout.preferredHeight: 14
290 | Layout.fillWidth: true
291 | color: skins[index].imageSupport ? "#33000000" : skins[index].titleColor
292 |
293 | }
294 |
295 | Rectangle {
296 | Layout.fillHeight: true
297 | Layout.fillWidth: true
298 |
299 | color: !skins[index].light ? "#44000000" : "#11ffffff"
300 | RowLayout {
301 | anchors.fill: parent
302 | anchors.margins: 6
303 |
304 | Rectangle {
305 | z: 2
306 | Layout.fillHeight: true
307 | Layout.preferredWidth: 40
308 | color: !skins[index].gradSupport && !skins[index].imageSupport ? skins[index].contentBackColor :
309 | !skins[index].light ? "#33000000" : "#33ffffff"
310 | radius: 4
311 |
312 | }
313 |
314 | Rectangle {
315 | z: 2
316 | Layout.fillHeight: true
317 | Layout.fillWidth: true
318 | color: !skins[index].gradSupport && !skins[index].imageSupport ? skins[index].contentBackColor :
319 | !skins[index].light ? "#33000000" : "#33ffffff"
320 | radius: 4
321 | }
322 |
323 | }
324 | }
325 |
326 |
327 | }
328 | }
329 |
330 | YaheiText {
331 | text: skins[index].name
332 | font.pixelSize: 14
333 | color: skins[content.GridView.view.currentIndex].accentColor
334 | opacity: 0.7
335 | anchors.horizontalCenter: parent.horizontalCenter
336 | }
337 | }
338 | MouseArea {
339 | anchors.fill: parent
340 | onClicked: {
341 | content.GridView.view.requestSwitchSkin(index)
342 | }
343 | }
344 |
345 | }
346 |
347 | }
348 |
349 |
350 |
351 | }
352 |
--------------------------------------------------------------------------------
/common/SkinPopup.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.12
3 | import QtQuick.Layouts 1.12
4 | import QtGraphicalEffects 1.12
5 | import Qt.labs.platform 1.0
6 | import Qt.Singleton 1.0
7 | import "qrc:/common"
8 |
9 | Popup {
10 | id: _popup
11 |
12 |
13 |
14 |
15 | background: Rectangle {
16 | implicitWidth: 650
17 | implicitHeight: 420
18 | radius: 1
19 | layer.enabled: true
20 | gradient: skin.gradient
21 | layer.effect: DropShadow {
22 | visible: !_enterAnima.running & !_exitAnima.running
23 | }
24 | Image {
25 | id: image
26 | visible: skin.imageSupport
27 | anchors.fill: parent
28 | source: !skin.imageSupport ? "" : skin.imageUrl
29 | fillMode: Image.PreserveAspectCrop
30 | }
31 |
32 | ColumnLayout {
33 | anchors.fill: parent
34 | spacing: 0
35 | Rectangle {
36 | color: skin.titleColor
37 | width: parent.width
38 | Layout.fillWidth: true
39 | Layout.preferredHeight: 33
40 | }
41 | Rectangle {
42 | color: skin.contentBackColor
43 | Layout.fillHeight: true
44 | Layout.fillWidth: true
45 | }
46 | }
47 |
48 |
49 | ImageButton {
50 | anchors.right: parent.right
51 | imageSrc: "qrc:/windowRes/close.png"
52 | // hoverimageSrc:"qrc:/res/close_hover.png"
53 | backHoverColor: "#FA5151"
54 | ToolTip.delay: 1000
55 | ToolTip.visible: hovered
56 | ToolTip.text: qsTr("关闭")
57 | onClicked: close();
58 | }
59 | Image {
60 | antialiasing: true
61 | source: "qrc:/windowRes/icon.png"
62 | width: 24
63 | height: 24
64 | x: 4
65 | y: 2
66 | fillMode: Image.PreserveAspectFit
67 | }
68 | YaheiText {
69 | text: "主题装扮"
70 | font.pixelSize: 15
71 | x: 32
72 | y: 4
73 | color: "#FFF"
74 | }
75 |
76 | Row {
77 | spacing: 12
78 | anchors.bottom: parent.bottom
79 | anchors.left: parent.left
80 | anchors.leftMargin: 23
81 | anchors.bottomMargin: 5
82 | visible: skin.gradSupport || skin.imageSupport
83 | YaheiText {
84 | text: "透明度"
85 | font.pixelSize: 13
86 | color: skin.accentColor
87 | anchors.verticalCenter: parent.verticalCenter
88 | }
89 | BaseSlider {
90 | id: _slider
91 | from: 0.5
92 | to: 1.0
93 | value: setting.skinOpacity
94 | onMoved: {
95 | setting.skinOpacity = value;
96 | }
97 | }
98 | }
99 |
100 | Row {
101 | anchors.bottom: parent.bottom
102 | anchors.right: parent.right
103 | anchors.rightMargin: 23
104 | anchors.bottomMargin: 8
105 | spacing: 6
106 |
107 | SkinBaseButton {
108 | text: "自定义"
109 | height: 21
110 | width: 75
111 | font.pixelSize: 12
112 | anchors.verticalCenter: parent.verticalCenter
113 | backRadius: 5
114 | onClicked: {
115 | message('info', "暂不支持!")
116 |
117 | }
118 | }
119 |
120 |
121 | SkinBaseButton {
122 | text: "恢复默认"
123 | height: 21
124 | width: 75
125 | font.pixelSize: 12
126 | anchors.verticalCenter: parent.verticalCenter
127 | backRadius: 5
128 | onClicked: {
129 | _content.currentIndex = 1;
130 | setting.skinOpacity = 0.9
131 | }
132 | }
133 | }
134 | }
135 |
136 |
137 | GridView {
138 | id: _content
139 | anchors.fill: parent
140 | anchors.topMargin: 30
141 | anchors.bottomMargin: 30
142 | model: SkinSingleton.skins
143 | cellWidth: parent.width/4
144 | cellHeight: cellWidth
145 | delegate: SkinSingleton.exteriorComponent
146 | clip: true
147 | currentIndex: setting.skinIndex
148 | highlight: Rectangle { border.width: 2; color: "transparent"; border.color: accentColor; radius: 5 }
149 | onCurrentIndexChanged: {
150 | setting.skinIndex = currentIndex
151 | }
152 |
153 | function requestSwitchSkin(idx) {
154 | _content.currentIndex = idx;
155 | }
156 | }
157 |
158 | modal: true
159 | dim: false
160 | focus: true
161 |
162 | parent: Overlay.overlay
163 | x: Math.round((parent.width - width) / 2)
164 | y: Math.round((parent.height - height) / 2)
165 |
166 | closePolicy: Popup.CloseOnEscape
167 |
168 | enter: Transition {
169 | id: _enterAnima
170 | NumberAnimation { property: "scale"; from: 0.0; to: 1.0; duration: 200; easing.type : Easing.OutBack }
171 | NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 300; }
172 | ScriptAction {
173 | script: _content.positionViewAtIndex( setting.skinIndex, GridView.Center);
174 | }
175 | }
176 | exit: Transition {
177 | id: _exitAnima
178 | NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 300; }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/common/YaheiText.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 |
3 | Text {
4 | id: _text
5 | font.pixelSize: 15
6 | font.family: "Microsoft Yahei"
7 | text: "text"
8 | color: accentColor
9 | }
10 |
--------------------------------------------------------------------------------
/common/qmlQianDialog/BlogDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Controls 2.14
3 | import QtQuick.Layouts 1.14
4 | import QtLocation 5.14
5 | import QtQuick.Controls.Material 2.12
6 | import Qt.labs.platform 1.0
7 | import "qrc:/common"
8 |
9 | DropPopup {
10 | id: skinDialog
11 |
12 |
13 | readonly property string typeQuestion : "question.png"
14 | readonly property string typeError : "error.png"
15 | readonly property string typeInformation : "info.png"
16 | readonly property string typeSuccess : "ok.png"
17 |
18 | enum DialogType {
19 | DialogQuestion,
20 | DialogError,
21 | DialogInformation,
22 | DialogSuccess
23 | }
24 |
25 | z: 100
26 |
27 | width: contentLayout.width+80 < 340 ? 340 : contentLayout.width + 80
28 | height: !title.length ? contentLayout.height + 60 : contentLayout.height + 80
29 |
30 |
31 | property alias title: _title.text
32 | property alias icon: _icon.source
33 |
34 | property string accentColorStr: accentColor
35 | function dialogOpen() {
36 |
37 | icon = typeInformation
38 | rejectVisible = false
39 | open()
40 | }
41 |
42 |
43 | Item {
44 | anchors.fill: parent
45 |
46 | ImageButton {
47 | anchors.right: parent.right
48 | imageSrc: "qrc:/windowRes/close2.png"
49 | hoverimageSrc:"qrc:/windowRes/close_hover.png"
50 | backHoverColor: "#FA5151"
51 | BaseToolTip {
52 | visible: parent.hovered
53 | text: "关闭"
54 | font.pixelSize: 12
55 | delay: 1000
56 | }
57 | onClicked: close();
58 | }
59 |
60 | ColumnLayout {
61 | id: dialogLayout
62 | width: skinDialog.width
63 | spacing: 0
64 | RowLayout {
65 | visible: title.length
66 | Layout.leftMargin: 6
67 | Layout.preferredHeight: 28
68 | YaheiText {
69 | id: _title
70 | font.pixelSize: 16
71 | color: tingeColor
72 | text: "关于QianWindow"
73 | }
74 | }
75 | Rectangle {
76 | visible: title.length
77 | height: 1
78 | color: tingeOpacityColor
79 | Layout.fillWidth: true
80 | }
81 | ColumnLayout {
82 | id: contentLayout
83 | Layout.margins: 20
84 | Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
85 | RowLayout {
86 | Layout.topMargin: title != "" ? 0 : 20
87 | Layout.bottomMargin: 20
88 | Image {
89 | id: _icon
90 | antialiasing: true
91 | source: "info.png"
92 | Layout.preferredWidth: 40
93 | Layout.preferredHeight: 40
94 | fillMode: Image.PreserveAspectFit
95 | }
96 |
97 | YaheiText {
98 | text: `最新版本视频地址: B站演示入口`
99 | font.pixelSize: 15
100 | color: tingeColor
101 | onLinkActivated: Qt.openUrlExternally(link);
102 | }
103 |
104 | }
105 |
106 | }
107 | }
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/common/qmlQianDialog/SkinQianDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Controls 2.14
3 | import QtQuick.Layouts 1.14
4 | import QtLocation 5.14
5 | import QtQuick.Controls.Material 2.12
6 | import Qt.labs.platform 1.0
7 | import "qrc:/common"
8 |
9 | DropPopup {
10 | id: skinDialog
11 |
12 |
13 | readonly property string typeQuestion : "question.png"
14 | readonly property string typeError : "error.png"
15 | readonly property string typeInformation : "info.png"
16 | readonly property string typeSuccess : "ok.png"
17 |
18 | enum DialogType {
19 | DialogQuestion,
20 | DialogError,
21 | DialogInformation,
22 | DialogSuccess
23 | }
24 |
25 | z: 100
26 |
27 | width: contentLayout.width+80 < 340 ? 340 : contentLayout.width + 80
28 | height: !title.length ? contentLayout.height + 60 : contentLayout.height + 80
29 |
30 | property alias title: _title.text
31 | property alias text: _content.text
32 | property alias icon: _icon.source
33 |
34 |
35 | function dialogOpen(type, _text, _title = "") {
36 |
37 | icon = type == SkinQianDialog.DialogQuestion ? typeQuestion :
38 | type == SkinQianDialog.DialogError ? typeError :
39 | type == SkinQianDialog.DialogInformation ? typeInformation : typeSuccess
40 |
41 | rejectVisible = type == SkinQianDialog.DialogQuestion ? true : false
42 |
43 | title = _title
44 | text = _text
45 | open()
46 | }
47 |
48 |
49 | Item {
50 | anchors.fill: parent
51 |
52 | ImageButton {
53 | anchors.right: parent.right
54 | imageSrc: "qrc:/windowRes/close2.png"
55 | hoverimageSrc:"qrc:/windowRes/close_hover.png"
56 | backHoverColor: "#FA5151"
57 | BaseToolTip {
58 | visible: parent.hovered
59 | text: "关闭"
60 | font.pixelSize: 12
61 | delay: 1000
62 | }
63 | onClicked: close();
64 | }
65 |
66 | ColumnLayout {
67 | id: dialogLayout
68 | width: skinDialog.width
69 | spacing: 0
70 | RowLayout {
71 | visible: title.length
72 | Layout.leftMargin: 6
73 | Layout.preferredHeight: 28
74 | YaheiText {
75 | id: _title
76 | font.pixelSize: 16
77 | color: tingeColor
78 | }
79 | }
80 | Rectangle {
81 | visible: title.length
82 | height: 1
83 | color: tingeOpacityColor
84 | Layout.fillWidth: true
85 | }
86 | ColumnLayout {
87 | id: contentLayout
88 | Layout.margins: 20
89 | Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
90 | RowLayout {
91 | Layout.topMargin: title != "" ? 0 : 20
92 | Layout.bottomMargin: 20
93 | Image {
94 | id: _icon
95 | antialiasing: true
96 | source: "info.png"
97 | Layout.preferredWidth: 40
98 | Layout.preferredHeight: 40
99 | fillMode: Image.PreserveAspectFit
100 | }
101 |
102 | YaheiText {
103 | id: _content
104 | text: ""
105 | font.pixelSize: 15
106 | color: tingeColor
107 | }
108 |
109 | }
110 |
111 | }
112 | }
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/common/qmlQianDialog/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianDialog/error.png
--------------------------------------------------------------------------------
/common/qmlQianDialog/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianDialog/info.png
--------------------------------------------------------------------------------
/common/qmlQianDialog/ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianDialog/ok.png
--------------------------------------------------------------------------------
/common/qmlQianDialog/question.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianDialog/question.png
--------------------------------------------------------------------------------
/common/qmlQianHints/Message.qml:
--------------------------------------------------------------------------------
1 |
2 | import QtQuick 2.10
3 |
4 | Rectangle {
5 | id: msgBox
6 | property alias text: msg.text
7 | property var type: "info"
8 |
9 | clip: true
10 | width: msg.contentWidth + 105
11 | height: 44
12 | color: type=== "info" ? "#fdf6ec" : type=== "success" ? "#f0f9eb" : "#fef0f0"
13 | border.color:type=== "info" ? "#faecd8" : type=== "success" ? "#e1f3d8" : "#fde2e2"
14 | radius: 5
15 | anchors.horizontalCenter: parent.horizontalCenter
16 | visible: false;
17 |
18 | function open(_type, _text) {
19 | type =_type
20 | text = _text
21 |
22 | animation.restart();
23 | }
24 |
25 | Image {
26 | id: img
27 | source: type
28 | === "info" ? "remind.png" : type
29 | === "success" ? "true.png" : "error.png"
30 | width: 24
31 | height: 24
32 | anchors {
33 | verticalCenter: parent.verticalCenter
34 | left: parent.left
35 | leftMargin: 30
36 | }
37 | }
38 | Text {
39 | id: msg
40 | color: type=== "info" ? "#e6a23c" : type=== "success" ? "#67c23a" : "#f56c6c"
41 | font.pixelSize: 17
42 | font.family: "Microsoft Yahei"
43 | anchors {
44 | verticalCenter: img.verticalCenter
45 | left: img.right
46 | leftMargin: 10
47 | }
48 | }
49 |
50 |
51 | SequentialAnimation{
52 | id: animation
53 | running: false
54 | ParallelAnimation {
55 | ScriptAction {
56 | script: msgBox.visible = true
57 | }
58 | NumberAnimation {
59 | target: msgBox
60 | property: "y"
61 | from: 0
62 | to: 40
63 | duration: 300
64 | easing.type : Easing.InOutQuad
65 | }
66 | NumberAnimation {
67 | target: msgBox
68 | property: "opacity"
69 | from: 0.3
70 | to: 1.0
71 | duration: 300
72 | easing.type : Easing.InOutQuad
73 | }
74 | }
75 |
76 |
77 | PauseAnimation {
78 | duration: 2000
79 | }
80 |
81 | ParallelAnimation {
82 | NumberAnimation {
83 | target: msgBox
84 | property: "y"
85 | from: 40
86 | to: 0
87 | duration: 300
88 | easing.type : Easing.InOutQuad
89 | }
90 | NumberAnimation {
91 | target: msgBox
92 | property: "opacity"
93 | from: 1.0
94 | to: 0.3
95 | duration: 300
96 | easing.type : Easing.InOutQuad
97 | }
98 | }
99 |
100 | ScriptAction {
101 | script: msgBox.visible = false
102 | }
103 |
104 | }
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/common/qmlQianHints/QianQuestionMark.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.5
3 | import "qrc:/common"
4 |
5 | Item {
6 | property string hint: "hint "
7 | implicitWidth: 22
8 | implicitHeight: 22
9 |
10 | Image {
11 | anchors.fill: parent
12 | anchors.margins: 1
13 | source: skin.light ? "questionMarkDarker.png" : "questionMark.png"
14 | mipmap: true
15 | }
16 | MouseArea {
17 | id: mouse
18 | anchors.fill: parent
19 | hoverEnabled: true
20 |
21 | }
22 |
23 | BaseToolTip {
24 | visible: mouse.containsMouse
25 | text: hint
26 | font.pixelSize: 13
27 | delay: 1
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/common/qmlQianHints/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianHints/error.png
--------------------------------------------------------------------------------
/common/qmlQianHints/questionMark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianHints/questionMark.png
--------------------------------------------------------------------------------
/common/qmlQianHints/questionMarkDarker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianHints/questionMarkDarker.png
--------------------------------------------------------------------------------
/common/qmlQianHints/remind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianHints/remind.png
--------------------------------------------------------------------------------
/common/qmlQianHints/true.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianHints/true.png
--------------------------------------------------------------------------------
/common/qmlQianStretchList/QianStretchDalegate.qml:
--------------------------------------------------------------------------------
1 | import QtQuick.Controls 2.14
2 | import QtQuick.Layouts 1.14
3 | import QtQuick 2.14
4 | import QtGraphicalEffects 1.14
5 | import Qt.Singleton 1.0
6 | Item {
7 | id: container
8 | width: skin.gradSupport ? ListView.view.width : ListView.view.width-10
9 | height: columnlayout.height
10 |
11 |
12 | property int itemLeftMargin: 10 + tier*10
13 |
14 | property int itemIndex: index
15 | property int crtIndex: container.ListView.view.currentIndex
16 |
17 |
18 |
19 | function checkCurrentIndexIsChild(subitem) {
20 |
21 | if(subitem.count <= 0) return false;
22 |
23 | for(let i = 0; i < subitem.count; i++) {
24 | let model = subitem.get(i);
25 |
26 | if(model.subItem.count > 0) {
27 | let ret = checkCurrentIndexIsChild(model.subItem);
28 | if(ret != null) {
29 | return ret;
30 | }
31 | } else {
32 | if(model.toIndex == strechCurrentIndex)
33 | return true;
34 | }
35 |
36 | }
37 | return false;
38 |
39 | }
40 |
41 | property int dataState: strechCurrentIndex == toIndex ? 0 : mouse.containsMouse ? 1
42 | : checkCurrentIndexIsChild(subItem) ? 2 : -1
43 |
44 | ColumnLayout {
45 | id: columnlayout
46 | anchors.centerIn: parent
47 |
48 | width: parent.width
49 | spacing: 0
50 |
51 | Item {
52 | id: content
53 | Layout.fillWidth: true
54 | Layout.preferredHeight: itemHeight
55 |
56 |
57 | Rectangle {
58 | id: frontRect
59 | anchors.fill: parent
60 | anchors.leftMargin: skin.gradSupport ? 28 : 18
61 | anchors.rightMargin: skin.gradSupport ? -frontRect.height/2 : 18
62 | anchors.topMargin: 9
63 | anchors.bottomMargin: 9
64 |
65 | color: !skin.light && dataState == 2 ? skin.stretchFoldBackSelectColor : subItem.count? skin.stretchFoldBackColor :
66 | toIndex == strechCurrentIndex ? skin.stretchSelectBackColor :
67 | mouse.containsMouse ? skin.stretchBackHoverColor : skin.stretchBackColor
68 |
69 |
70 | Behavior on color {
71 | ColorAnimation { duration: 200 }
72 | }
73 |
74 | radius: skin.gradSupport ? frontRect.height/2 : 6
75 | RowLayout {
76 | anchors.fill: parent
77 | anchors.margins: 10
78 | anchors.leftMargin: subItem.count > 0 && (skin.gradSupport) ? itemLeftMargin-20 : itemLeftMargin
79 | anchors.rightMargin: 20
80 |
81 | Image {
82 | visible: subItem.count > 0 ? true : false
83 | Layout.alignment : Qt.AlignVCenter | Qt.AlignLeft
84 | Layout.preferredWidth: 20
85 | Layout.preferredHeight: 20
86 | mipmap: true
87 | source: "./icons/indicator_right.png"
88 | rotation: !stretch ? 0 : 90
89 |
90 | Behavior on rotation {
91 | NumberAnimation { duration: 200 }
92 | }
93 | ColorOverlay{
94 | anchors.fill: parent
95 | source: parent
96 | color: stretch ? skin.stretchFoldSelectColor : skin.stretchColor
97 | }
98 |
99 | }
100 |
101 | Text {
102 | Layout.leftMargin: 4
103 | font.family: "Microsoft Yahei"
104 | text: name
105 | font.pixelSize: 16
106 | color: stretch ? skin.stretchFoldSelectColor :
107 | toIndex == strechCurrentIndex ? skin.stretchSelectColor : skin.stretchColor
108 |
109 |
110 | elide: Text.ElideRight
111 | clip: true
112 | scale: tier < 4 ? 1.0 - tier*0.04 : 0.84
113 |
114 | }
115 |
116 |
117 | Rectangle {
118 | visible: hintNumber < 0 ? false : true
119 | Layout.preferredWidth: hintNum.contentWidth < 22 ? 22 : hintNum.contentWidth+6
120 | Layout.preferredHeight: 22
121 |
122 |
123 | color: "#FF5E54"
124 | radius: Layout.preferredHeight / 2
125 | Text {
126 | id: hintNum
127 | anchors.centerIn: parent
128 | font.family: "Microsoft Yahei"
129 | text: hintNumber > 999 ? "999+" : hintNumber
130 | font.pixelSize: 12
131 | color: "#FFF"
132 | }
133 | scale: tier < 4 ? 1.0 - tier*0.08 : 0.76
134 | }
135 |
136 | Item {
137 | Layout.fillWidth: true
138 | }
139 |
140 |
141 | }
142 |
143 | }
144 |
145 |
146 |
147 |
148 | MouseArea {
149 | id: mouse
150 | anchors.fill: parent
151 | hoverEnabled: true
152 | onClicked: {
153 | if(subItem.count > 0) {
154 | stretch = !stretch
155 | } else if(strechCurrentIndex != toIndex) {
156 | strechCurrentName = name
157 | strechCurrentIndex = toIndex
158 | switchPage(strechCurrentName)
159 | }
160 | }
161 | }
162 | }
163 |
164 | ListView {
165 | id: subView
166 | model: subItem
167 | Layout.fillWidth: true
168 | Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
169 |
170 | Layout.preferredHeight: stretch ?subView.contentHeight : 0
171 | visible: true
172 | clip: true
173 | currentIndex: -1
174 | delegate: stretchList.delegate
175 |
176 | Behavior on Layout.preferredHeight {
177 | NumberAnimation { duration: 200 }
178 | }
179 |
180 | displaced: Transition {
181 | NumberAnimation { properties: "x,y"; duration: 90 }
182 | }
183 | }
184 |
185 | }
186 |
187 |
188 | }
189 |
--------------------------------------------------------------------------------
/common/qmlQianStretchList/QianStretchEntry.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.12
2 | import QtQuick.Controls 2.14
3 | import QtQuick.Layouts 1.14
4 | import QtQml.Models 2.12
5 | import Qt.Singleton 1.0
6 | import "qrc:/common"
7 |
8 | Item {
9 | signal switchPage(string name)
10 | property int strechCurrentIndex: 0
11 | property int strechLength: 0
12 |
13 | property var itemsArrays: [
14 | {
15 | name: "基础组件",
16 | stretch: true,
17 | subItem: [
18 | {
19 | name: "Buttons",
20 | },
21 | {
22 | name: "Other",
23 | },
24 | {
25 | name: "提示",
26 | }
27 | ]
28 | },
29 |
30 | {
31 | name: "个人开源",
32 | icon: "",
33 | stretch: false,
34 | subItem: [
35 | {
36 | name: "合成大西瓜",
37 | },
38 | {
39 | name: "图片预览器",
40 | },
41 | {
42 | name: "DragView",
43 | }
44 | ]
45 | }
46 | ]
47 |
48 |
49 | ListModel {
50 | id: stretchModel
51 | dynamicRoles : true
52 | }
53 |
54 |
55 | property int itemHeight: 60 // 184 * 60
56 | property string strechCurrentName: ""
57 | property var alarmObjItem: null
58 |
59 |
60 |
61 | // 校验未知
62 | function checkUnknown(field, defaultData) {
63 | return field == undefined ? defaultData : field
64 | }
65 |
66 | function createModel(target, tier) {
67 |
68 |
69 | let idx = -999
70 | if( target.subItem == undefined || !target.subItem.length) {
71 | idx = strechLength
72 | strechLength += 1
73 | }
74 |
75 |
76 | return {
77 | 'name': target.name,
78 | 'icon': checkUnknown(target.icon, ""),
79 | 'hintNumber': checkUnknown(target.hintNumber, -1),
80 | 'stretch': checkUnknown(target.stretch, false),
81 | 'tier': tier,
82 | 'subItem' : [],
83 | 'toIndex' : idx,
84 | };
85 | }
86 |
87 | function createModel2(name, icon, tier, toIndex, hintNumber) {
88 |
89 | return {
90 | 'name': name,
91 | 'icon': icon,
92 | 'hintNumber': hintNumber,
93 | 'stretch': false,
94 | 'tier': tier,
95 | 'subItem' : [],
96 | 'toIndex' : toIndex,
97 | };
98 | }
99 |
100 | function appendSubItem(parent, subItem, tier) {
101 | if (subItem == undefined || subItem.length == 0) return;
102 |
103 |
104 |
105 | for(let i = 0; i < subItem.length; i++) {
106 |
107 | let model = createModel(subItem[i], tier);
108 |
109 | parent.subItem.append(model);
110 |
111 | let count = appendSubItem(parent.subItem.get(parent.subItem.count-1), subItem[i].subItem, tier+1);
112 | }
113 | }
114 |
115 |
116 | function searchItemByToIndex(parent, toIndex) {
117 |
118 | for(let i = 0; i < parent.count; i++) {
119 |
120 | let model = parent.get(i);
121 |
122 | if(model.toIndex == toIndex)
123 | return model;
124 |
125 | if(model.subItem.count > 0) {
126 | let ret = searchItemByToIndex(model.subItem, toIndex);
127 | if(ret != null) {
128 | return ret;
129 | }
130 | }
131 | }
132 | return null;
133 | }
134 |
135 |
136 | Component.onCompleted: {
137 | for(let i = 0; i < itemsArrays.length; i++) {
138 |
139 | let tier = 0;
140 | let model = createModel(itemsArrays[i], tier);
141 | stretchModel.append(model);
142 | appendSubItem(stretchModel.get(stretchModel.count-1), itemsArrays[i].subItem, tier+1);
143 |
144 | }
145 |
146 | }
147 |
148 |
149 | ColumnLayout {
150 | anchors.fill: parent
151 | ListView {
152 | id: stretchList
153 | Layout.fillHeight: true
154 | Layout.topMargin: 8
155 | Layout.bottomMargin: 8
156 | Layout.rightMargin: skin.gradSupport ? 0 :6
157 | Layout.fillWidth: true
158 | clip: true
159 | currentIndex: -1
160 | model: stretchModel
161 |
162 |
163 |
164 | delegate: QianStretchDalegate {
165 | }
166 |
167 | displaced: Transition {
168 | NumberAnimation { properties: "x,y"; duration: 90 }
169 | }
170 |
171 | ScrollBar.vertical: ScrollBar {
172 | id: scroll1
173 | policy: size<1.0? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
174 | x: skin.gradSupport ? 8 : stretchList.width-8
175 |
176 | contentItem: Rectangle {
177 | implicitWidth: 8
178 | implicitHeight: 100
179 | radius: width / 2
180 | color: skin.light ? skin.stretchSelectBackColor : accentOpacityHoverColor
181 | }
182 | width: 8
183 | background: Item {
184 |
185 | }
186 | }
187 | }
188 |
189 |
190 |
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/common/qmlQianStretchList/icons/indicator_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/common/qmlQianStretchList/icons/indicator_right.png
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "frameless.h"
5 | #include
6 | #include
7 | #include
8 | #include "Backed.h"
9 | #include "./pages/QianProjectPages/QianDragViewPage/qiandrageventcatch.h"
10 |
11 |
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
16 | QCoreApplication::setOrganizationName("Some organization");
17 | QApplication app(argc, argv);
18 | QQuickStyle::setStyle("Material");
19 |
20 |
21 | QQmlApplicationEngine engine;
22 |
23 | qmlRegisterType("Qt.QianDragEventCatch", 1, 0, "QianDragEventCatch");
24 | qmlRegisterType("Qt.Window", 1, 0, "Frameless");
25 | qmlRegisterSingletonType(QUrl("qrc:/common/SkinModel.qml"), "Qt.Singleton", 1, 0, "SkinSingleton");
26 | qmlRegisterSingletonType("Qt.Backed", 1, 0, "Backed", Backed_qobject_provider);
27 |
28 |
29 | const QUrl url(QStringLiteral("qrc:/main.qml"));
30 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
31 | &app, [url](QObject *obj, const QUrl &objUrl) {
32 | if (!obj && url == objUrl)
33 | QCoreApplication::exit(-1);
34 | }, Qt::QueuedConnection);
35 | engine.load(url);
36 |
37 | return app.exec();
38 | }
39 |
--------------------------------------------------------------------------------
/main.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtGraphicalEffects 1.12
3 | import Qt.Window 1.0
4 | import QtQuick.Window 2.14
5 | import Qt.Singleton 1.0
6 | import QtQuick.Controls.Material 2.12
7 | import Qt.labs.platform 1.1
8 | import Qt.labs.settings 1.0
9 |
10 | Frameless {
11 | id: rootWindow
12 |
13 | property string titleStr: "QianWindow"
14 | property var areas: [
15 | Qt.rect(0, 0, 99999, 42)
16 | ]
17 |
18 | property color accentColor: SkinSingleton.skins[setting.skinIndex].accentColor // 皮肤深色
19 | property color accentContrlColor: SkinSingleton.skins[setting.skinIndex].accentContrlColor // 皮肤控件深色
20 | property color accentOpacityColor: Qt.rgba(accentColor.r, accentColor.g, accentColor.b, 0.5) // 皮肤控件深色透明 (一般用在滚动条)
21 | property color accentOpacityHoverColor: Qt.rgba(accentColor.r, accentColor.g, accentColor.b, 0.45) // 皮肤控件深色透明 淡色 (一般用在滚动条鼠标徘徊)
22 |
23 | property color tingeColor: skin.light ? "#555" : "#b1b1b1" // 皮肤淡色(白色皮肤为浅黑 黑色皮肤为灰色)
24 | property color tingeDrakerColor: Qt.darker(tingeColor, 1.2) // 皮肤谈深色
25 |
26 |
27 |
28 | property color tingeOpacityColor: skin.light ? "#11000000" : "#11FFFFFF" // 皮肤谈透明色
29 | property color tingeOpacityLightColor: skin.light ? "#06000000" : "#06FFFFFF" // 皮肤谈透明色(亮)
30 |
31 |
32 | property color mainColor: !skin.gradSupport && !skin.imageSupport ? skin.mainColor :
33 | !skin.light ? Qt.rgba(0,0,0, skin.gradMainOpacity - setting.skinOpacity * 0.48) : Qt.rgba(1,1,1, skin.gradMainOpacity + setting.skinOpacity * 0.28)
34 |
35 | property var skin: SkinSingleton.skins[setting.skinIndex]
36 |
37 |
38 | Material.accent: accentColor
39 | Material.theme: skin.light ? Material.Light : Material.Dark
40 | Material.foreground: tingeColor
41 | width: 1150
42 | height: 750
43 | visible: true
44 | title: titleStr
45 | color: "transparent"
46 | resizable: true
47 | moveArea: areas
48 | minimumWidth: 1130
49 | minimumHeight: 730
50 |
51 | function closeFunc() {
52 | close();
53 | }
54 |
55 | WindowEntry {
56 | anchors.fill: parent
57 | anchors.margins: rootWindow.maximized ? 0 : 8
58 | radius: rootWindow.maximized ? 0 : 4
59 | }
60 |
61 |
62 |
63 | Settings {
64 | id: setting
65 | property int skinIndex: 1
66 | property real skinOpacity: 1
67 | property string skinCustomFile: ""
68 | fileName: "app.ini"
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/pages/BaseControlPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Window 2.14
3 | import QtQuick.Layouts 1.12
4 | import QtQuick.Controls 2.14
5 | import QtQuick.Controls.Material 2.12
6 | import "qrc:/common"
7 | Item {
8 | property int leftWidth: 182
9 | property int fontsize: 19
10 | ColumnLayout {
11 | anchors.fill: parent
12 | anchors.rightMargin: 60
13 | anchors.topMargin: 30
14 | anchors.bottomMargin: 30
15 | anchors.leftMargin: 60
16 | spacing: 10
17 |
18 | RowLayout {
19 | YaheiText {
20 | text: "Buttons"
21 | font.pixelSize: fontsize
22 | Layout.preferredWidth: leftWidth
23 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
24 | }
25 | ColumnLayout {
26 | spacing: 20
27 | RowLayout {
28 | spacing: 20
29 | SkinBaseButton {
30 | font.pixelSize: 14
31 | backRadius: 4
32 | text: "SkinBtn1"
33 |
34 | }
35 | SkinBaseButton2 {
36 | font.pixelSize: 14
37 | backRadius: 4
38 | text: "SkinBtn2"
39 | }
40 | }
41 |
42 | RowLayout {
43 | spacing: 20
44 | BaseButton {
45 | text: "Blue"
46 | Layout.preferredHeight: 28
47 | Layout.preferredWidth: 78
48 | font.pixelSize: 14
49 | backRadius: 4
50 | bckcolor: "#4785FF"
51 | }
52 |
53 | BaseButton {
54 | bckcolor: "#EC3315"
55 | Layout.preferredHeight: 28
56 | Layout.preferredWidth: 78
57 | font.pixelSize: 14
58 | backRadius: 4
59 | text: "Red"
60 |
61 | }
62 |
63 | BaseButton {
64 | text: "Yellow"
65 | Layout.preferredHeight: 28
66 | Layout.preferredWidth: 78
67 | font.pixelSize: 14
68 | backRadius: 4
69 | bckcolor: "#ED9709"
70 | }
71 | }
72 |
73 | }
74 | }
75 |
76 | Rectangle {
77 | height: 1
78 | color: tingeOpacityColor
79 | Layout.fillWidth: true
80 | Layout.topMargin: 12
81 | }
82 |
83 | RowLayout {
84 | YaheiText {
85 | text: "RadioButton"
86 | font.pixelSize: fontsize
87 | Layout.preferredWidth: leftWidth
88 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
89 | Layout.topMargin: 12
90 | }
91 | ColumnLayout {
92 | RadioButton {
93 | font.pixelSize: fontsize - 2
94 | indicator.width: 18
95 | indicator.height: 18
96 |
97 | font.family: "Microsoft Yahei"
98 | text: "Option 1"
99 |
100 | }
101 | RadioButton {
102 | font.pixelSize: fontsize - 2
103 | indicator.width: 18
104 | indicator.height: 18
105 | font.family: "Microsoft Yahei"
106 | text: "Option 2"
107 | }
108 | RadioButton {
109 | enabled: false
110 | font.pixelSize: fontsize - 2
111 | indicator.width: 18
112 | indicator.height: 18
113 | font.family: "Microsoft Yahei"
114 | text: "Option 3"
115 | }
116 |
117 | }
118 | }
119 |
120 | Rectangle {
121 | height: 1
122 | color: tingeOpacityColor
123 | Layout.fillWidth: true
124 | }
125 |
126 | RowLayout {
127 | YaheiText {
128 | text: "CheckBox"
129 | font.pixelSize: fontsize
130 | Layout.preferredWidth: leftWidth
131 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
132 | Layout.topMargin: 12
133 |
134 | }
135 | ColumnLayout {
136 | BaseCheckBox {
137 | font.pixelSize: fontsize - 2
138 | text: "Option 1"
139 |
140 | }
141 | BaseCheckBox {
142 | font.pixelSize: fontsize - 2
143 | text: "Option 2"
144 | }
145 | BaseCheckBox {
146 | enabled: false
147 | font.pixelSize: fontsize - 2
148 | text: "Option 3"
149 | }
150 |
151 | }
152 | }
153 |
154 | Rectangle {
155 | height: 1
156 | color: tingeOpacityColor
157 | Layout.fillWidth: true
158 | }
159 |
160 | RowLayout {
161 | YaheiText {
162 | text: "Switch"
163 | font.pixelSize: fontsize
164 | Layout.preferredWidth: leftWidth
165 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
166 | Layout.topMargin: 12
167 |
168 | }
169 |
170 | RowLayout {
171 | spacing: 20
172 | Switch {
173 | font.pixelSize: fontsize - 2
174 | indicator.height: 18
175 | font.family: "Microsoft Yahei"
176 | text: "Blue"
177 | Material.accent: "#4785FF"
178 | }
179 | Switch {
180 | font.pixelSize: fontsize - 2
181 | indicator.height: 18
182 | font.family: "Microsoft Yahei"
183 | text: "Red"
184 | Material.accent: "#EC3315"
185 | }
186 | Switch {
187 | enabled: false
188 | font.pixelSize: fontsize - 2
189 | indicator.height: 18
190 | font.family: "Microsoft Yahei"
191 | text: "Disable"
192 |
193 | }
194 |
195 | }
196 |
197 | }
198 |
199 |
200 | Item {
201 | Layout.fillHeight: true
202 | Layout.fillWidth: true
203 | }
204 |
205 | }
206 |
207 | }
208 |
--------------------------------------------------------------------------------
/pages/BaseOtherControlPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Window 2.14
3 | import QtQuick.Layouts 1.12
4 | import QtQuick.Controls 2.14
5 | import QtQuick.Controls.Material 2.12
6 | import "qrc:/common"
7 | Item {
8 |
9 | property int leftWidth: 182
10 | property int fontsize: 19
11 | ColumnLayout {
12 | anchors.fill: parent
13 | anchors.rightMargin: 60
14 | anchors.topMargin: 30
15 | anchors.bottomMargin: 30
16 | anchors.leftMargin: 60
17 | spacing: 22
18 |
19 | RowLayout {
20 | YaheiText {
21 | text: "Progress Bar"
22 | font.pixelSize: fontsize
23 | Layout.preferredWidth: leftWidth
24 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
25 | }
26 | ColumnLayout {
27 | spacing: 20
28 | ProgressBar {
29 | id: progress
30 | indeterminate: false
31 | implicitWidth: 220
32 | value: 0
33 |
34 | NumberAnimation on value {
35 | id: progressAnimation
36 | from: 0
37 | to: 1
38 | duration: 2000
39 | running: true
40 | loops: Animation.Infinite
41 | }
42 | }
43 |
44 | ProgressBar {
45 | indeterminate: true
46 | implicitWidth: 220
47 | }
48 |
49 | }
50 | }
51 |
52 | Rectangle {
53 | height: 1
54 | color: tingeOpacityColor
55 | Layout.fillWidth: true
56 | }
57 |
58 | RowLayout {
59 | YaheiText {
60 | text: "BusyIndicator"
61 | font.pixelSize: fontsize
62 | Layout.preferredWidth: leftWidth
63 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
64 | }
65 | ColumnLayout {
66 | spacing: 20
67 | RowLayout {
68 | spacing: 20
69 | BusyIndicator {
70 | running: true
71 |
72 | }
73 |
74 | BusyIndicator {
75 | running: true
76 | Material.accent: "#4785FF"
77 |
78 | }
79 | BusyIndicator {
80 | running: true
81 | Material.accent: "#EC3315"
82 |
83 | }
84 | BusyIndicator {
85 | running: true
86 | Material.accent: "#ED9709"
87 |
88 | }
89 |
90 | }
91 |
92 | }
93 | }
94 | Rectangle {
95 | height: 1
96 | color: tingeOpacityColor
97 | Layout.fillWidth: true
98 | }
99 |
100 | RowLayout {
101 | YaheiText {
102 | text: "Dial"
103 | font.pixelSize: fontsize
104 | Layout.preferredWidth: leftWidth
105 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
106 | }
107 | ColumnLayout {
108 | spacing: 20
109 | RowLayout {
110 | spacing: 20
111 | Dial {
112 | }
113 |
114 | Dial {
115 | Material.accent: "#4785FF"
116 |
117 | }
118 | Dial {
119 | Material.accent: "#EC3315"
120 |
121 | }
122 | Dial {
123 | Material.accent: "#ED9709"
124 |
125 | }
126 |
127 | }
128 | }
129 | }
130 | Rectangle {
131 | height: 1
132 | color: tingeOpacityColor
133 | Layout.fillWidth: true
134 | }
135 |
136 |
137 | RowLayout {
138 | YaheiText {
139 | text: "Slider"
140 | font.pixelSize: fontsize
141 | Layout.preferredWidth: leftWidth
142 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
143 | }
144 | ColumnLayout {
145 | spacing: 10
146 | RowLayout {
147 | spacing: 20
148 | YaheiText {
149 | text: "Skin Slider"
150 | font.pixelSize: fontsize
151 | Layout.preferredWidth: 134
152 | }
153 | Slider {
154 | from: 1
155 | value: 25
156 | to: 100
157 | }
158 | }
159 |
160 | RowLayout {
161 | spacing: 20
162 | YaheiText {
163 | text: "Blue Slider"
164 | font.pixelSize: fontsize
165 | Layout.preferredWidth: 134
166 | }
167 | Slider {
168 | from: 1
169 | value: 25
170 | to: 100
171 | Material.accent: "#4785FF"
172 | }
173 | }
174 |
175 | RowLayout {
176 | spacing: 20
177 | YaheiText {
178 | text: "Red Slider"
179 | font.pixelSize: fontsize
180 | Layout.preferredWidth: 134
181 | }
182 | Slider {
183 | from: 1
184 | value: 25
185 | to: 100
186 | Material.accent: "#EC3315"
187 | }
188 | }
189 |
190 | RowLayout {
191 | spacing: 20
192 |
193 | YaheiText {
194 | text: "Yellow Slider"
195 | font.pixelSize: fontsize
196 | Layout.preferredWidth: 134
197 | }
198 | Slider {
199 | from: 1
200 | value: 25
201 | to: 100
202 | Material.accent: "#ED9709"
203 | }
204 | }
205 |
206 |
207 | }
208 | }
209 |
210 |
211 |
212 | Item {
213 | Layout.fillHeight: true
214 | Layout.fillWidth: true
215 | }
216 |
217 |
218 |
219 |
220 |
221 | }
222 |
223 | }
224 |
--------------------------------------------------------------------------------
/pages/HintPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Window 2.14
3 | import QtQuick.Layouts 1.12
4 | import QtQuick.Controls 2.14
5 | import QtQuick.Controls.Material 2.12
6 | import "qrc:/common"
7 | import "qrc:/common/qmlQianHints"
8 | import "qrc:/common/qmlQianDialog"
9 | Item {
10 | property int leftWidth: 182
11 | property int fontsize: 19
12 |
13 | Message{
14 | id:messageTip
15 | z: 1
16 | parent: Overlay.overlay
17 | }
18 |
19 | function message(type, message) {
20 | if(type!=='success'&&type!=='error'&&type!=='info'){
21 | return false
22 | }
23 | messageTip.open(type, message)
24 | }
25 |
26 | SkinQianDialog {
27 | id: skinQianDialog
28 | backParent: windowEntry
29 | parent: Overlay.overlay
30 | onAccept: {
31 | message('success', "You clicked the accept button!")
32 | skinQianDialog.close();
33 | }
34 | }
35 |
36 |
37 |
38 | ColumnLayout {
39 | anchors.fill: parent
40 | anchors.rightMargin: 60
41 | anchors.topMargin: 30
42 | anchors.bottomMargin: 30
43 | anchors.leftMargin: 60
44 | spacing: 22
45 |
46 | RowLayout {
47 | YaheiText {
48 | text: "Top Hint"
49 | font.pixelSize: fontsize
50 | Layout.preferredWidth: leftWidth
51 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
52 | }
53 | ColumnLayout {
54 | spacing: 20
55 |
56 | SkinBaseButton {
57 | font.pixelSize: 14
58 | backRadius: 4
59 | text: "Info"
60 | onClicked: message('info', "You clicked the info button!")
61 | }
62 | SkinBaseButton {
63 | font.pixelSize: 14
64 | backRadius: 4
65 | text: "Error"
66 | onClicked: message('error', "You clicked the error button!")
67 | }
68 | SkinBaseButton {
69 | font.pixelSize: 14
70 | backRadius: 4
71 | text: "Success"
72 | onClicked: message('success', "You clicked the success button!")
73 | }
74 |
75 | }
76 | }
77 |
78 | Rectangle {
79 | height: 1
80 | color: tingeOpacityColor
81 | Layout.fillWidth: true
82 | }
83 |
84 | RowLayout {
85 | YaheiText {
86 | text: "对话框"
87 | font.pixelSize: fontsize
88 | Layout.preferredWidth: leftWidth
89 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
90 | }
91 | ColumnLayout {
92 | spacing: 20
93 | RowLayout {
94 | spacing: 40
95 | SkinBaseButton {
96 | font.pixelSize: 14
97 | backRadius: 4
98 | text: "无标题询问"
99 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogQuestion, "是否需要清理任务?")
100 | }
101 | SkinBaseButton {
102 | font.pixelSize: 14
103 | backRadius: 4
104 | text: "带标题询问"
105 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogQuestion, "是否需要清理任务?", "任务清理")
106 | }
107 | }
108 |
109 | RowLayout {
110 | spacing: 40
111 | BaseButton {
112 | font.pixelSize: 14
113 | backRadius: 4
114 | text: "无标题成功"
115 | bckcolor: "#4785FF"
116 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogSuccess, "任务清理完成! 请重启软件生效!")
117 | }
118 | BaseButton {
119 | font.pixelSize: 14
120 | backRadius: 4
121 | text: "带标题成功"
122 | bckcolor: "#4785FF"
123 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogSuccess, "任务清理完成! 请重启软件生效!", "任务清理")
124 | }
125 | }
126 | RowLayout {
127 | spacing: 40
128 | BaseButton {
129 | font.pixelSize: 14
130 | backRadius: 4
131 | text: "无标题提示"
132 | bckcolor: "#16B7BF"
133 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogInformation, "当前没有任务可以清理!")
134 | }
135 | BaseButton {
136 | font.pixelSize: 14
137 | backRadius: 4
138 | text: "带标题提示"
139 | bckcolor: "#16B7BF"
140 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogInformation, "当前没有任务可以清理!", "任务清理")
141 | }
142 | }
143 |
144 | RowLayout {
145 | spacing: 40
146 | BaseButton {
147 | font.pixelSize: 14
148 | backRadius: 4
149 | text: "无标题错误"
150 | bckcolor: "#EC3315"
151 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogError, "清理任务失败,请检查用户权限!")
152 | }
153 | BaseButton {
154 | font.pixelSize: 14
155 | backRadius: 4
156 | text: "带标题错误"
157 | bckcolor: "#EC3315"
158 | onClicked: skinQianDialog.dialogOpen(SkinQianDialog.DialogError, "清理任务失败,请检查用户权限!", "任务清理")
159 | }
160 | }
161 |
162 |
163 | }
164 | }
165 |
166 | Rectangle {
167 | height: 1
168 | color: tingeOpacityColor
169 | Layout.fillWidth: true
170 | }
171 |
172 | RowLayout {
173 | YaheiText {
174 | text: "提示标记"
175 | font.pixelSize: fontsize
176 | Layout.preferredWidth: leftWidth
177 | Layout.alignment: Qt.AlignTop | Qt.AlignLeft
178 | }
179 | ColumnLayout {
180 | spacing: 20
181 |
182 | RowLayout {
183 | BaseCheckBox {
184 | font.pixelSize: fontsize - 2
185 | text: "开启GPU渲染"
186 |
187 | }
188 | QianQuestionMark {
189 | hint: "如果支持GPU,开启GPU渲染更加流畅"
190 | }
191 |
192 | }
193 |
194 | RowLayout {
195 | BaseCheckBox {
196 | font.pixelSize: fontsize - 2
197 | text: "开启安全防护"
198 | }
199 | QianQuestionMark {
200 | hint: "开启后不被其他恶意软件篡改"
201 | }
202 |
203 | }
204 |
205 |
206 |
207 |
208 | }
209 | }
210 |
211 |
212 |
213 |
214 |
215 |
216 | Item {
217 | Layout.fillHeight: true
218 | Layout.fillWidth: true
219 | }
220 |
221 | }
222 |
223 | }
224 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/QianDragDelegate.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Layouts 1.14
3 | import QtQuick.Controls 2.14
4 | Item {
5 | id: container
6 | signal closeRequest()
7 | height: ListView.view.height
8 | width: contentLayout.width
9 | states: State {
10 | name: "remove";
11 | PropertyChanges { target: container; y: ListView.view.height }
12 | }
13 |
14 | transitions: Transition {
15 | SequentialAnimation {
16 | NumberAnimation { properties: "y"; duration: 200 }
17 | ScriptAction { script: closeRequest() }
18 | }
19 | }
20 |
21 | function informationContains(x, y) {
22 | if(x >= information.x && (x) <= information.x + information.width
23 | && y >= information.y && (y) <= information.y + information.height)
24 | return true
25 |
26 | return false
27 | }
28 |
29 | RowLayout {
30 | id: contentLayout
31 | Layout.margins: 4
32 | y: (container.height - itemHeight)/2
33 | spacing: 0
34 | Rectangle {
35 | radius: 2
36 | Layout.preferredHeight: itemHeight
37 | Layout.preferredWidth: interval
38 | visible: (index == dragDelegate.dragIndex) && (index != dragDelegate.pressIndex)
39 | && (index-1 != dragDelegate.pressIndex)
40 | color: "#FED963"
41 | }
42 |
43 | QianDragDelegateInformation {
44 | id: information
45 | isSelect: container.ListView.view.currentIndex == index
46 | opacity: dragDelegate.pressIndex == index ? 0.6 : 1.0
47 | onRequestRemove: {
48 | container.state = "remove";
49 | }
50 | modelData: model
51 | Behavior on color {
52 | ColorAnimation { duration: 200 }
53 | }
54 | }
55 | Rectangle {
56 | radius: 1
57 | Layout.preferredHeight: itemHeight
58 | Layout.preferredWidth: interval
59 |
60 | visible: index+1 == container.ListView.view.count && (index+1 == dragDelegate.dragIndex) && (index != dragDelegate.pressIndex)
61 | color: "#FED963"
62 |
63 | }
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/QianDragDelegateInformation.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Layouts 1.14
3 | import QtQuick.Controls 2.14
4 | import QtGraphicalEffects 1.14
5 | import ".."
6 | import "qrc:/common"
7 | Rectangle {
8 | id: container
9 | property var modelData: null
10 | property bool isSelect: false
11 | signal requestRemove()
12 |
13 | radius: itemRadius
14 | Layout.margins: 4
15 | implicitHeight: itemHeight
16 | implicitWidth: itemWidth
17 | color: isSelect ? "#FED963" : skin.light ? "#F1F1F1" : "#222"
18 | clip: true
19 |
20 | layer.enabled: true
21 | layer.effect: DropShadow {
22 | horizontalOffset: 1
23 | verticalOffset: 1
24 | color: "#000"
25 | }
26 |
27 | ImageButton {
28 | anchors.top: parent.top
29 | anchors.right: parent.right
30 | anchors.topMargin: 5
31 | anchors.rightMargin: 5
32 | width: 49
33 | height: 49
34 | imageSrc: "qrc:/pages/QianProjectPages/QianDragViewPage/remove.png"
35 | backHoverColor: skin.light ? "#02000000" : "#11FFFFFF"
36 | ToolTip.delay: 1000
37 | ToolTip.visible: hovered
38 | ToolTip.text: qsTr("删除")
39 | onClicked: requestRemove()
40 | }
41 |
42 | Text {
43 | anchors.centerIn: parent
44 | color: isSelect ? "#AC2727" : skin.light ? "#F2732E" : "#FED963";
45 | text: modelData == null ? "" : modelData.name
46 | font.pixelSize: itemPixSize
47 | font.family: "Microsoft Yahei"
48 | elide: Text.ElideRight
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/QianDragView.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Controls 2.14
3 | import Qt.QianDragEventCatch 1.0
4 |
5 | Flickable {
6 | id: contains
7 | property real itemWidth: 140
8 | property real itemHeight: 180
9 | property int itemPixSize: 20
10 | property int interval: 4
11 | property int itemRadius: 5
12 | property int animatioMoveIndex: -1
13 | property int maxFlickVelocity: 0
14 | property alias chatView : _chatView
15 |
16 |
17 | function append(text) {
18 | modelData.append({"name": text})
19 | chatView.positionViewAtIndex(modelData.count-1, ListView.End)
20 | }
21 |
22 | QianDragEventCatch {
23 | id: dragCatch
24 | container: contains
25 | filterObj: _chatView
26 |
27 | property bool isDrag: false
28 | property int pressMouseX: 0
29 | property int pressMouseY: 0
30 | property int pressItemX: 0
31 | property int pressItemY: 0
32 | property int pressIndex: -1
33 |
34 | onReleased: {
35 | chatView.interactive = true
36 | if (!dragDelegate.visible) {
37 | chatView.currentIndex = chatView.currentIndex == pressIndex ? -1 : pressIndex
38 | } else {
39 | isDrag = false;
40 | dragDelegate.finish()
41 | }
42 | }
43 | onPressed: {
44 | if(mouseY >= (chatView.height - itemHeight)/2 && mouseY <= (chatView.height + itemHeight)/2) {
45 | chatView.interactive = false
46 | pressIndex = chatView.indexAt(mouseX+chatView.contentX, mouseY);
47 | if(pressIndex<0) {
48 | catchEnable = false
49 | chatView.interactive = true
50 | return;
51 | }
52 | let item = chatView.itemAtIndex(pressIndex)
53 | if(item == null) {
54 | catchEnable = false
55 | chatView.interactive = true
56 | return;
57 | }
58 | let contains = item.informationContains(mouseX-item.x, mouseY -item.y)
59 | isDrag = false;
60 | pressMouseX = mouseX;
61 | pressMouseY = mouseY;
62 | pressItemX = item.x - chatView.contentX
63 | pressItemY = (chatView.height - itemHeight)/2;
64 |
65 | } else {
66 | isDrag = false
67 | catchEnable = false
68 | chatView.interactive = true
69 | }
70 | }
71 | onMoved: {
72 | if (isDrag == false && (Math.abs(pressMouseX-mouseX) > 4 || Math.abs(pressMouseY-mouseY) > 4) && !scrollAnimation.running) {
73 | dragDelegate.show(chatView.model.get(pressIndex),
74 | pressItemX, mouseX, pressIndex, pressItemY, mouseY)
75 | isDrag = true
76 | } else if (isDrag) {
77 | dragDelegate.move(mouseX, mouseY)
78 | }
79 | }
80 | }
81 |
82 |
83 | ListView {
84 | id: _chatView
85 | anchors.fill: parent
86 | currentIndex: -1
87 |
88 | orientation: ListView.Horizontal
89 |
90 | Component.onCompleted: {
91 | for(var i = 0; i < 5; i++) {
92 | modelData.append({"name": "数据块" + i})
93 | }
94 | }
95 |
96 | model: ListModel {
97 | id: modelData
98 | }
99 |
100 |
101 |
102 |
103 | ScrollBar.horizontal: ScrollBar {
104 | id: scroll
105 | policy: size<1.0? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
106 |
107 | contentItem: Rectangle {
108 | implicitHeight: 6
109 | implicitWidth: 100
110 | radius: 3
111 | color: scroll.pressed ? accentOpacityColor
112 | : accentOpacityHoverColor
113 | border.color: "#AAEF3007"
114 | border.width: dragDelegate.visible && (scroll.position == 0 || scroll.position >=(1.0 - scroll.visualSize)) ? 1 : 0
115 |
116 |
117 | }
118 | background: Item {
119 |
120 | }
121 |
122 | NumberAnimation on position {
123 | id: scrollAnimation
124 | duration: 300
125 | running: false
126 | function requestStart(from, to, duration) {
127 | scrollAnimation.from = from
128 | scrollAnimation.to = to
129 | scrollAnimation.duration = duration
130 | scrollAnimation.restart()
131 | }
132 | onRunningChanged: {
133 | if(!scrollAnimation.running && dragCatch.isDrag) {
134 | if(dragDelegate.visible) dragDelegate.update()
135 | }
136 | }
137 | }
138 | }
139 |
140 | NumberAnimation on x {
141 | id: xAnimation
142 | duration: 300
143 | running: false
144 | function requestStart(from, to) {
145 | xAnimation.from = from
146 | xAnimation.to = to
147 | xAnimation.restart()
148 | }
149 |
150 | }
151 |
152 |
153 | add: Transition {
154 | NumberAnimation { properties: "y"; from: -chatView.height; to: 0; duration: 150 }
155 | }
156 | move: Transition {
157 | NumberAnimation { properties: "x,y"; duration: 180 }
158 | }
159 |
160 | moveDisplaced: Transition {
161 | SequentialAnimation {
162 | ScriptAction{
163 | script: {
164 | let item = chatView.itemAtIndex(animatioMoveIndex)
165 | if(item != null) item.z = 100
166 | }
167 | }
168 |
169 | NumberAnimation { properties: "x,y"; duration: 180 }
170 | ScriptAction{
171 | script: {
172 | let item = chatView.itemAtIndex(animatioMoveIndex)
173 | if(item != null) item.z = 1
174 | }
175 | }
176 | }
177 | }
178 | displaced: Transition {
179 | NumberAnimation { properties: "x,y"; duration: 180 }
180 | }
181 |
182 | delegate: QianDragDelegate {
183 | id: delegate
184 | onCloseRequest: {
185 | chatView.model.remove(index)
186 | }
187 | }
188 | QianDragDelegateInformation {
189 | id: dragDelegate
190 | visible: false
191 | height: itemHeight
192 | width: itemWidth
193 | property int pressX: 0
194 | property int pressY: 0
195 | property int baseY: 0
196 | property int baseX: 0
197 | property int dragIndex: -99
198 | property int pressIndex: -99
199 | function show(data,baseX,preX,pressIndex, baseY,preY) {
200 | dragDelegate.modelData = data
201 | dragDelegate.pressIndex = pressIndex
202 | dragDelegate.isSelect = pressIndex == chatView.currentIndex
203 | pressX = preX
204 | x = baseX
205 | dragDelegate.baseX = baseX
206 | dragDelegate.baseY = baseY
207 | pressY = preY
208 | y = baseY
209 | visible = true
210 | }
211 |
212 | function finish() {
213 | visible = false
214 | var index = dragIndex;
215 | if (index > 1 && pressIndex itemWidth/2 ? index+1 : index;
235 | }
236 |
237 | let to;
238 | let step;
239 |
240 | if(x < itemWidth/4 && scroll.position > 0) {
241 | let step = scroll.visualSize*0.12;
242 | to = scroll.position - step
243 | if(to < 0) {
244 | to = 0
245 | }
246 | scrollAnimation.requestStart(scroll.position, to, 200)
247 | } else if(scrollAnimation.running && x >= itemWidth/4 && x <= itemWidth/4 && scroll.position > 0) {
248 | scrollAnimation.stop()
249 | } else if(x >= (chatView.width-itemWidth*0.75) && scroll.visualSize > 0 && scroll.position <(1.0 - scroll.visualSize)) {
250 | let step = scroll.visualSize*0.12;
251 | to = scroll.position + step
252 | if(to > 1.0 - scroll.visualSize) {
253 | to = 1.0 - scroll.visualSize
254 | }
255 | scrollAnimation.requestStart(scroll.position, to, 200)
256 | }
257 |
258 | }
259 |
260 | function move(mvX, mvY) {
261 | var movex = mvX - pressX
262 | x = movex + baseX
263 | var movey = mvY - pressY
264 | y = movey + baseY
265 | update();
266 | }
267 |
268 | }
269 | }
270 |
271 | }
272 |
273 |
274 |
275 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/QianDragViewPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Window 2.14
3 | import QtQuick.Layouts 1.12
4 | import QtQuick.Controls 2.14
5 | import QtQuick.Controls.Material 2.12
6 | import "qrc:/common"
7 | Item {
8 |
9 | property int index: 5
10 | ColumnLayout {
11 | anchors.fill: parent
12 | anchors.margins: 10
13 | spacing: 22
14 |
15 | property int index: 5
16 |
17 | RowLayout {
18 | Layout.fillWidth: true
19 |
20 | spacing: 5
21 | BaseTextField {
22 | id: input
23 | Layout.fillWidth: true
24 | Layout.preferredHeight: 32
25 | text: "数据块" + index
26 | font.pixelSize: 18
27 | font.family: "Microsoft Yahei"
28 |
29 |
30 | }
31 | SkinBaseButton {
32 | id: btn
33 | text: "添加"
34 | font.pixelSize: 17
35 | backRadius: 4
36 | onClicked: {
37 | if (input.text.length > 0) {
38 | list.append(input.text)
39 | index += 1
40 | input.text = "数据块" + index
41 | }
42 | }
43 | }
44 | }
45 |
46 | QianDragView {
47 | id: list
48 | Layout.fillWidth: true
49 | Layout.fillHeight: true
50 | clip: true
51 | }
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/qiandrageventcatch.cpp:
--------------------------------------------------------------------------------
1 | #include "qiandrageventcatch.h"
2 | #include
3 | #include
4 | QianDragEventCatch::QianDragEventCatch(QObject *parent) : QObject(parent)
5 | {
6 |
7 | }
8 |
9 |
10 | QianDragEventCatch::~QianDragEventCatch()
11 | {
12 | if (_container)
13 | _container->removeEventFilter(this);
14 |
15 | if (_filterObj)
16 | _filterObj->removeEventFilter(this);
17 |
18 | }
19 |
20 | void QianDragEventCatch::setContainer(QObject *target)
21 | {
22 | if (!target) return;
23 |
24 | if (_container != target) {
25 | if (_container) _container->removeEventFilter(this);
26 | target->installEventFilter(this);
27 | _container = target;
28 | emit containerChanged();
29 | }
30 | }
31 |
32 | void QianDragEventCatch::setFilterObj(QObject *target)
33 | {
34 | if (!target) return;
35 |
36 | if (_filterObj != target) {
37 | if (_filterObj) _filterObj->removeEventFilter(this);
38 | target->installEventFilter(this);
39 | _filterObj = target;
40 | emit filterObjChanged();
41 | }
42 | }
43 |
44 |
45 | bool QianDragEventCatch::eventFilter(QObject *obj, QEvent *evt)
46 | {
47 | QMouseEvent *mouse = dynamic_cast(evt);
48 | if(mouse ) {
49 | if(mouse->button() == Qt::LeftButton && mouse->type() == QEvent::MouseButtonPress) {
50 | _catchEnable = true;
51 | emit pressed(mouse->pos().x(), mouse->pos().y());
52 | } else if(mouse->buttons() == Qt::LeftButton && mouse->type() == QEvent::MouseMove && _catchEnable) {
53 | emit moved(mouse->pos().x(), mouse->pos().y());
54 | } else if(mouse->button() == Qt::LeftButton && mouse->type() ==QEvent::MouseButtonRelease && _catchEnable) {
55 | emit released(mouse->pos().x(), mouse->pos().y());
56 | }
57 | }
58 | return QObject::eventFilter(obj, evt);
59 | }
60 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/qiandrageventcatch.h:
--------------------------------------------------------------------------------
1 | #ifndef QianDragEventCatch_H
2 | #define QianDragEventCatch_H
3 |
4 | #include
5 |
6 | class QianDragEventCatch : public QObject
7 | {
8 | Q_OBJECT
9 | Q_PROPERTY(QObject* container READ container WRITE setContainer NOTIFY containerChanged)
10 | Q_PROPERTY(QObject* filterObj READ filterObj WRITE setFilterObj NOTIFY filterObjChanged)
11 |
12 | Q_PROPERTY(bool catchEnable MEMBER _catchEnable NOTIFY catchEnableChanged)
13 | signals:
14 | void containerChanged();
15 | void filterObjChanged();
16 | void catchEnableChanged();
17 |
18 | public:
19 | explicit QianDragEventCatch(QObject *parent = nullptr);
20 | ~QianDragEventCatch();
21 |
22 | QObject *container() { return _container; }
23 | void setContainer(QObject *container);
24 |
25 | QObject *filterObj() { return _filterObj; }
26 | void setFilterObj(QObject *container);
27 |
28 |
29 | bool eventFilter(QObject *obj, QEvent *evt);
30 |
31 |
32 | signals:
33 | void released(int mouseX, int mouseY);
34 | void pressed(int mouseX, int mouseY);
35 | void moved(int mouseX, int mouseY);
36 |
37 | protected:
38 |
39 | QObject *_container{nullptr};
40 | QObject *_filterObj{nullptr};
41 | bool _catchEnable{true};
42 | };
43 |
44 | #endif // QianDragEventCatch_H
45 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianDragViewPage/remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianDragViewPage/remove.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/Ball.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | ** 小球控件
3 | ** Author : 诺谦 https://blog.csdn.net/qq_37997682/article/details/126640154
4 | ** Create : 2021-5-24
5 | ****************************************************************************/
6 |
7 | import QtQuick 2.12
8 | Image {
9 | id: img
10 |
11 | property var pointX: 0
12 | property var pointY: 0
13 | property var preX: 0
14 | property var preY: 0
15 | property var vx: 0
16 | property var vy: 0
17 | property var r: 0
18 | property var cor: 0 // 碰撞后的能量损失值,为 1 表示碰撞后不会损失能量
19 | property var mass: 0 // 小球质量,球体越大,质量越大
20 | property var rotate: 0
21 | property var ballType: 0 // 小球类型
22 | property var shapeChange: false // 形状是否在改变中,创建小球的时候,形状会慢慢变大,此时用户不能立即降落小球
23 | property var mergeSrc: "" // 合并时的动画资源
24 | property var mergeStart: false // 启动合并动画显示
25 | property var endPointX: 0 // 合并时的终点x坐标
26 | property var endPointY: 0 // 启动合的终点y坐标
27 |
28 | Behavior on width {
29 | NumberAnimation {
30 | id: widthAnima; duration: 300;
31 |
32 |
33 | onRunningChanged: shapeChange = running;
34 | }
35 | }
36 |
37 | Behavior on height { NumberAnimation { duration: 300; } }
38 |
39 | fillMode: Image.Stretch
40 | mipmap: true
41 | x: pointX - width/2
42 | y: pointY - height/2
43 | width: 0
44 | height: 0
45 |
46 | NumberAnimation on pointX {
47 | id: enPointXAnimation
48 | running: mergeStart == true
49 | to: endPointX; duration: 300
50 | }
51 | NumberAnimation on pointY {
52 | id: enPointYAnimation
53 | running: mergeStart == true
54 | to: endPointY; duration: 300
55 | }
56 |
57 | NumberAnimation on rotate {
58 | id: rotateAnimation
59 | running: mergeStart == true
60 | to: calcEndRotate()
61 | duration: 300
62 | onFinished: {
63 | preX = pointX
64 | preY = pointY
65 | mergeStart = false
66 | }
67 | }
68 |
69 | function calcEndRotate() {
70 |
71 | let distance = Math.sqrt(Math.pow((endPointX - pointX),2) + Math.pow((endPointY - pointY),2));
72 |
73 | if (endPointX > pointX) // 往右
74 | return rotation + 360/(2 * r * 3.14) * distance * 0.5;
75 | else // 往左
76 | return rotation - 360/(2 * r * 3.14) * distance * 0.5;
77 |
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/BallRun.js:
--------------------------------------------------------------------------------
1 | .import QtQuick 2.0 as QQ
2 |
3 |
4 | var ballData = [
5 | {
6 | "radius" : 125,
7 | "cor" : 0.2,
8 | "image" : "icon/ball1.png",
9 | "mergeImage" : "icon/merge2.png",
10 | },
11 | {
12 | "radius" : 115,
13 | "cor" : 0.3,
14 | "image" : "icon/ball2.png",
15 | "mergeImage" : "icon/merge3.png",
16 | },
17 | {
18 | "radius" : 105,
19 | "cor" : 0.3,
20 | "image" : "icon/ball3.png",
21 | "mergeImage" : "icon/merge4.png",
22 | },
23 | {
24 | "radius" : 95,
25 | "cor" : 0.3,
26 | "image" : "icon/ball4.png",
27 | "mergeImage" : "icon/merge5.png",
28 | },
29 | {
30 | "radius" : 80,
31 | "cor" : 0.3,
32 | "image" : "icon/ball5.png",
33 | "mergeImage" : "icon/merge6.png",
34 | },
35 | {
36 | "radius" : 70,
37 | "cor" : 0.3,
38 | "image" : "icon/ball6.png",
39 | "mergeImage" : "icon/merge7.png",
40 | },
41 | {
42 | "radius" : 60,
43 | "cor" : 0.3,
44 | "image" : "icon/ball7.png",
45 | "mergeImage" : "icon/merge8.png",
46 | },
47 | {
48 | "radius" : 50,
49 | "cor" : 0.3,
50 | "image" : "icon/ball8.png",
51 | "mergeImage" : "icon/merge9.png",
52 | },
53 | {
54 | "radius" : 40,
55 | "cor" : 0.3,
56 | "image" : "icon/ball9.png",
57 | "mergeImage" : "icon/merge10.png",
58 | },
59 | {
60 | "radius" : 30,
61 | "cor" : 0.3,
62 | "image" : "icon/ball10.png",
63 | "mergeImage" : "icon/merge11.png",
64 | },
65 | {
66 | "radius" : 20,
67 | "cor" : 0.1,
68 | "image" : "icon/ball11.png",
69 | "mergeImage" : "icon/merge11.png",
70 | },
71 | ];
72 |
73 | var component;
74 | var mergeComponent;
75 | var balls = new Array(0);
76 | var currentBall = null;
77 |
78 |
79 | function getBallData() {
80 |
81 | if (balls.length < 3) // 开场前3个都为葡萄
82 | return ballData.length - 1;
83 |
84 | else if (balls.length < 6)
85 | return Math.random() < 0.55 ? ballData.length - 1 :
86 | Math.random() < 0.55 ? ballData.length - 2 :
87 | Math.random() < 0.88 ? ballData.length - 3 :
88 | Math.random() < 0.77 ? ballData.length - 4 :
89 | Math.random() < 0.66 ? ballData.length - 5 : ballData.length - 6;
90 |
91 | else
92 | return Math.random() < 0.35 ? ballData.length - 1 :
93 | Math.random() < 0.25 ? ballData.length - 2 :
94 | Math.random() < 0.36 ? ballData.length - 3 :
95 | Math.random() < 0.40 ? ballData.length - 4 : ballData.length - 5;
96 | }
97 |
98 |
99 | function newBall(x) {
100 | if (component == null)
101 | component = Qt.createComponent("Ball.qml");
102 |
103 | if (component.status == QQ.Component.Ready) {
104 | let index = getBallData();
105 |
106 | if (x < ballData[index].radius) {
107 | x = ballData[index].radius
108 | } else if (x + ballData[index].radius > width) {
109 | x = width - ballData[index].radius
110 | }
111 |
112 | var dynamicObject = component.createObject(canvas,
113 | { pointX: x,
114 | pointY: ballData[index].radius,
115 | r: ballData[index].radius,
116 | cor: ballData[index].cor,
117 | source: ballData[index].image,
118 | mass: ballData[index].radius * ballData[index].radius,
119 | ballType: index,
120 | mergeSrc : ballData[index].mergeImage,
121 | });
122 | dynamicObject.width = ballData[index].radius * 2;
123 | dynamicObject.height = ballData[index].radius * 2;
124 | currentBall = dynamicObject
125 |
126 | }
127 | }
128 |
129 |
130 | function currentBallMove(x) {
131 | if (currentBall == null) {
132 | return false;
133 | }
134 | if (x < currentBall.r || x + currentBall.r > width) {
135 | return false;
136 | }
137 |
138 | currentBall.pointX = x ;
139 | return true;
140 | }
141 |
142 | function currentBallStartDown() {
143 | if (currentBall == null) {
144 | return false;
145 | }
146 |
147 |
148 | if ( currentBall.shapeChange == true) {
149 | return false;
150 | }
151 |
152 | currentBall.vy = 10;
153 | balls[balls.length] = currentBall
154 | currentBall = null
155 | return true;
156 | }
157 |
158 | const edgeCorX = 0.2;
159 | const edgeCorY = 0.2;
160 | const ballAy = 1;
161 | function ballsMove() {
162 | for (var i in balls) {
163 | var ball = balls[i];
164 |
165 |
166 | ball.vy += ballAy;
167 |
168 | ball.preX = ball.pointX
169 | ball.preY = ball.pointY
170 | ball.pointX += ball.vx;
171 | ball.pointY += ball.vy;
172 |
173 | if (ball.pointX < ball.r) {
174 | ball.pointX = ball.r
175 | ball.vx = -ball.vx * edgeCorX
176 | if (Math.abs(ball.vx)<0.1) ball.vx = 0
177 |
178 | } else if (ball.pointX + ball.r > width) {
179 | ball.pointX = width - ball.r
180 | ball.vx = -ball.vx * edgeCorX
181 | if (Math.abs(ball.vx)<0.1) ball.vx = 0
182 |
183 | }
184 |
185 | if (ball.pointY < ball.r) {
186 | ball.pointY = ball.r
187 | ball.vy = -ball.vy * edgeCorY
188 | } else if (ball.pointY + ball.r > height) {
189 | ballIsDown(ball);
190 | ball.pointY = height - ball.r
191 | ball.vy = -ball.vy * edgeCorY
192 | }
193 |
194 |
195 | }
196 | }
197 |
198 |
199 |
200 | function collide() {
201 |
202 | for (let i = 0; i < balls.length; i++) {
203 | let ball1 = balls[i]
204 | for (let j = i + 1; j < balls.length; j++) {
205 | let ball2 = balls[j]
206 | let distance = Math.sqrt(Math.pow((ball1.pointX - ball2.pointX),2) + Math.pow((ball1.pointY - ball2.pointY),2));
207 | let radius = ball1.r + ball2.r;
208 |
209 | if (distance > radius) continue;
210 |
211 |
212 | if (!ball1.mergeStart && !ball2.mergeStart && ball1.ballType == ball2.ballType && ball2.ballType > 0) {
213 | mergeBall(j,i);
214 | return;
215 | }
216 | else
217 | changeSpeedAndDirection(ball1, ball2, distance, radius);
218 | }
219 | }
220 | }
221 |
222 | function ballsRotate() {
223 |
224 | for (let i = 0; i < balls.length; i++) {
225 | var ball = balls[i]
226 | if (ball.mergeStart) continue
227 | let distance = Math.sqrt(Math.pow((ball.pointX - ball.preX),2) + Math.pow((ball.pointY - ball.preY),2));
228 |
229 | if (Math.abs(distance) && ball.vy < 10 ) {
230 | if (ball.vx > 0) {
231 | ball.rotation += 360/(2 * ball.r * 3.14) * distance;
232 | }
233 | else {
234 | ball.rotation -= 360/(2 * ball.r * 3.14) * distance;
235 | }
236 | if (Math.abs(ball.vx) < 0.1)
237 | ball.vx = 0
238 |
239 | }
240 | }
241 | }
242 |
243 |
244 | function changeSpeedAndDirection(ball1, ball2, distance, radius) {
245 |
246 |
247 | if (distance < radius) {
248 | let dd = radius - distance;
249 | let offsetC = radius - distance;
250 | let ballOffsetX = (ball1.pointX - ball2.pointX) / radius * offsetC ;
251 | let ballOffsetY = Math.abs((ball1.pointY - ball2.pointY) / radius * offsetC);
252 |
253 | let ball1MassRation = ball2.mass / (ball1.mass+ball2.mass);
254 | let ball2MassRation = ball1.mass / (ball1.mass+ball2.mass);
255 |
256 | ball1.pointX += ballOffsetX * ball1MassRation;
257 | ball2.pointX -= ballOffsetX * ball2MassRation;
258 | if (ball1.pointY > ball2.pointY) ball2.pointY -= ballOffsetY;
259 | else ball1.pointY -= ballOffsetY;
260 |
261 | }
262 | let dx = ball1.pointX - ball2.pointX
263 | let dy = ball1.pointY - ball2.pointY
264 |
265 | let ex = dx / radius; let ey = dy / radius;
266 |
267 | let v1n = ex * ball1.vx + ey * ball1.vy
268 | let v2n = ex * ball2.vx + ey * ball2.vy
269 | if(v1n >= v2n) return;
270 | let v1nn = ball1.cor * ((ball1.mass - ball2.mass) * v1n + 2 *ball2.mass *v2n ) / (ball1.mass +ball2.mass)
271 | let v2nn = ball2.cor * ((ball2.mass - ball1.mass) * v2n + 2 *ball1.mass *v1n ) / (ball1.mass +ball2.mass)
272 |
273 | let ux = -dy / radius; let uy = dx / radius;
274 | let v1t =ux * ball1.vx + uy*ball1.vy
275 | let v2t = ux * ball2.vx + uy * ball2.vy
276 |
277 | ball1.vx = v1nn*ex +v1t*ux;
278 | ball1.vy = v1nn*ex +v1t*uy;
279 |
280 | ball2.vx = v2nn*ex +v2t*ux;
281 | ball2.vy = v2nn*ex +v2t*uy;
282 |
283 |
284 | if (v1n == 0 && v1t ==0 && v2t == 0) {
285 | ball2.vx += 0.1
286 | ball2.vy += 0.3
287 | }
288 |
289 | }
290 |
291 | function mergeBall(i, j) {
292 | let ball1 = balls[i]
293 | let ball2 = balls[j]
294 |
295 |
296 |
297 | ball1.endPointX = ball1.pointX + (ball2.pointX - ball1.pointX) / 2
298 | ball1.endPointY = ball1.pointY + (ball2.pointY - ball1.pointY) / 2
299 |
300 | if (ball1.vy > 10)
301 | ball1.vy = 0
302 |
303 | if (ball1.endPointX < ball1.r) {
304 | ball1.endPointX = ball1.r
305 | } else if (ball1.endPointX + ball1.r > width) {
306 | ball1.endPointX = width - ball1.r
307 | }
308 |
309 | if (ball1.endPointY < ball1.r) {
310 | ball1.endPointY = ball1.r
311 | } else if (ball1.endPointY + ball1.r > height) {
312 | ball1.endPointY = height - ball.r
313 | }
314 |
315 | ball2.destroy();
316 | balls[j] = null;
317 | balls.splice(j, 1);
318 |
319 | score += (ballData.length - ball1.ballType) * 2
320 | ball1.ballType -= 1
321 | ball1.mergeSrc = ballData[ball1.ballType].mergeImage;
322 |
323 | ball1.r = ballData[ball1.ballType].radius
324 | ball1.cor = ballData[ball1.ballType].cor
325 | ball1.mass = ball1.r * ball1.r
326 | ball1.source = ballData[ball1.ballType].image
327 | ball1.width = ball1.r * 2;
328 | ball1.height = ball1.r * 2;
329 | ball1.vx = 0
330 | ball1.vy = 0
331 |
332 | ball1.mergeStart = true
333 |
334 | newMergeAnimal(ball1.endPointX,ball1.endPointY,ball1.r,ballData[ball1.ballType].mergeImage);
335 | }
336 |
337 |
338 | function ballOverflow() {
339 |
340 | for (var i in balls) {
341 | let ball = balls[i]
342 | if (!ball.mergeStart && Math.abs(ball.vy) < 0.3 && Math.abs(ball.vx) < 0.3 && (ball.y < lineDashY)) {
343 |
344 | if (currentBall != null) {
345 | balls[balls.length] = currentBall
346 | currentBall = null
347 | }
348 | return true
349 | }
350 | }
351 | return false
352 | }
353 |
354 | function ballCloseAnimal() {
355 |
356 | var minY = 999999
357 | var index = -1
358 |
359 | for (var i in balls) {
360 | if (balls[i].pointY < minY) {
361 | minY = balls[i].pointY
362 | index = i
363 | }
364 | }
365 |
366 | if (index >= 0) {
367 | let image = balls[index].ballType > 0 ? balls[index].ballType -1 : balls[index].ballType
368 |
369 | newMergeAnimal(balls[index].pointX,
370 | balls[index].pointY,
371 | balls[index].r,
372 | ballData[image].mergeImage);
373 |
374 | balls[index].destroy();
375 | balls[index] = null;
376 | balls.splice(index, 1);
377 | }
378 | return index
379 | }
380 |
381 |
382 | function process() {
383 |
384 | if (!finish) {
385 | ballsMove();
386 | collide();
387 | ballsRotate();
388 | if (ballOverflow()) {
389 | finish = 1
390 | }
391 | }
392 | else if (finish == 1) {
393 | let date = new Date;
394 | let totalMs = date - preBallLeaveDate;
395 |
396 | if (totalMs > 60) {
397 | if (ballCloseAnimal() >= 0) {
398 | preBallLeaveDate = date
399 | } else {
400 | finish = 2
401 | finishSound.play()
402 |
403 | }
404 | }
405 | }
406 | }
407 |
408 |
409 | function newMergeAnimal(pointX, pointY, radius, image) {
410 |
411 | if (mergeComponent == null)
412 | mergeComponent = Qt.createComponent("MergeAnimal.qml");
413 |
414 | if (mergeComponent.status == QQ.Component.Ready) {
415 |
416 | var dynamicMerge = mergeComponent.createObject(canvas,
417 | { x: pointX - radius * 1.3,
418 | y: pointY - radius * 1.3,
419 | width: radius * 2.6,
420 | height: radius * 2.6,
421 | mergeSrc: image,
422 | });
423 |
424 | } else {
425 | console.log("error loading block component");
426 | return false;
427 | }
428 |
429 | mergeSound1.play()
430 | mergeSound2.play()
431 | return true;
432 | }
433 |
434 | function ballIsDown(ball) {
435 | if (ball.vy > 30)
436 | downSound.play();
437 | }
438 |
439 |
440 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/FinishWindow.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Layouts 1.12
3 |
4 | Rectangle {
5 | id: finishWind
6 | property int score: 1200
7 | color: "#80000000"
8 | z: 501
9 |
10 | ColumnLayout {
11 | anchors.centerIn: parent
12 | spacing: 40
13 |
14 | Row {
15 | spacing: 20
16 | Layout.alignment: Qt.AlignCenter
17 | Image {
18 | source: "icon/finish.png"
19 | width: 58
20 | height: 58
21 | }
22 | ScoreNumber {
23 | id: scoreNumber
24 | height: 58
25 | value: finishWind.score
26 | }
27 | }
28 |
29 | Text {
30 | Layout.alignment: Qt.AlignCenter
31 | Layout.fillWidth: true
32 | color: "#FFFFFF"
33 | font.pixelSize: 40
34 | font.family: "Microsoft Yahei"
35 | font.letterSpacing: 28
36 | text: "游戏结束"
37 | horizontalAlignment: Text.AlignHCenter
38 | }
39 |
40 | Text {
41 | Layout.alignment: Qt.AlignCenter
42 | Layout.fillWidth: true
43 | color: "#FFFFFF"
44 | font.pixelSize: 17
45 | font.family: "Microsoft Yahei"
46 | font.letterSpacing: 5
47 | text: "点击重新开始"
48 | horizontalAlignment: Text.AlignHCenter
49 | }
50 |
51 | }
52 |
53 |
54 | NumberAnimation on opacity {
55 | from: 0; to: 1.0; duration: 600; running: finishWind.visible
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/GameCanvas.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | ** 游戏界面-负责刷新小球运动轨迹等
3 | ** Author : 诺谦 https://blog.csdn.net/qq_37997682/article/details/126640154
4 | ** Create : 2021-5-24
5 | ****************************************************************************/
6 |
7 | import QtQuick 2.12
8 | import "BallRun.js" as BallRes
9 | import QtMultimedia 5.10
10 | Canvas {
11 | id: canvas
12 |
13 | visible: true
14 | property int score: 0
15 | property int lineDashY: 100
16 | property int finish: 0 // 0 : 未结束 1: 结束动画 2: 结束界面
17 | property var preBallLeaveDate: new Date
18 | onPaint: {
19 | var context = getContext('2d')
20 | var preDate = new Date;
21 |
22 | function draw() {
23 | BallRes.process();
24 | requestAnimationFrame(draw);
25 | }
26 |
27 | drawLineDash();
28 | draw();
29 | }
30 |
31 | MouseArea {
32 | id : area
33 | anchors.fill: parent
34 | hoverEnabled: true
35 | onPositionChanged: {
36 | if (!finish ) BallRes.currentBallMove(mouseX)
37 | }
38 | onClicked: {
39 | if (!finish && BallRes.currentBallStartDown()) {
40 | BallRes.newBall(area.mouseX)
41 | }
42 | else if (finish == 2) {
43 | finish = 0
44 | score = 0
45 | BallRes.newBall(area.mouseX)
46 | }
47 | }
48 | }
49 |
50 | function drawLineDash() {
51 | context.setLineDash( [ 6, 6, 3] );
52 | context.lineWidth = 4;
53 | context.clearRect(0, lineDashY - 4, canvas.width, lineDashY + 4);
54 | context.strokeStyle = "#91431E"
55 | context.lineCap = "round"
56 | context.moveTo(0, lineDashY);
57 | context.lineTo(canvas.width, lineDashY);
58 | context.stroke();
59 | }
60 |
61 |
62 |
63 | SoundEffect {
64 | id: downSound
65 | source: "audio/down.wav"
66 | }
67 |
68 | SoundEffect {
69 | id: mergeSound1
70 | volume: 0.6
71 | source: "audio/merge1.wav"
72 | }
73 |
74 | SoundEffect {
75 | id: mergeSound2
76 | source: "audio/merge2.wav"
77 | }
78 |
79 | SoundEffect {
80 | id: finishSound
81 | source: "audio/finish.wav"
82 | }
83 |
84 | ScoreNumber {
85 | id: scoreNumber
86 | x: 10
87 | y: 20
88 | value: score
89 | }
90 |
91 | Component.onCompleted: BallRes.newBall(area.mouseX);
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/MergeAnimal.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | ** 小球合并时,产生的动画控件
3 | ** Author : 诺谦 https://blog.csdn.net/qq_37997682/article/details/126640154
4 | ** Create : 2021-5-24
5 | ****************************************************************************/
6 |
7 | import QtQuick 2.12
8 | import QtMultimedia 5.10
9 | Item {
10 | property var mergeSrc: ""
11 | property var modelSize: 5
12 |
13 | id: merge
14 |
15 | Repeater {
16 | model: modelSize
17 | Image {
18 | fillMode: Image.Stretch
19 | anchors.fill: parent
20 | source: mergeSrc
21 | rotation: Math.random()*90
22 | opacity: (modelSize - index) / modelSize // 0 -> 1
23 | scale: (modelSize - index) / modelSize // 0 -> 1
24 |
25 | NumberAnimation on opacity {
26 | id: mergeAnimation
27 | running: true
28 | to: 1.0; duration: 200
29 | onFinished: merge.animationFinished()
30 | }
31 | }
32 | }
33 |
34 |
35 |
36 |
37 | function animationFinished() {
38 | this.destroy(100);
39 | }
40 | Timer {
41 |
42 | running: true
43 | interval: 300
44 | onTriggered: merge.destroy()
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/QianMergeWatermelonPage.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | ** 主界面
3 | ** Author : 诺谦 https://blog.csdn.net/qq_37997682/article/details/126640154
4 | ** Create : 2021-5-24
5 | ****************************************************************************/
6 |
7 | import QtQuick 2.12
8 | import QtQuick.Controls 2.12
9 | import QtQuick.Layouts 1.14
10 | Item {
11 | id: screen
12 |
13 |
14 | Rectangle {
15 | anchors.fill: parent
16 | anchors.margins: 10
17 | color: "transparent"
18 | clip: true
19 |
20 | Rectangle {
21 | id: home
22 | width: parent.width;
23 | height: parent.height - 80
24 | color: skin.light ? "#FFE89D" : "#AAFFE89D"
25 | GameCanvas {
26 | id: gameCanvas
27 | anchors.fill: parent
28 | }
29 |
30 | }
31 | Image {
32 | id: background
33 | width: parent.width;
34 | height: 80
35 | anchors.top: home.bottom
36 | source: "icon/bottomBack.png"
37 | fillMode: Image.PreserveAspectCrop
38 | opacity: skin.light ? 1.0 : 0.8
39 | }
40 | FinishWindow {
41 | anchors.fill: parent
42 | visible: gameCanvas.finish == 2
43 | score: gameCanvas.score
44 | }
45 | }
46 |
47 |
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/ScoreNumber.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | ** 成绩值显示控件
3 | ** Author : 诺谦 https://blog.csdn.net/qq_37997682/article/details/126640154
4 | ** Create : 2021-5-24
5 | ****************************************************************************/
6 |
7 | import QtQuick 2.12
8 |
9 | Canvas {
10 | property int value: 1200
11 | property var numberWidth: numberImage.sourceSize.width / 10
12 | property var numberHeight: numberImage.sourceSize.height
13 | property var drawWidth: numberWidth * height / numberHeight
14 |
15 | id: canvas
16 | width: drawWidth * value.toString().length
17 | height: 40
18 | z: 50
19 | onPaint: {
20 | var context = getContext('2d')
21 | context.clearRect(0,0, canvas.width, canvas.height);
22 | var scoreStr = value.toString()
23 | var dy = 0
24 | var spacing = 5
25 | var dx = canvas.width/2 - ((drawWidth + spacing) * scoreStr.length - spacing)/2;
26 |
27 | for (var i in scoreStr) {
28 | context.drawImage(numberImage, numberImage.getNumberX(parseInt(scoreStr[i])), 0, numberWidth,numberHeight,
29 | dx, dy, drawWidth, height);
30 | dx += drawWidth - spacing
31 | }
32 | }
33 |
34 | Image {
35 | id : numberImage
36 |
37 | source: "icon/number1.png"
38 | visible: false
39 | mipmap: true
40 |
41 | function getNumberX(num) {
42 | return sourceSize.width / 10 * num
43 | }
44 | }
45 | onValueChanged: canvas.requestPaint()
46 | }
47 |
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/d2cb5a4f-1334-4eab-8578-a76aa028644e.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/d2cb5a4f-1334-4eab-8578-a76aa028644e.mp3
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/down.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/down.mp3
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/down.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/down.wav
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/finish.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/finish.mp3
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/finish.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/finish.wav
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge1.mp3
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge1.wav
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge2.mp3
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/audio/merge2.wav
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/1.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball1.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball10.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball11.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball2.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball3.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball4.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball5.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball6.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball7.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball8.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/ball9.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/bottomBack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/bottomBack.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/finish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/finish.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge10.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge11 - 副本.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge11 - 副本.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge11.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge2.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge3.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge4.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge5.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge6.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge7.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge8.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/merge9.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/icon/number1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/icon/number1.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianMergeWatermelonPage/介绍.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/pages/QianProjectPages/QianMergeWatermelonPage/介绍.png
--------------------------------------------------------------------------------
/pages/QianProjectPages/QianPhotoPage.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.14
2 | import QtQuick.Window 2.14
3 | import QtQuick.Layouts 1.12
4 | import QtQuick.Controls 2.14
5 | import QtQuick.Controls.Material 2.12
6 | import Qt.labs.platform 1.1
7 | import QtGraphicalEffects 1.14
8 | import "qrc:/common"
9 | Item {
10 | id: container
11 | property string picturesLocation : "";
12 | property var imageNameFilters : ["所有图片格式 (*.png; *.jpg; *.bmp; *.gif; *.jpeg)"];
13 | property var pictureList : []
14 | property alias pictureIndex : view.currentIndex
15 | property var scaleMax : 800 // 最大800%
16 | property var scaleMin : 10 // 最小10%
17 | property var titleColor : "#E8E8E8"
18 |
19 |
20 | property var ctrlSliderList : [
21 | ["放大", scaleMin, scaleMax , photoImage.scale * 100 , "%"],
22 | ["旋转", -180, 180 , photoImage.rotation, "°"],
23 | ]
24 |
25 | Material.foreground: tingeDrakerColor
26 | FileDialog {
27 | id: fileDialog
28 | title: "请打开图片(可以多选)"
29 | fileMode: FileDialog.OpenFiles
30 | folder: picturesLocation
31 | nameFilters: imageNameFilters
32 | onAccepted: {
33 | pictureList = files
34 | view.currentIndex = -1
35 | view.currentIndex = 0
36 | }
37 | onFolderChanged: picturesLocation = folder
38 | }
39 |
40 | Rectangle {
41 | id: back
42 | radius: 8
43 | color: skin.light ? "#F4F4F4" : "#22000000"
44 | anchors.fill: parent
45 | anchors.margins: 4
46 | clip: true
47 |
48 | antialiasing: true
49 | }
50 |
51 |
52 | Flickable {
53 | id: flick
54 | anchors.fill: back
55 | clip: true
56 |
57 | MouseArea {
58 | anchors.fill: parent
59 | onWheel: {
60 | console.log( photoImage.rotation, wheel.angleDelta.y);
61 | if (wheel.modifiers & Qt.ControlModifier) { // ctrl + 滑轮 则进行旋转图片
62 | photoImage.rotation += wheel.angleDelta.y / 120 * 5;
63 | if (photoImage.rotation > 180)
64 | photoImage.rotation = 180
65 | else if (photoImage.rotation < -180)
66 | photoImage.rotation = -180
67 | if (Math.abs(photoImage.rotation) < 4)
68 | photoImage.rotation = 0;
69 | } else {
70 | photoImage.scale += photoImage.scale * wheel.angleDelta.y / 120 / 10;
71 | if (photoImage.scale > scaleMax / 100)
72 | photoImage.scale = scaleMax / 100
73 | else if (photoImage.scale < scaleMin / 100)
74 | photoImage.scale = scaleMin / 100
75 | }
76 | }
77 | }
78 | Image {
79 | id: photoImage
80 | fillMode: Image.Pad
81 | source: (typeof pictureList[pictureIndex] === 'undefined') ? "" : pictureList[pictureIndex]
82 | smooth: true
83 | mipmap: true
84 | antialiasing: true
85 | Component.onCompleted: {
86 | x = parent.width / 2 - width / 2
87 | y = parent.height / 2 - height / 2
88 | pictureList.length = 0
89 | }
90 |
91 | onStatusChanged: {
92 | if(status == Image.Ready) {
93 | photoImage.x = (imageBack.width) / 2 - photoImage.width / 2
94 | photoImage.y = (imageBack.height) / 2 - photoImage.height / 2
95 |
96 | console.log("back.width imageBack.width", back.width, imageBack.width, photoImage.width)
97 |
98 |
99 | photoImage.scale = 1.0
100 | photoImage.rotation = 0
101 |
102 | }
103 |
104 | }
105 |
106 | PinchArea {
107 | anchors.fill: parent
108 | pinch.target: parent
109 | pinch.minimumRotation: -180 // 设置拿捏旋转图片最大最小比例
110 | pinch.maximumRotation: 180
111 | pinch.minimumScale: 0.1 // 设置拿捏缩放图片最小最大比例
112 | pinch.maximumScale: 10
113 | pinch.dragAxis: Pinch.XAndYAxis
114 | }
115 |
116 | MouseArea {
117 | anchors.fill: parent
118 | drag.target: parent
119 | drag.axis: Drag.XAndYAxis
120 | drag.minimumX: 20 - photoImage.width
121 | drag.maximumX: flick.width - 20
122 | drag.minimumY: 20 - photoImage.height
123 | drag.maximumY: flick.height - 20
124 | }
125 |
126 | }
127 | }
128 |
129 | ColumnLayout {
130 | id: _source
131 | anchors.fill: back
132 | anchors.margins: 4
133 | spacing: 4
134 | RowLayout {
135 | Layout.fillHeight: true
136 | Layout.fillWidth: true
137 | spacing: 1
138 |
139 | Item {
140 | id: imageBack
141 | Layout.fillHeight: true
142 | Layout.fillWidth: true
143 | }
144 |
145 | Rectangle {
146 | Layout.fillHeight: true
147 | Layout.preferredWidth : 220
148 | color: skin.light ? "#99FFFFFF" : "#88000000"
149 |
150 | radius: 8
151 |
152 |
153 | GroupBox {
154 | id: fileGroup
155 | title: "文件选项"
156 |
157 | y:5
158 | width: parent.width
159 | font.family: "Microsoft Yahei"
160 | background.scale: 0.9
161 |
162 | ColumnLayout {
163 | anchors.centerIn: parent
164 | spacing: 12
165 | Repeater {
166 | model : ListModel {
167 | id: fileModel
168 | ListElement { name: "打开文件"; }
169 | ListElement { name: "上一张"; }
170 | ListElement { name: "下一张"; }
171 |
172 | }
173 | SkinBaseButton {
174 | text: fileModel.get(index).name
175 | font.pixelSize: 15
176 | onPressed: fileGroupPressed(index)
177 | Layout.preferredWidth: 92
178 | Layout.preferredHeight: 30
179 | backRadius: 6
180 |
181 | }
182 | }
183 | }
184 | }
185 |
186 |
187 | GroupBox {
188 | id: ctrlGroup
189 | title: "图片控制"
190 | width: parent.width
191 | font.family: "Microsoft Yahei"
192 | anchors.top: fileGroup.bottom
193 | anchors.topMargin: 5
194 | background.scale: 0.9
195 |
196 | ColumnLayout {
197 | width: parent.width-10
198 | Repeater {
199 | model : 2
200 | RowLayout {
201 | YaheiText {
202 | leftPadding: 4
203 | text: ctrlSliderList[index][0]
204 | horizontalAlignment: Text.AlignRight
205 | font.pixelSize: 14
206 | }
207 | Slider {
208 | id: ctrlSlider
209 | Layout.fillWidth: true
210 | from: ctrlSliderList[index][1]
211 | value: ctrlSliderList[index][3]
212 | to: ctrlSliderList[index][2]
213 | stepSize: 1
214 | onMoved: setCtrlValue(index, value);
215 | }
216 | YaheiText {
217 | Layout.preferredWidth : 40
218 | color: tingeColor
219 | text: parseInt(ctrlSliderList[index][3].toString()) + ctrlSliderList[index][4]
220 | }
221 | }
222 | }
223 | }
224 | }
225 |
226 | GroupBox {
227 | id: imageInfoGroup
228 | title: "基本信息"
229 | width: parent.width
230 | font.family: "Microsoft Yahei"
231 | height: 170
232 | anchors.top: ctrlGroup.bottom
233 | anchors.topMargin: 5
234 | background.scale: 0.9
235 |
236 |
237 | ColumnLayout {
238 | width: parent.width-10
239 | spacing: 16
240 | YaheiText {
241 | text: "尺寸: " + photoImage.sourceSize.width + "X" + photoImage.sourceSize.height
242 | font.pixelSize: 14
243 | color: tingeColor
244 | leftPadding: 4
245 | }
246 | YaheiText {
247 | text: "路径: " + ((typeof pictureList[pictureIndex] === 'undefined') ?
248 | "等待打开文件..." : pictureList[pictureIndex].replace("file:///",""))
249 |
250 | Layout.preferredWidth: parent.width - 20
251 | Layout.preferredHeight: 80
252 | wrapMode: Text.Wrap
253 | font.pixelSize: 14
254 | color: tingeColor
255 | leftPadding: 4
256 | }
257 |
258 | }
259 | }
260 |
261 | }
262 |
263 |
264 | }
265 |
266 | Rectangle {
267 | id: images
268 | Behavior on Layout.preferredHeight { NumberAnimation { duration: 250 } }
269 | Layout.fillWidth: true
270 | Layout.preferredHeight: 130
271 | color: skin.light ? "#99FFFFFF" : "#88000000"
272 | radius: 8
273 |
274 | ColumnLayout {
275 | anchors.fill: parent
276 | Button {
277 | id: imageCtrlBtn
278 | Layout.alignment: Qt.AlignVCenter | Qt. AlignRight
279 | text: images.Layout.preferredHeight <= 30 ? "展开("+pictureList.length+")" :
280 | "收起("+pictureList.length+")"
281 |
282 | z: 100
283 | background: Rectangle {
284 | color: "transparent"
285 | }
286 | contentItem: Label {
287 | id: btnForeground
288 | text: parent.text
289 | font.family: "Microsoft Yahei"
290 | font.pixelSize: 14
291 | color: imageCtrlBtn.hovered ? tingeColor : tingeDrakerColor
292 | horizontalAlignment: Text.AlignHCenter
293 | verticalAlignment: Text.AlignVCenter
294 | }
295 | onPressed: {
296 | if (text.indexOf("收起") >= 0) {
297 | images.Layout.preferredHeight = 30
298 | } else {
299 | images.Layout.preferredHeight = 130
300 | }
301 | }
302 | }
303 |
304 | ListView {
305 | id: view
306 | Layout.fillHeight: true
307 | Layout.fillWidth: true
308 | spacing: 4
309 | orientation: ListView.Horizontal
310 | ScrollBar.horizontal: ScrollBar {
311 | id: scroll1
312 | policy: size<1.0? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
313 |
314 | contentItem: Rectangle {
315 | implicitHeight: 8
316 | implicitWidth: 100
317 | radius: height / 2
318 | color: scroll1.pressed ? accentOpacityColor
319 | : accentOpacityHoverColor
320 | }
321 | height: 8
322 | background: Item {
323 |
324 | }
325 | }
326 |
327 | model: pictureList.length
328 |
329 |
330 | delegate: Rectangle {
331 | implicitWidth: 85
332 | implicitHeight: 85
333 | Image {
334 | anchors.fill:parent
335 | anchors.margins: 6
336 | antialiasing: true
337 | fillMode: Image.PreserveAspectFit
338 | source: pictureList[index]
339 | }
340 | border.color: view.currentIndex == index ? accentContrlColor : "transparent"
341 | color: tingeOpacityLightColor
342 | radius: 3
343 |
344 | MouseArea {
345 | anchors.fill: parent
346 | onClicked: view.currentIndex = index
347 | }
348 | Component.onCompleted: console.log("pictureList[index]",pictureList[index])
349 | }
350 |
351 |
352 |
353 | }
354 | }
355 | }
356 |
357 | }
358 |
359 |
360 |
361 | function fileGroupPressed(index) {
362 | switch (index) {
363 | case 0 : fileDialog.open(); break;
364 | case 1 : openNewImageAndUpdateScroll(pictureIndex - 1); break;
365 | case 2 : openNewImageAndUpdateScroll(pictureIndex + 1); break;
366 | }
367 | }
368 |
369 |
370 | function setCtrlValue(index, value) {
371 | switch (index) {
372 | case 0 : photoImage.scale = value / 100; break;
373 | case 1 : photoImage.rotation = value; break;
374 | }
375 | }
376 |
377 |
378 |
379 | function openNewImageAndUpdateScroll(index) {
380 | if (index < 0 || index >= pictureList.length) {
381 | return false
382 | }
383 | pictureIndex = index
384 | view.positionViewAtIndex( pictureIndex, ListView.Beginning)
385 |
386 | return true
387 | }
388 |
389 |
390 | }
391 |
--------------------------------------------------------------------------------
/preview/linux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/preview/linux.png
--------------------------------------------------------------------------------
/preview/windwos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/preview/windwos.png
--------------------------------------------------------------------------------
/qianWindow.pro:
--------------------------------------------------------------------------------
1 | QT += quick
2 | QT += quickcontrols2
3 | QT += widgets
4 |
5 | CONFIG += c++11
6 | CONFIG += resources_big
7 | # The following define makes your compiler emit warnings if you use
8 | # any Qt feature that has been marked deprecated (the exact warnings
9 | # depend on your compiler). Refer to the documentation for the
10 | # deprecated API to know how to port your code away from it.
11 | DEFINES += QT_DEPRECATED_WARNINGS
12 |
13 | # You can also make your code fail to compile if it uses deprecated APIs.
14 | # In order to do so, uncomment the following line.
15 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
16 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
17 |
18 | SOURCES += \
19 | main.cpp \
20 | pages/QianProjectPages/QianDragViewPage/qiandrageventcatch.cpp \
21 |
22 | RESOURCES += qml.qrc
23 | include(./common/Frameless/frameless.pri)
24 | include(./common/Backed/Backed.pri)
25 |
26 |
27 | #INCLUDEPATH += $$PWD/pages/QianProjectPages/QianDragViewPage
28 |
29 | win32 {
30 | RC_FILE += ./windowRes/Icon.rc
31 | }
32 |
33 |
34 | # Additional import path used to resolve QML modules in Qt Creator's code model
35 | QML_IMPORT_PATH =
36 |
37 | # Additional import path used to resolve QML modules just for Qt Quick Designer
38 | QML_DESIGNER_IMPORT_PATH =
39 |
40 | # Default rules for deployment.
41 | qnx: target.path = /tmp/$${TARGET}/bin
42 | else: unix:!android: target.path = /opt/$${TARGET}/bin
43 | !isEmpty(target.path): INSTALLS += target
44 |
45 | HEADERS += \
46 | pages/QianProjectPages/QianDragViewPage/qiandrageventcatch.h \
47 |
--------------------------------------------------------------------------------
/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | main.qml
4 | common/SkinModel.qml
5 | ContentList.qml
6 | LeftSidebar.qml
7 | WindowEntry.qml
8 | WindowTilte.qml
9 | common/SkinImageButton.qml
10 | common/ImageButton.qml
11 | common/ScaleImageButton.qml
12 | common/Sidebar.qml
13 | common/BaseToolTip.qml
14 | common/YaheiText.qml
15 | common/BaseSlider.qml
16 | windowRes/close.png
17 | windowRes/close_hover.png
18 | windowRes/close2.png
19 | windowRes/icon.png
20 | windowRes/max.png
21 | windowRes/minimize.png
22 | windowRes/normal.png
23 | windowRes/skin.png
24 | InputPage.qml
25 | common/BaseButton.qml
26 | common/SkinPopup.qml
27 | common/SkinBaseButton.qml
28 | PageManager.qml
29 | pages/BaseControlPage.qml
30 | common/SkinBaseButton2.qml
31 | pages/BaseOtherControlPage.qml
32 | common/DropPopup.qml
33 | common/BaseCheckBox.qml
34 | common/qmlQianStretchList/QianStretchDalegate.qml
35 | common/qmlQianStretchList/QianStretchEntry.qml
36 | common/qmlQianStretchList/icons/indicator_right.png
37 | pages/QianProjectPages/QianPhotoPage.qml
38 | pages/QianProjectPages/QianMergeWatermelonPage/Ball.qml
39 | pages/QianProjectPages/QianMergeWatermelonPage/BallRun.js
40 | pages/QianProjectPages/QianMergeWatermelonPage/FinishWindow.qml
41 | pages/QianProjectPages/QianMergeWatermelonPage/GameCanvas.qml
42 | pages/QianProjectPages/QianMergeWatermelonPage/MergeAnimal.qml
43 | pages/QianProjectPages/QianMergeWatermelonPage/QianMergeWatermelonPage.qml
44 | pages/QianProjectPages/QianMergeWatermelonPage/ScoreNumber.qml
45 | pages/QianProjectPages/QianMergeWatermelonPage/audio/d2cb5a4f-1334-4eab-8578-a76aa028644e.mp3
46 | pages/QianProjectPages/QianMergeWatermelonPage/audio/down.mp3
47 | pages/QianProjectPages/QianMergeWatermelonPage/audio/down.wav
48 | pages/QianProjectPages/QianMergeWatermelonPage/audio/finish.mp3
49 | pages/QianProjectPages/QianMergeWatermelonPage/audio/finish.wav
50 | pages/QianProjectPages/QianMergeWatermelonPage/audio/merge1.mp3
51 | pages/QianProjectPages/QianMergeWatermelonPage/audio/merge1.wav
52 | pages/QianProjectPages/QianMergeWatermelonPage/audio/merge2.mp3
53 | pages/QianProjectPages/QianMergeWatermelonPage/audio/merge2.wav
54 | pages/QianProjectPages/QianMergeWatermelonPage/icon/1.png
55 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball1.png
56 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball2.png
57 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball3.png
58 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball4.png
59 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball5.png
60 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball6.png
61 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball7.png
62 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball8.png
63 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball9.png
64 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball10.png
65 | pages/QianProjectPages/QianMergeWatermelonPage/icon/ball11.png
66 | pages/QianProjectPages/QianMergeWatermelonPage/icon/bottomBack.png
67 | pages/QianProjectPages/QianMergeWatermelonPage/icon/finish.png
68 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge2.png
69 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge3.png
70 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge4.png
71 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge5.png
72 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge6.png
73 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge7.png
74 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge8.png
75 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge9.png
76 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge10.png
77 | pages/QianProjectPages/QianMergeWatermelonPage/icon/merge11.png
78 | pages/QianProjectPages/QianMergeWatermelonPage/icon/number1.png
79 | pages/QianProjectPages/QianDragViewPage/QianDragDelegate.qml
80 | pages/QianProjectPages/QianDragViewPage/QianDragDelegateInformation.qml
81 | pages/QianProjectPages/QianDragViewPage/QianDragView.qml
82 | pages/QianProjectPages/QianDragViewPage/QianDragViewPage.qml
83 | pages/QianProjectPages/QianDragViewPage/remove.png
84 | common/BaseTextField.qml
85 | common/qmlQianHints/error.png
86 | common/qmlQianHints/Message.qml
87 | common/qmlQianHints/remind.png
88 | common/qmlQianHints/true.png
89 | common/qmlQianDialog/info.png
90 | common/qmlQianDialog/SkinQianDialog.qml
91 | common/qmlQianHints/QianQuestionMark.qml
92 | common/qmlQianHints/questionMark.png
93 | common/qmlQianHints/questionMarkDarker.png
94 | common/qmlQianDialog/error.png
95 | common/qmlQianDialog/ok.png
96 | common/qmlQianDialog/question.png
97 | pages/HintPage.qml
98 | common/qmlQianDialog/BlogDialog.qml
99 |
100 |
101 |
--------------------------------------------------------------------------------
/windowRes/Icon.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON DISCARDABLE "icon.ico"
2 |
--------------------------------------------------------------------------------
/windowRes/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/close.png
--------------------------------------------------------------------------------
/windowRes/close2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/close2.png
--------------------------------------------------------------------------------
/windowRes/close_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/close_hover.png
--------------------------------------------------------------------------------
/windowRes/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/icon.ico
--------------------------------------------------------------------------------
/windowRes/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/icon.png
--------------------------------------------------------------------------------
/windowRes/max.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/max.png
--------------------------------------------------------------------------------
/windowRes/minimize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/minimize.png
--------------------------------------------------------------------------------
/windowRes/normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/normal.png
--------------------------------------------------------------------------------
/windowRes/skin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nuoqian-lgtm/QianWindow/91d2685f78defaf77bc8ccb5490a17e3ba14291a/windowRes/skin.png
--------------------------------------------------------------------------------