mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-01 15:42:20 +08:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
e2cefb6114 | |||
bdf4da81dd | |||
f4cebb5c14 | |||
88b15b92ea | |||
d43e661388 | |||
5df0efbc58 | |||
818b588daa | |||
3fbd494724 | |||
b864be5f67 | |||
a81e7958c5 | |||
b1d57c43c4 | |||
02adfb4b0e | |||
97e0d614d0 | |||
46caf288d8 | |||
aceb3fee7b |
37
.github/workflows/ubuntu.yml
vendored
37
.github/workflows/ubuntu.yml
vendored
@ -1,6 +1,7 @@
|
||||
name: Ubuntu
|
||||
# Qt官方没有linux平台的x86包
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '*.pro'
|
||||
@ -20,11 +21,8 @@ jobs:
|
||||
os: [ubuntu-18.04,ubuntu-20.04]
|
||||
qt_ver: [5.15.2]
|
||||
qt_arch: [gcc_64]
|
||||
exclude:
|
||||
# Qt6.2.2 need GLIBC_2.28, ubuntu 18.04 have not.
|
||||
- os: ubuntu-18.04
|
||||
qt_ver: 6.2.2
|
||||
qt_arch: gcc_64
|
||||
env:
|
||||
targetName: example
|
||||
steps:
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
@ -32,7 +30,7 @@ jobs:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
cached: 'false'
|
||||
- name: ubuntu install GL library
|
||||
run: sudo apt-get install -y libglew-dev libglfw3-dev
|
||||
run: sudo apt-get install -y libglew-dev libglfw3-dev qml-module-qtquick-controls qml-module-qtquick-controls2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
@ -40,3 +38,30 @@ jobs:
|
||||
run: |
|
||||
qmake
|
||||
make
|
||||
- name: install QT linux deploy
|
||||
uses: miurahr/install-linuxdeploy-action@v1
|
||||
with:
|
||||
plugins: qt appimage
|
||||
# 打包
|
||||
- name: package
|
||||
run: |
|
||||
# make sure Qt plugin finds QML sources so it can deploy the imported files
|
||||
export QML_SOURCES_PATHS=src
|
||||
# 拷贝依赖
|
||||
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=bin/release/${targetName} --appdir bin/release/
|
||||
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}.AppImage
|
||||
# 上传artifacts
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}
|
||||
path: ${{ env.targetName }}.AppImage
|
||||
# tag 上传Release
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ env.targetName }}.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ matrix.os }}_${{ matrix.qt_ver }}.AppImage
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
3
.github/workflows/windows-mingw.yml
vendored
3
.github/workflows/windows-mingw.yml
vendored
@ -27,6 +27,7 @@ jobs:
|
||||
qt_tools_mingw_install: mingw810_64
|
||||
env:
|
||||
targetName: example.exe
|
||||
fileName: example
|
||||
steps:
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
@ -65,7 +66,7 @@ jobs:
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ matrix.qt_ver }}-${{ matrix.qt_target }}-${{ matrix.qt_arch }}
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_ver }}-${{ matrix.qt_arch }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
|
3
.github/workflows/windows.yml
vendored
3
.github/workflows/windows.yml
vendored
@ -32,6 +32,7 @@ jobs:
|
||||
qt_arch_install: msvc2019_64
|
||||
env:
|
||||
targetName: example.exe
|
||||
fileName: example
|
||||
# 步骤
|
||||
steps:
|
||||
# 安装Qt
|
||||
@ -66,7 +67,7 @@ jobs:
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ matrix.qt_ver }}-${{ matrix.qt_target }}-${{ matrix.qt_arch }}
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_ver }}-${{ matrix.qt_arch }}
|
||||
msvcArch: ${{ matrix.msvc_arch }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
15
README.md
15
README.md
@ -4,12 +4,11 @@
|
||||
|
||||
这是一个漂亮的Fluent组件库,使用QML插件开发的
|
||||
|
||||
## status
|
||||
## 编译状态
|
||||
| [Windows][win-link]| [Ubuntu][ubuntu-link]|[MacOS][macos-link]|
|
||||
|---------------|---------------|-----------------|
|
||||
| ![win-badge] | ![ubuntu-badge] | ![macos-badge] |
|
||||
|
||||
|
||||
[win-link]: https://github.com/zhuzichu520/FluentUI/actions?query=workflow%3AWindows "WindowsAction"
|
||||
[win-badge]: https://github.com/zhuzichu520/FluentUI/workflows/Windows/badge.svg "Windows"
|
||||
|
||||
@ -19,6 +18,18 @@
|
||||
[macos-link]: https://github.com/zhuzichu520/FluentUI/actions?query=workflow%3AMacOS "MacOSAction"
|
||||
[macos-badge]: https://github.com/zhuzichu520/FluentUI/workflows/MacOS/badge.svg "MacOS"
|
||||
|
||||
## 发布
|
||||
|
||||
|[已发布][release-link]|[下载][download-link]|下载次数|
|
||||
|:--:|:--:|:--:|
|
||||
|![release-badge] |![download-badge]|![download-latest]|
|
||||
|
||||
[release-link]: https://github.com/zhuzichu520/FluentUI/releases "Release status"
|
||||
[release-badge]: https://img.shields.io/github/release/zhuzichu520/FluentUI.svg?style=flat-square "Release status"
|
||||
[download-link]: https://github.com/zhuzichu520/FluentUI/releases/latest "Download status"
|
||||
[download-badge]: https://img.shields.io/github/downloads/zhuzichu520/FluentUI/total.svg "Download status"
|
||||
[download-latest]: https://img.shields.io/github/downloads/zhuzichu520/FluentUI/latest/total.svg "latest status"
|
||||
|
||||
## 支持的组件
|
||||
|
||||
|目录|说明|备注|
|
||||
|
1
example.svg
Normal file
1
example.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1678260749060" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11227" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M0 0m170.663111 0l682.652445 0q170.663111 0 170.663111 170.663111l0 682.652445q0 170.663111-170.663111 170.663111l-682.652445 0q-170.663111 0-170.663111-170.663111l0-682.652445q0-170.663111 170.663111-170.663111Z" fill="#EBF2FF" p-id="11228"></path><path d="M512.351993 787.674257c182.822858 0 330.926439 98.568613 331.033103 231.312514 0 1.674632-0.031999 3.338597-0.106664 5.002563H181.43622c-0.074665-1.663965-0.106664-3.327931-0.106664-5.002563 0-132.743901 148.210246-231.312514 331.022437-231.312514z" fill="#7D99C8" p-id="11229"></path><path d="M592.264994 721.158309v79.817004h-0.810649c-5.546551 30.079373-38.847191 53.204225-79.102352 53.204225-40.244495 0-73.545134-23.114185-79.091686-53.193559h-0.81065V721.158309h159.815337z" fill="#FBDBCB" p-id="11230"></path><path d="M508.213412 765.626716c-44.105748-1.226641-85.363555-19.306264-118.568196-56.916147-22.826191-25.866128-35.199267-53.054895-37.097894-81.576968l-21.610217-1.610633a59.988084 59.988084 0 0 1-55.433511-56.585488l-0.319994-5.72788a34.932606 34.932606 0 0 1 43.124435-35.839254l0.949314-9.098477a608.008666 608.008666 0 0 1 40.031166-159.015354l10.389117-25.866127H655.026354l10.389117 25.866127a608.008666 608.008666 0 0 1 40.031166 159.015354l0.95998 9.098477a34.932606 34.932606 0 0 1 43.103102 35.839254l-0.309327 5.72788a59.988084 59.988084 0 0 1-55.433512 56.585488l-21.610217 1.610633c-1.909294 28.522072-14.271703 55.710839-37.097893 81.576968-34.239287 38.793858-77.054395 56.798817-122.717444 56.980146z" fill="#FFE7DB" p-id="11231"></path><path d="M546.911273 182.822858a10.666444 10.666444 0 0 1 1.429303 4.31991c0.533322 5.055895 0.714652 9.226474 0.533322 12.501073l-0.202662 2.346618 3.221266-0.543989c21.876878-3.733256 38.452532-9.877128 49.705631-18.452949l2.197288-1.73863a10.666444 10.666444 0 0 1 16.682319 3.98925c8.767817 20.650236 11.125102 40.681819 7.039853 60.116081l-0.373325 1.578633c4.746568 1.514635 9.589134 3.199933 14.506364 5.066562 27.882086 10.581113 57.769463 26.367451 76.883732 75.65709 20.212912 52.084248 18.826274 116.562905-4.149247 193.425304l-1.855961 6.101206H701.425387c-0.47999-51.732256-8.319827-90.526114-23.540843-116.392242-15.221016-25.866128-29.716714-46.185704-43.487094-60.969396-41.513802 10.399783-79.85967 15.914335-115.037603 16.564988l-6.997188 0.063998v0.191996c-37.065894 0-77.737047-5.546551-122.024124-16.628986-13.77038 10.954438-28.266078 31.220683-43.487094 60.7774-15.221016 29.556718-23.060853 68.414575-23.540843 116.584238h-11.114435c-24.746151-79.571676-26.740776-146.076957-6.005209-199.52651 8.746484-22.548864 19.732922-38.079207 31.764672-49.321639 18.079623-20.660903 40.180496-36.009916 66.302619-46.068374a424.716485 424.716485 0 0 1 32.319326-11.029103c25.25814-9.034478 44.991063-16.767651 59.209433-23.210183a366.221704 366.221704 0 0 0 29.151393-14.869024l7.359847-4.266578a10.666444 10.666444 0 0 1 14.623695 3.733256z" fill="#7D99C8" p-id="11232"></path></svg>
|
After Width: | Height: | Size: 3.2 KiB |
@ -6,8 +6,11 @@ FluWindow {
|
||||
|
||||
width: 500
|
||||
height: 600
|
||||
minimumWidth: 300
|
||||
minimumHeight: 400
|
||||
minimumWidth: 500
|
||||
minimumHeight: 600
|
||||
maximumWidth: 500
|
||||
maximumHeight: 600
|
||||
|
||||
title:"关于"
|
||||
|
||||
FluAppBar{
|
||||
@ -31,7 +34,7 @@ FluWindow {
|
||||
fontStyle: FluText.Title
|
||||
}
|
||||
FluText{
|
||||
text:"v1.0.0"
|
||||
text:"v1.0.2"
|
||||
fontStyle: FluText.Body
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ FluWindow {
|
||||
id:appbar
|
||||
title: "FluentUI"
|
||||
showDark: true
|
||||
showFps: true
|
||||
}
|
||||
|
||||
ListModel{
|
||||
@ -55,6 +54,10 @@ FluWindow {
|
||||
text:"Rectangle"
|
||||
page:"qrc:/T_Rectangle.qml"
|
||||
}
|
||||
ListElement{
|
||||
text:"Expander"
|
||||
page:"qrc:/T_Expander.qml"
|
||||
}
|
||||
ListElement{
|
||||
text:"TreeView"
|
||||
page:"qrc:/T_TreeView.qml"
|
||||
@ -88,7 +91,7 @@ FluWindow {
|
||||
FluMenuItem{
|
||||
text:"意见反馈"
|
||||
onClicked:{
|
||||
showInfo("正在建设中...")
|
||||
Qt.openUrlExternally("https://github.com/zhuzichu520/FluentUI/issues/new")
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
@ -111,6 +114,7 @@ FluWindow {
|
||||
topMargin: 20
|
||||
bottomMargin: 52
|
||||
}
|
||||
ScrollBar.vertical: ScrollBar { }
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
clip: true
|
||||
width: 160
|
||||
|
@ -127,6 +127,30 @@ Item {
|
||||
text:"Disabled"
|
||||
}
|
||||
}
|
||||
FluDivider{
|
||||
Layout.fillWidth: true ; height:1
|
||||
}
|
||||
RowLayout{
|
||||
Layout.topMargin: 20
|
||||
width: parent.width
|
||||
FluCheckBox{
|
||||
disabled:icon_button_check.checked
|
||||
}
|
||||
Item{
|
||||
height: 1
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id:icon_button_check
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
FluText{
|
||||
text:"Disabled"
|
||||
}
|
||||
}
|
||||
FluDivider{
|
||||
Layout.fillWidth: true ; height:1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
78
example/T_Expander.qml
Normal file
78
example/T_Expander.qml
Normal file
@ -0,0 +1,78 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtGraphicalEffects 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
FluText{
|
||||
id:title
|
||||
text:"Expander"
|
||||
fontStyle: FluText.TitleLarge
|
||||
}
|
||||
ScrollView{
|
||||
clip: true
|
||||
width: parent.width
|
||||
contentWidth: parent.width
|
||||
anchors{
|
||||
top: title.bottom
|
||||
bottom: parent.bottom
|
||||
}
|
||||
Column{
|
||||
spacing: 5
|
||||
Item{
|
||||
width: 1
|
||||
height: 20
|
||||
}
|
||||
FluExpander{
|
||||
headerText:"打开一个单选框"
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
spacing: 8
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: 15
|
||||
leftMargin: 15
|
||||
}
|
||||
Repeater{
|
||||
id:repeater
|
||||
property int selecIndex : 0
|
||||
model: 3
|
||||
delegate: FluRadioButton{
|
||||
checked : repeater.selecIndex===index
|
||||
text:"RodioButton_"+index
|
||||
onClicked:{
|
||||
repeater.selecIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluExpander{
|
||||
Layout.topMargin: 20
|
||||
headerText:"打开一个滑动文本框"
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
ScrollView{
|
||||
id:scrollview
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
contentWidth: parent.width
|
||||
FluText{
|
||||
id:test
|
||||
width: scrollview.width
|
||||
wrapMode: Text.WrapAnywhere
|
||||
padding: 14
|
||||
text:"先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。宫中府中,俱为一体;陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明;故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏。臣不胜受恩感激。今当远离,临表涕零,不知所言。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,12 @@ Item {
|
||||
Layout.leftMargin: 15
|
||||
value: 50
|
||||
}
|
||||
FluSlider{
|
||||
orientation:FluSlider.Vertical
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 15
|
||||
value: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,33 @@ Item {
|
||||
Layout.preferredWidth: 300
|
||||
placeholderText: "多行输入框"
|
||||
}
|
||||
FluAutoSuggestBox{
|
||||
Layout.topMargin: 20
|
||||
values:generateRandomNames(100)
|
||||
placeholderText: "AutoSuggestBox"
|
||||
Layout.preferredWidth: 300
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateRandomNames(numNames) {
|
||||
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const names = [];
|
||||
function generateRandomName() {
|
||||
const nameLength = Math.floor(Math.random() * 5) + 4;
|
||||
let name = '';
|
||||
for (let i = 0; i < nameLength; i++) {
|
||||
const letterIndex = Math.floor(Math.random() * 26);
|
||||
name += alphabet.charAt(letterIndex);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
for (let i = 0; i < numNames; i++) {
|
||||
const name = generateRandomName();
|
||||
names.push(name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -59,6 +59,17 @@ Item {
|
||||
FluTheme.isDark = !FluTheme.isDark
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:"无边框"
|
||||
fontStyle: FluText.Subtitle
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluToggleSwitch{
|
||||
checked: FluTheme.isFrameless
|
||||
onClickFunc:function(){
|
||||
FluTheme.isFrameless = !FluTheme.isFrameless
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include <QDir>
|
||||
#include <QQuickWindow>
|
||||
#include <QProcess>
|
||||
|
||||
QMap<QString, QVariant> properties(){
|
||||
@ -16,6 +17,7 @@ int main(int argc, char *argv[])
|
||||
QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io");
|
||||
QCoreApplication::setApplicationName("FluentUI");
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
// QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
|
||||
QGuiApplication app(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
QMapIterator<QString, QVariant> iterator(properties());
|
||||
|
@ -29,5 +29,6 @@
|
||||
<file>T_Theme.qml</file>
|
||||
<file>T_Dialog.qml</file>
|
||||
<file>T_TreeView.qml</file>
|
||||
<file>T_Expander.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -59,7 +59,7 @@ void FluApp::navigate(const QString& route){
|
||||
view->setSource((routes().value(route).toString()));
|
||||
if(isAppWindow){
|
||||
QObject::connect(view->engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
|
||||
QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view](){view->setSource({});});
|
||||
// QObject::connect(qApp, &QGuiApplication::aboutToQuit, qApp, [&view](){view->setSource({});});
|
||||
}else{
|
||||
view->closeDeleteLater();
|
||||
}
|
||||
|
@ -16,5 +16,6 @@ FluTheme::FluTheme(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
primaryColor(FluColors::getInstance()->Blue());
|
||||
isFrameless(true);
|
||||
isDark(false);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ class FluTheme : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(FluColorSet*,primaryColor)
|
||||
Q_PROPERTY_AUTO(bool,isFrameless);
|
||||
Q_PROPERTY_AUTO(bool,isDark);
|
||||
public:
|
||||
explicit FluTheme(QObject *parent = nullptr);
|
||||
|
@ -33,6 +33,8 @@ void Fluent::registerTypes(const char *uri){
|
||||
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper");
|
||||
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
|
||||
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluAutoSuggestBox.qml"),uri,major,minor,"FluAutoSuggestBox");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluExpander.qml"),uri,major,minor,"FluExpander");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTreeView.qml"),uri,major,minor,"FluTreeView");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentDialog.qml"),uri,major,minor,"FluContentDialog");
|
||||
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenuItem.qml"),uri,major,minor,"FluMenuItem");
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
void closeDeleteLater();
|
||||
bool isMax() const;
|
||||
bool isFull() const;
|
||||
void refreshWindow();
|
||||
QQuickItem *titleItem() const;
|
||||
|
||||
static QMap<WId,FramelessView*> *windowCache;
|
||||
@ -38,6 +39,7 @@ signals:
|
||||
protected:
|
||||
void showEvent(QShowEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
bool event(QEvent *ev) override;
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
# else
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
#include <FluTheme.h>
|
||||
|
||||
class FramelessViewPrivate
|
||||
{
|
||||
@ -12,10 +13,10 @@ public:
|
||||
bool m_deleteLater = false;
|
||||
QQuickItem *m_titleItem = nullptr;
|
||||
};
|
||||
|
||||
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
|
||||
{
|
||||
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
refreshWindow();
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
@ -23,15 +24,31 @@ FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessVi
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
connect(FluTheme::getInstance(),&FluTheme::isFramelessChanged,this,[=](){
|
||||
refreshWindow();
|
||||
});
|
||||
}
|
||||
|
||||
void FramelessView::refreshWindow(){
|
||||
if(FluTheme::getInstance()->isFrameless()){
|
||||
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
}else{
|
||||
setFlags(Qt::Window);
|
||||
}
|
||||
setResizeMode(SizeViewToRootObject);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
}
|
||||
|
||||
FramelessView::~FramelessView()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void FramelessView::showEvent(QShowEvent *e)
|
||||
{
|
||||
Super::showEvent(e);
|
||||
}
|
||||
|
||||
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
@ -46,9 +63,9 @@ QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSi
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
|
||||
return { x, y, w, h };
|
||||
}
|
||||
|
||||
void FramelessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
@ -58,6 +75,7 @@ void FramelessView::moveToScreenCenter()
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
|
||||
void FramelessView::closeDeleteLater(){
|
||||
d->m_deleteLater = true;
|
||||
}
|
||||
@ -66,14 +84,17 @@ bool FramelessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
|
||||
bool FramelessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
|
||||
QQuickItem *FramelessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
|
||||
void FramelessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
@ -82,6 +103,7 @@ void FramelessView::setIsMax(bool isMax)
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
|
||||
void FramelessView::setIsFull(bool isFull)
|
||||
{
|
||||
if(d->m_isFull == isFull)
|
||||
@ -90,6 +112,7 @@ void FramelessView::setIsFull(bool isFull)
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
|
||||
void FramelessView::setTitleItem(QQuickItem *item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
@ -107,3 +130,15 @@ void FramelessView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Super::resizeEvent(e);
|
||||
}
|
||||
|
||||
bool FramelessView::event(QEvent *ev)
|
||||
{
|
||||
if (ev->type() == QEvent::Close) {
|
||||
if(d->m_deleteLater){
|
||||
deleteLater();
|
||||
ev->setAccepted(false);
|
||||
}
|
||||
}
|
||||
return QQuickWindow::event(ev);
|
||||
}
|
||||
|
||||
|
@ -3,27 +3,7 @@
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
#include <VersionHelpers.h>
|
||||
#include <WinUser.h>
|
||||
#include <dwmapi.h>
|
||||
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <wtypes.h>
|
||||
#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved
|
||||
#pragma comment(lib, "User32.lib")
|
||||
#pragma comment(lib, "Gdi32.lib")
|
||||
|
||||
static bool isMaxWin(QWindow* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowMaximized;
|
||||
}
|
||||
static bool isFullWin(QQuickView* win)
|
||||
{
|
||||
return win->windowState() == Qt::WindowFullScreen;
|
||||
}
|
||||
|
||||
#include <FluTheme.h>
|
||||
|
||||
class FramelessViewPrivate
|
||||
{
|
||||
@ -33,10 +13,10 @@ public:
|
||||
bool m_deleteLater = false;
|
||||
QQuickItem *m_titleItem = nullptr;
|
||||
};
|
||||
|
||||
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
|
||||
{
|
||||
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
refreshWindow();
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
|
||||
@ -44,15 +24,31 @@ FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessVi
|
||||
setIsMax(windowState() == Qt::WindowMaximized);
|
||||
setIsFull(windowState() == Qt::WindowFullScreen);
|
||||
});
|
||||
connect(FluTheme::getInstance(),&FluTheme::isFramelessChanged,this,[=](){
|
||||
refreshWindow();
|
||||
});
|
||||
}
|
||||
|
||||
void FramelessView::refreshWindow(){
|
||||
if(FluTheme::getInstance()->isFrameless()){
|
||||
setFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
}else{
|
||||
setFlags(Qt::Window);
|
||||
}
|
||||
setResizeMode(SizeViewToRootObject);
|
||||
setResizeMode(SizeRootObjectToView);
|
||||
}
|
||||
|
||||
FramelessView::~FramelessView()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void FramelessView::showEvent(QShowEvent *e)
|
||||
{
|
||||
Super::showEvent(e);
|
||||
}
|
||||
|
||||
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
|
||||
{
|
||||
int w = normalSize.width();
|
||||
@ -67,9 +63,9 @@ QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSi
|
||||
y = screenGeo.y();
|
||||
h = screenGeo.height();
|
||||
}
|
||||
|
||||
return { x, y, w, h };
|
||||
}
|
||||
|
||||
void FramelessView::moveToScreenCenter()
|
||||
{
|
||||
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
|
||||
@ -79,6 +75,7 @@ void FramelessView::moveToScreenCenter()
|
||||
setGeometry(geo);
|
||||
update();
|
||||
}
|
||||
|
||||
void FramelessView::closeDeleteLater(){
|
||||
d->m_deleteLater = true;
|
||||
}
|
||||
@ -87,14 +84,17 @@ bool FramelessView::isMax() const
|
||||
{
|
||||
return d->m_isMax;
|
||||
}
|
||||
|
||||
bool FramelessView::isFull() const
|
||||
{
|
||||
return d->m_isFull;
|
||||
}
|
||||
|
||||
QQuickItem *FramelessView::titleItem() const
|
||||
{
|
||||
return d->m_titleItem;
|
||||
}
|
||||
|
||||
void FramelessView::setIsMax(bool isMax)
|
||||
{
|
||||
if (d->m_isMax == isMax)
|
||||
@ -103,6 +103,7 @@ void FramelessView::setIsMax(bool isMax)
|
||||
d->m_isMax = isMax;
|
||||
emit isMaxChanged(d->m_isMax);
|
||||
}
|
||||
|
||||
void FramelessView::setIsFull(bool isFull)
|
||||
{
|
||||
if(d->m_isFull == isFull)
|
||||
@ -111,6 +112,7 @@ void FramelessView::setIsFull(bool isFull)
|
||||
d->m_isFull = isFull;
|
||||
emit isFullChanged(d->m_isFull);
|
||||
}
|
||||
|
||||
void FramelessView::setTitleItem(QQuickItem *item)
|
||||
{
|
||||
d->m_titleItem = item;
|
||||
@ -121,43 +123,16 @@ bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qint
|
||||
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
#if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1))
|
||||
// Work-around a bug caused by typo which only exists in Qt 5.11.1
|
||||
const auto msg = *reinterpret_cast<MSG**>(message);
|
||||
#else
|
||||
const auto msg = static_cast<LPMSG>(message);
|
||||
#endif
|
||||
if (!msg || !msg->hwnd)
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
if (msg->message == WM_WINDOWPOSCHANGING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_NCCALCSIZE: {
|
||||
const auto mode = static_cast<BOOL>(msg->wParam);
|
||||
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
|
||||
if (mode == TRUE)
|
||||
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(msg->lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
*result = WVR_REDRAW;
|
||||
//规避 拖动border进行resize时界面闪烁
|
||||
if (!isMaxWin(this) && !isFullWin(this))
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top -= 0.1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientRect->top != 0)
|
||||
{
|
||||
clientRect->top += 0.1;
|
||||
}
|
||||
}
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = 0;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Super::nativeEvent(eventType, message, result);
|
||||
}
|
||||
@ -166,3 +141,15 @@ void FramelessView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
Super::resizeEvent(e);
|
||||
}
|
||||
|
||||
bool FramelessView::event(QEvent *ev)
|
||||
{
|
||||
if (ev->type() == QEvent::Close) {
|
||||
if(d->m_deleteLater){
|
||||
deleteLater();
|
||||
ev->setAccepted(false);
|
||||
}
|
||||
}
|
||||
return QQuickWindow::event(ev);
|
||||
}
|
||||
|
||||
|
@ -13,13 +13,15 @@ Rectangle{
|
||||
return borerlessColor
|
||||
return Window.window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1)
|
||||
}
|
||||
height: 50
|
||||
visible: FluTheme.isFrameless
|
||||
height: visible ? 50 : 0
|
||||
width: {
|
||||
if(parent==null)
|
||||
return 200
|
||||
return parent.width
|
||||
}
|
||||
z: 65535
|
||||
clip: true
|
||||
property string title: "标题"
|
||||
property color textColor: FluTheme.isDark ? "#000000" : "#FFFFFF"
|
||||
property bool showDark: false
|
||||
|
134
src/controls/FluAutoSuggestBox.qml
Normal file
134
src/controls/FluAutoSuggestBox.qml
Normal file
@ -0,0 +1,134 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
TextField{
|
||||
id:input
|
||||
width: 300
|
||||
property var values:[]
|
||||
color: FluTheme.isDark ? "#FFFFFF" : "#1A1A1A"
|
||||
selectionColor: {
|
||||
if(FluTheme.isDark){
|
||||
return FluTheme.primaryColor.lighter
|
||||
}else{
|
||||
return FluTheme.primaryColor.dark
|
||||
}
|
||||
}
|
||||
rightPadding: 30
|
||||
selectByMouse: true
|
||||
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: input
|
||||
|
||||
FluIconButton{
|
||||
icon:FluentIcons.FA_close
|
||||
iconSize: 14
|
||||
width: 20
|
||||
height: 20
|
||||
opacity: 0.5
|
||||
visible: input.text !== ""
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
}
|
||||
onClicked:{
|
||||
input.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
searchData()
|
||||
}
|
||||
|
||||
Popup{
|
||||
id:input_popup
|
||||
visible: input.focus
|
||||
y:input.height
|
||||
onClosed: {
|
||||
input.focus = false
|
||||
}
|
||||
background: Rectangle{
|
||||
width: input.width
|
||||
radius: 4
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
color: FluTheme.isDark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(243/255,241/255,240/255,1)
|
||||
height: 38*Math.min(Math.max(list_view.count,1),8)
|
||||
ListView{
|
||||
id:list_view
|
||||
signal closePopup
|
||||
anchors.fill: parent
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
clip: true
|
||||
header: Item{
|
||||
width: input.width
|
||||
height: visible ? 38 : 0
|
||||
visible: list_view.count === 0
|
||||
FluText{
|
||||
text:"没有找到结果"
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
ScrollBar.vertical: ScrollBar { }
|
||||
delegate: Item{
|
||||
height: 38
|
||||
width: input.width
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 2
|
||||
anchors.bottomMargin: 2
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
color: {
|
||||
if(item_mouse.containsMouse){
|
||||
return FluTheme.isDark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(234/255,234/255,234/255,1)
|
||||
}
|
||||
return FluTheme.isDark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(243/255,241/255,240/255,1)
|
||||
}
|
||||
radius: 3
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
input_popup.close()
|
||||
input.text = modelData
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:modelData
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
searchData()
|
||||
}
|
||||
|
||||
function searchData(){
|
||||
var result = []
|
||||
values.map(function(item){
|
||||
if(item.indexOf(input.text)!==-1){
|
||||
result.push(item)
|
||||
}
|
||||
})
|
||||
list_view.model = result
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ Rectangle {
|
||||
property string text: "Standard Button"
|
||||
property int startPadding : 15
|
||||
property int endPadding : 15
|
||||
property int topPadding: 8
|
||||
property int bottomPadding: 8
|
||||
property int topPadding: 5
|
||||
property int bottomPadding: 5
|
||||
property bool disabled: false
|
||||
property color primaryColor : "#0064B0"
|
||||
signal clicked
|
||||
@ -62,9 +62,8 @@ Rectangle {
|
||||
id:button_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !disabled
|
||||
onClicked: {
|
||||
if(disabled)
|
||||
return
|
||||
button.clicked()
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,26 @@ Item {
|
||||
property string text: "Check Box"
|
||||
property var checkClicked
|
||||
property bool hovered: mouse_area.containsMouse
|
||||
|
||||
property bool disabled: false
|
||||
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
property color borderNormalColor: FluTheme.isDark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1)
|
||||
property color borderCheckedColor: FluTheme.isDark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
property color borderHoverColor: FluTheme.isDark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1)
|
||||
property color borderDisableColor: FluTheme.isDark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
|
||||
property color normalColor: FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1)
|
||||
property color checkedColor: FluTheme.isDark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
|
||||
property color hoverColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color checkedHoverColor: FluTheme.isDark ? Qt.darker(checkedColor,1.1) : Qt.lighter(checkedColor,1.1)
|
||||
|
||||
property color checkedDisableColor: FluTheme.isDark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
|
||||
property color disableColor: FluTheme.isDark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1)
|
||||
|
||||
RowLayout{
|
||||
spacing: 4
|
||||
Rectangle{
|
||||
@ -19,46 +36,32 @@ Item {
|
||||
height: 22
|
||||
radius: 4
|
||||
border.color: {
|
||||
if(FluTheme.isDark){
|
||||
if(checked){
|
||||
return FluTheme.primaryColor.lighter
|
||||
}
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}else{
|
||||
if(checked){
|
||||
if(mouse_area.containsMouse){
|
||||
return Qt.rgba(25/255,117/255,187/255,1)
|
||||
}
|
||||
return FluTheme.primaryColor.dark
|
||||
}
|
||||
return Qt.rgba(136/255,136/255,136/255,1)
|
||||
if(disabled){
|
||||
return borderDisableColor
|
||||
}
|
||||
if(checked){
|
||||
return borderCheckedColor
|
||||
}
|
||||
if(hovered){
|
||||
return borderHoverColor
|
||||
}
|
||||
return borderNormalColor
|
||||
}
|
||||
border.width: 1
|
||||
color: {
|
||||
if(FluTheme.isDark){
|
||||
if(checked){
|
||||
if(mouse_area.containsMouse){
|
||||
return Qt.rgba(74/255,149/255,207/255,1)
|
||||
}
|
||||
return FluTheme.primaryColor.lighter
|
||||
if(checked){
|
||||
if(disabled){
|
||||
return checkedDisableColor
|
||||
}
|
||||
if(mouse_area.containsMouse){
|
||||
return Qt.rgba(62/255,62/255,62/255,1)
|
||||
if(hovered){
|
||||
return checkedHoverColor
|
||||
}
|
||||
return Qt.rgba(45/255,45/255,45/255,1)
|
||||
}else{
|
||||
if(checked){
|
||||
if(mouse_area.containsMouse){
|
||||
return Qt.rgba(25/255,117/255,187/255,1)
|
||||
}
|
||||
return FluTheme.primaryColor.dark
|
||||
}
|
||||
if(mouse_area.containsMouse){
|
||||
return Qt.rgba(244/255,244/255,244/255,1)
|
||||
}
|
||||
return Qt.rgba(247/255,247/255,247/255,1)
|
||||
return checkedColor
|
||||
}
|
||||
if(hovered){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
|
||||
FluIcon {
|
||||
@ -79,6 +82,7 @@ Item {
|
||||
id:mouse_area
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !disabled
|
||||
onClicked: {
|
||||
if(checkClicked){
|
||||
checkClicked()
|
||||
|
@ -23,10 +23,12 @@ Popup {
|
||||
anchors.centerIn: Overlay.overlay
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
background: Rectangle {
|
||||
id:layout_content
|
||||
implicitWidth:minWidth
|
||||
implicitHeight: text_title.height + text_message.height + layout_actions.height
|
||||
color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1)
|
||||
radius:5
|
||||
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
|
82
src/controls/FluExpander.qml
Normal file
82
src/controls/FluExpander.qml
Normal file
@ -0,0 +1,82 @@
|
||||
import QtQuick 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
|
||||
|
||||
property string headerText: "Titlte"
|
||||
property bool expand: false
|
||||
|
||||
id:root
|
||||
height: layout_header.height + container.height
|
||||
width: 400
|
||||
|
||||
property int contentHeight : 300
|
||||
|
||||
default property alias content: container.data
|
||||
|
||||
Rectangle{
|
||||
id:layout_header
|
||||
width: parent.width
|
||||
height: 50
|
||||
radius: 4
|
||||
border.color: FluTheme.isDark ? Qt.rgba(53/255,53/255,53/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
color: FluTheme.isDark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
|
||||
|
||||
MouseArea{
|
||||
id:root_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
expand = !expand
|
||||
}
|
||||
}
|
||||
|
||||
FluText{
|
||||
text: headerText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 15
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 15
|
||||
}
|
||||
hoverColor: FluTheme.isDark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(245/255,245/255,245/255,1)
|
||||
normalColor: FluTheme.isDark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
hovered: root_mouse.containsMouse
|
||||
icon: expand ? FluentIcons.FA_angle_up : FluentIcons.FA_angle_down
|
||||
onClicked: {
|
||||
expand = !expand
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rectangle{
|
||||
id:container
|
||||
width: parent.width
|
||||
clip: true
|
||||
anchors{
|
||||
top: layout_header.bottom
|
||||
left: layout_header.left
|
||||
}
|
||||
radius: 4
|
||||
border.color: FluTheme.isDark ? Qt.rgba(53/255,53/255,53/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
color: FluTheme.isDark ? Qt.rgba(57/255,57/255,57/255,1) : Qt.rgba(249/255,249/255,249/255,1)
|
||||
height: expand ? contentHeight : 0
|
||||
Behavior on height {
|
||||
NumberAnimation{
|
||||
duration: 150
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -8,8 +8,8 @@ Rectangle {
|
||||
property string text: "Filled Button"
|
||||
property int startPadding : 15
|
||||
property int endPadding : 15
|
||||
property int topPadding: 8
|
||||
property int bottomPadding: 8
|
||||
property int topPadding: 5
|
||||
property int bottomPadding: 5
|
||||
property bool disabled: false
|
||||
|
||||
signal clicked
|
||||
|
@ -13,6 +13,11 @@ Rectangle {
|
||||
signal clicked
|
||||
property bool disabled: false
|
||||
property bool hovered: button_mouse.containsMouse
|
||||
|
||||
property color hoverColor: FluTheme.isDark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color normalColor: FluTheme.isDark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1)
|
||||
property color disableColor: FluTheme.isDark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(1,1,1,1)
|
||||
|
||||
property color textColor: {
|
||||
if(FluTheme.isDark){
|
||||
if(disabled){
|
||||
@ -29,17 +34,10 @@ Rectangle {
|
||||
radius: 4
|
||||
|
||||
color: {
|
||||
if(FluTheme.isDark){
|
||||
if(disabled){
|
||||
return Qt.rgba(59/255,59/255,59/255,1)
|
||||
}
|
||||
return button_mouse.containsMouse ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(50/255,50/255,50/255,1)
|
||||
}else{
|
||||
if(disabled){
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
return button_mouse.containsMouse ? Qt.rgba(244/255,244/255,244/255,1) : Qt.rgba(1,1,1,1)
|
||||
if(disabled){
|
||||
return disableColor
|
||||
}
|
||||
return (hovered || button_mouse.containsMouse) ? hoverColor : normalColor
|
||||
}
|
||||
|
||||
Text {
|
||||
@ -69,7 +67,7 @@ Rectangle {
|
||||
if(button.text === ""){
|
||||
return false
|
||||
}
|
||||
return button_mouse.containsMouse
|
||||
return (hovered || button_mouse.containsMouse)
|
||||
}
|
||||
delay: 1000
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ Popup {
|
||||
implicitHeight: container.height
|
||||
color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1)
|
||||
radius: 5
|
||||
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import QtQuick.Controls 2.12
|
||||
FluRectangle {
|
||||
id: control
|
||||
|
||||
width: 180
|
||||
height: 6
|
||||
width: 150
|
||||
height: 5
|
||||
radius: [3,3,3,3]
|
||||
clip: true
|
||||
color: FluTheme.isDark ? Qt.rgba(41/255,41/255,41/255,1) : Qt.rgba(214/255,214/255,214/255,1)
|
||||
|
@ -4,13 +4,13 @@ import QtQuick.Controls 2.12
|
||||
Rectangle {
|
||||
id: control
|
||||
|
||||
width: 60
|
||||
height: 60
|
||||
radius: 30
|
||||
width: 44
|
||||
height: 44
|
||||
radius: 22
|
||||
border.width: linWidth
|
||||
color: "#00000000"
|
||||
border.color: FluTheme.isDark ? Qt.rgba(41/255,41/255,41/255,1) : Qt.rgba(214/255,214/255,214/255,1)
|
||||
property real linWidth : 6
|
||||
property real linWidth : 5
|
||||
property real progress: 0.25
|
||||
property bool indeterminate: true
|
||||
readonly property real radius2 : radius - linWidth/2
|
||||
|
@ -6,23 +6,40 @@ Item{
|
||||
|
||||
id:root
|
||||
|
||||
property int lineWidth: 6
|
||||
property int dotSize: 30
|
||||
property int lineWidth: 5
|
||||
property int dotSize: 26
|
||||
property int value: 50
|
||||
|
||||
enum Orientation {
|
||||
Horizontal,
|
||||
Vertical
|
||||
}
|
||||
|
||||
height: control.height
|
||||
width: control.width
|
||||
|
||||
property int orientation: FluSlider.Horizontal
|
||||
|
||||
property bool isHorizontal: orientation === FluSlider.Horizontal
|
||||
|
||||
Component.onCompleted: {
|
||||
dot.x =value/100*control.width - dotSize/2
|
||||
root.value = Qt.binding(function(){
|
||||
return (dot.x+15)/control.width*100
|
||||
})
|
||||
if(isHorizontal){
|
||||
dot.x =value/100*control.width - dotSize/2
|
||||
root.value = Qt.binding(function(){
|
||||
return (dot.x+dotSize/2)/control.width*100
|
||||
})
|
||||
}else{
|
||||
dot.y =value/100*control.height - dotSize/2
|
||||
root.value = Qt.binding(function(){
|
||||
return (dot.y+dotSize/2)/control.height*100
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
FluRectangle {
|
||||
|
||||
id: control
|
||||
|
||||
width: 300
|
||||
height: root.lineWidth
|
||||
width: isHorizontal ? 200 : root.lineWidth
|
||||
height: isHorizontal ? root.lineWidth : 200
|
||||
radius: [3,3,3,3]
|
||||
clip: true
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@ -30,8 +47,8 @@ Item{
|
||||
Rectangle{
|
||||
id:rect
|
||||
radius: 3
|
||||
width: control.width*(value/100)
|
||||
height: control.height
|
||||
width: isHorizontal ? control.width*(value/100) : control.width
|
||||
height: isHorizontal ? control.height : control.height*(value/100)
|
||||
color:FluTheme.isDark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark
|
||||
}
|
||||
}
|
||||
@ -40,11 +57,12 @@ Item{
|
||||
id:dot
|
||||
width: dotSize
|
||||
height: dotSize
|
||||
FluShadow{
|
||||
radius: 15
|
||||
}
|
||||
radius: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
FluShadow{
|
||||
radius: dotSize/2
|
||||
}
|
||||
radius: dotSize/2
|
||||
anchors.verticalCenter: isHorizontal ? parent.verticalCenter : undefined
|
||||
anchors.horizontalCenter: isHorizontal ? undefined :parent.horizontalCenter
|
||||
color:FluTheme.isDark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
|
||||
Rectangle{
|
||||
width: dotSize/2
|
||||
@ -65,9 +83,11 @@ Item{
|
||||
hoverEnabled: true
|
||||
drag {
|
||||
target: dot
|
||||
axis: Drag.XAxis
|
||||
minimumX: -dotSize/2
|
||||
maximumX: control.width - dotSize/2
|
||||
axis: isHorizontal ? Drag.XAxis : Drag.YAxis
|
||||
minimumX: isHorizontal ? -dotSize/2 : 0
|
||||
maximumX: isHorizontal ? (control.width - dotSize/2) : 0
|
||||
minimumY: isHorizontal ? 0 : -dotSize/2
|
||||
maximumY: isHorizontal ? 0 : (control.height - dotSize/2)
|
||||
}
|
||||
onPressed: {
|
||||
tool_tip.visible = true
|
||||
|
@ -22,6 +22,9 @@ Item {
|
||||
property int maximumHeight
|
||||
|
||||
property int borderless:{
|
||||
if(!FluTheme.isFrameless){
|
||||
return 0
|
||||
}
|
||||
if(window === null)
|
||||
return 4
|
||||
if(Window.window.visibility === Window.Maximized){
|
||||
@ -29,6 +32,7 @@ Item {
|
||||
}
|
||||
return 4
|
||||
}
|
||||
|
||||
default property alias content: container.data
|
||||
|
||||
FluWindowResize{
|
||||
@ -46,7 +50,7 @@ Item {
|
||||
color: {
|
||||
if(window === null)
|
||||
return borerlessColor
|
||||
return window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1)
|
||||
return window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1)
|
||||
}
|
||||
border.width: 1
|
||||
anchors.fill: parent
|
||||
|
0
src/macos_install.sh
Normal file → Executable file
0
src/macos_install.sh
Normal file → Executable file
@ -34,5 +34,7 @@
|
||||
<file>controls/FluTextButton.qml</file>
|
||||
<file>controls/FluContentDialog.qml</file>
|
||||
<file>controls/FluTreeView.qml</file>
|
||||
<file>controls/FluExpander.qml</file>
|
||||
<file>controls/FluAutoSuggestBox.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Reference in New Issue
Block a user