FluentUI/example/qml-Qt6/window/MainWindow.qml
朱子楚\zhuzi a6001ea142 update
2024-01-30 20:16:54 +08:00

390 lines
12 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.platform
import FluentUI
import example
import "../component"
import "../global"
import "../viewmodel"
FluWindow {
id:window
title: "FluentUI"
width: 960
height: 600
minimumWidth: 520
minimumHeight: 200
launchMode: FluWindowType.SingleTask
fitsAppBarWindows: true
appBar: FluAppBar {
height: 30
darkText: Lang.dark_mode
showDark: true
darkClickListener:(button)=>handleDarkChanged(button)
closeClickListener: ()=>{dialog_close.open()}
z:7
}
SettingsViewModel{
id:viewmodel_settings
}
FluEvent{
id:event_checkupdate
name: "checkUpdate"
onTriggered: {
checkUpdate(false)
}
}
onFirstVisible: {
timer_tour_delay.restart()
}
Timer{
id:timer_tour_delay
interval: 200
onTriggered: {
tour.open()
}
}
Component.onCompleted: {
checkUpdate(true)
FluEventBus.registerEvent(event_checkupdate)
}
Component.onDestruction: {
FluEventBus.unRegisterEvent(event_checkupdate)
}
SystemTrayIcon {
id:system_tray
visible: true
icon.source: "qrc:/example/res/image/favicon.ico"
tooltip: "FluentUI"
menu: Menu {
MenuItem {
text: "退出"
onTriggered: {
FluApp.exit()
}
}
}
onActivated:
(reason)=>{
if(reason === SystemTrayIcon.Trigger){
window.show()
window.raise()
window.requestActivate()
}
}
}
Timer{
id:timer_window_hide_delay
interval: 150
onTriggered: {
window.hide()
}
}
FluContentDialog{
id:dialog_close
title:"退出"
message:"确定要退出程序吗?"
negativeText:"最小化"
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
onNegativeClicked: {
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
timer_window_hide_delay.restart()
}
positiveText:"退出"
neutralText:"取消"
onPositiveClicked:{
FluApp.exit(0)
}
}
Component{
id:nav_item_right_menu
FluMenu{
id:menu
width: 130
FluMenuItem{
text: "在独立窗口打开"
visible: true
onClicked: {
FluApp.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
}
}
}
}
Flipable{
id:flipable
anchors.fill: parent
property bool flipped: false
property real flipAngle: 0
transform: Rotation {
id: rotation
origin.x: flipable.width/2
origin.y: flipable.height/2
axis { x: 0; y: 1; z: 0 }
angle: flipable.flipAngle
}
states: State {
PropertyChanges { target: flipable; flipAngle: 180 }
when: flipable.flipped
}
transitions: Transition {
NumberAnimation { target: flipable; property: "flipAngle"; duration: 1000 ; easing.type: Easing.OutCubic}
}
back: Item{
anchors.fill: flipable
visible: flipable.flipAngle !== 0
Row{
id:layout_back_buttons
z:8
anchors{
top: parent.top
left: parent.left
topMargin: FluTools.isMacos() ? 20 : 5
leftMargin: 5
}
FluIconButton{
iconSource: FluentIcons.ChromeBack
width: 30
height: 30
iconSize: 13
onClicked: {
flipable.flipped = false
}
}
FluIconButton{
iconSource: FluentIcons.Sync
width: 30
height: 30
iconSize: 13
onClicked: {
loader.reload()
}
}
}
FluRemoteLoader{
id:loader
lazy: true
anchors.fill: parent
source: "https://zhu-zichu.gitee.io/Qt_168_LieflatPage.qml"
}
}
front: Item{
id:page_front
visible: flipable.flipAngle !== 180
anchors.fill: flipable
FluNavigationView{
property int clickCount: 0
id:nav_view
width: parent.width
height: parent.height
z:999
//Stack模式每次切换都会将页面压入栈中随着栈的页面增多消耗的内存也越多内存消耗多就会卡顿这时候就需要按返回将页面pop掉释放内存。该模式可以配合FluPage中的launchMode属性设置页面的启动模式
// pageMode: FluNavigationViewType.Stack
//NoStack模式每次切换都会销毁之前的页面然后创建一个新的页面只需消耗少量内存可以配合FluViewModel保存页面数据推荐
pageMode: FluNavigationViewType.NoStack
items: ItemsOriginal
footerItems:ItemsFooter
topPadding:{
if(window.useSystemAppBar){
return 0
}
return FluTools.isMacos() ? 20 : 0
}
displayMode:viewmodel_settings.displayMode
logo: "qrc:/example/res/image/favicon.ico"
title:"FluentUI"
onLogoClicked:{
clickCount += 1
showSuccess("点击%1次".arg(clickCount))
if(clickCount === 5){
loader.reload()
flipable.flipped = true
clickCount = 0
}
}
autoSuggestBox:FluAutoSuggestBox{
iconSource: FluentIcons.Search
items: ItemsOriginal.getSearchData()
placeholderText: Lang.search
onItemClicked:
(data)=>{
ItemsOriginal.startPageByItem(data)
}
}
Component.onCompleted: {
ItemsOriginal.navigationView = nav_view
ItemsOriginal.paneItemMenu = nav_item_right_menu
ItemsFooter.navigationView = nav_view
ItemsFooter.paneItemMenu = nav_item_right_menu
setCurrentIndex(0)
}
}
}
}
Component{
id:com_reveal
CircularReveal{
id:reveal
target:window.layoutContainer()
anchors.fill: parent
onAnimationFinished:{
//动画结束后释放资源
loader_reveal.sourceComponent = undefined
}
onImageChanged: {
changeDark()
}
}
}
FluLoader{
id:loader_reveal
anchors.fill: parent
}
function distance(x1,y1,x2,y2){
return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
}
function handleDarkChanged(button){
if(!FluTheme.enableAnimation || window.fitsAppBarWindows === false){
changeDark()
}else{
if(loader_reveal.sourceComponent){
return
}
loader_reveal.sourceComponent = com_reveal
var target = window.layoutContainer()
var pos = button.mapToItem(target,0,0)
var mouseX = pos.x
var mouseY = pos.y
var radius = Math.max(distance(mouseX,mouseY,0,0),distance(mouseX,mouseY,target.width,0),distance(mouseX,mouseY,0,target.height),distance(mouseX,mouseY,target.width,target.height))
var reveal = loader_reveal.item
reveal.start(reveal.width*Screen.devicePixelRatio,reveal.height*Screen.devicePixelRatio,Qt.point(mouseX,mouseY),radius)
}
}
function changeDark(){
if(FluTheme.dark){
FluTheme.darkMode = FluThemeType.Light
}else{
FluTheme.darkMode = FluThemeType.Dark
}
}
Shortcut {
sequence: "F5"
context: Qt.WindowShortcut
onActivated: {
if(flipable.flipped){
loader.reload()
}
}
}
Shortcut {
sequence: "F6"
context: Qt.WindowShortcut
onActivated: {
tour.open()
}
}
FluTour{
id:tour
steps:{
var data = []
if(!window.useSystemAppBar){
data.push({title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>appBar.darkButton()})
}
data.push({title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()})
return data
}
}
FpsItem{
id:fps_item
}
FluText{
text:"fps %1".arg(fps_item.fps)
opacity: 0.3
anchors{
bottom: parent.bottom
right: parent.right
bottomMargin: 5
rightMargin: 5
}
}
FluContentDialog{
property string newVerson
property string body
id:dialog_update
title:"升级提示"
message:"FluentUI目前最新版本 "+ newVerson +" -- 当前应用版本 "+AppInfo.version+" \n现在是否去下载新版本\n\n更新内容\n"+body
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
negativeText: "取消"
positiveText:"确定"
onPositiveClicked:{
Qt.openUrlExternally("https://github.com/zhuzichu520/FluentUI/releases/latest")
}
}
FluNetworkCallable{
id:callable
property bool silent: true
onStart: {
console.debug("satrt check update...")
}
onFinish: {
console.debug("check update finish")
FluEventBus.post("checkUpdateFinish");
}
onSuccess:
(result)=>{
var data = JSON.parse(result)
console.debug("current version "+AppInfo.version)
console.debug("new version "+data.tag_name)
if(data.tag_name !== AppInfo.version){
dialog_update.newVerson = data.tag_name
dialog_update.body = data.body
dialog_update.open()
}else{
if(!silent){
showInfo("当前版本已经是最新版")
}
}
}
onError:
(status,errorString)=>{
if(!silent){
showError("网络异常!")
}
console.debug(status+";"+errorString)
}
}
function checkUpdate(silent){
callable.silent = silent
FluNetwork.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
.go(callable)
}
}