2023-08-24 15:50:37 +08:00
import QtQuick
import QtQuick . Window
import QtQuick . Controls
import QtQuick . Layouts
import Qt . labs . platform
import FluentUI
import example
2024-01-25 17:26:50 +08:00
import "../component"
import "../global"
import "../viewmodel"
2023-08-24 15:50:37 +08:00
2023-10-08 18:19:08 +08:00
FluWindow {
2023-08-24 15:50:37 +08:00
id:window
title: "FluentUI"
2024-03-09 22:26:21 +08:00
width: 1000
height: 680
2023-08-24 15:50:37 +08:00
minimumWidth: 520
minimumHeight: 200
launchMode: FluWindowType . SingleTask
2023-11-21 14:28:37 +08:00
fitsAppBarWindows: true
appBar: FluAppBar {
height: 30
2024-03-09 15:35:48 +08:00
darkText: qsTr ( "Dark Mode" )
2023-11-21 14:28:37 +08:00
showDark: true
darkClickListener: ( button ) = > handleDarkChanged ( button )
closeClickListener: ( ) = > { dialog_close . open ( ) }
z: 7
}
2023-10-08 18:19:08 +08:00
2023-09-12 18:45:15 +08:00
SettingsViewModel {
id:viewmodel_settings
}
2023-09-11 18:10:50 +08:00
FluEvent {
id:event_checkupdate
name: "checkUpdate"
onTriggered: {
checkUpdate ( false )
}
}
2023-10-19 22:52:36 +08:00
2023-11-27 16:45:37 +08:00
onFirstVisible: {
2023-12-14 23:50:58 +08:00
timer_tour_delay . restart ( )
}
Timer {
id:timer_tour_delay
interval: 200
onTriggered: {
tour . open ( )
}
2023-11-27 16:45:37 +08:00
}
Component.onCompleted: {
2023-09-11 18:10:50 +08:00
checkUpdate ( true )
FluEventBus . registerEvent ( event_checkupdate )
}
Component.onDestruction: {
FluEventBus . unRegisterEvent ( event_checkupdate )
2023-08-24 15:50:37 +08:00
}
SystemTrayIcon {
id:system_tray
visible: true
icon.source: "qrc:/example/res/image/favicon.ico"
tooltip: "FluentUI"
menu: Menu {
MenuItem {
text: "退出"
onTriggered: {
2023-10-19 22:52:36 +08:00
FluApp . exit ( )
2023-08-24 15:50:37 +08:00
}
}
}
onActivated:
( reason ) = > {
if ( reason === SystemTrayIcon . Trigger ) {
window . show ( )
window . raise ( )
window . requestActivate ( )
}
}
}
2023-12-04 17:10:08 +08:00
Timer {
2024-03-09 15:35:48 +08:00
id: timer_window_hide_delay
2023-12-04 17:10:08 +08:00
interval: 150
onTriggered: {
window . hide ( )
}
}
2023-08-24 15:50:37 +08:00
FluContentDialog {
2024-03-09 15:35:48 +08:00
id: dialog_close
title: qsTr ( "Quit" )
message: qsTr ( "Are you sure you want to exit the program?" )
negativeText: qsTr ( "Minimize" )
2023-08-24 15:50:37 +08:00
buttonFlags: FluContentDialogType . NegativeButton | FluContentDialogType . NeutralButton | FluContentDialogType . PositiveButton
2023-12-04 17:10:08 +08:00
onNegativeClicked: {
2024-03-09 15:35:48 +08:00
system_tray . showMessage ( qsTr ( "Friendly Reminder" ) , qsTr ( "FluentUI is hidden from the tray, click on the tray to activate the window again" ) ) ;
2023-12-04 17:10:08 +08:00
timer_window_hide_delay . restart ( )
2023-08-24 15:50:37 +08:00
}
2024-03-09 15:35:48 +08:00
positiveText: qsTr ( "Quit" )
neutralText: qsTr ( "Cancel" )
2023-08-24 15:50:37 +08:00
onPositiveClicked: {
2023-10-19 22:52:36 +08:00
FluApp . exit ( 0 )
}
}
Component {
2024-03-09 15:35:48 +08:00
id: nav_item_right_menu
2023-10-19 22:52:36 +08:00
FluMenu {
2024-03-09 23:42:01 +08:00
width: 186
2023-10-19 22:52:36 +08:00
FluMenuItem {
2024-03-09 15:35:48 +08:00
text: qsTr ( "Open in Separate Window" )
2024-03-09 23:42:01 +08:00
font.pixelSize: 12
2023-10-19 22:52:36 +08:00
onClicked: {
FluApp . navigate ( "/pageWindow" , { title: modelData . title , url: modelData . url } )
}
}
2023-08-24 15:50:37 +08:00
}
}
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 {
2023-11-21 14:28:37 +08:00
id:layout_back_buttons
2023-08-24 15:50:37 +08:00
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 ( )
}
}
2024-02-26 15:50:42 +08:00
Component.onCompleted: {
appBar . setHitTestVisible ( layout_back_buttons )
}
2023-08-24 15:50:37 +08:00
}
FluRemoteLoader {
id:loader
lazy: true
anchors.fill: parent
2024-01-30 20:16:54 +08:00
source: "https://zhu-zichu.gitee.io/Qt_168_LieflatPage.qml"
2023-08-24 15:50:37 +08:00
}
}
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属性, 设置页面的启动模式
2023-09-08 22:33:23 +08:00
// pageMode: FluNavigationViewType.Stack
2023-09-22 00:11:58 +08:00
//NoStack模式, 每次切换都会销毁之前的页面然后创建一个新的页面, 只需消耗少量内存, 可以配合FluViewModel保存页面数据( 推荐)
2023-09-08 22:33:23 +08:00
pageMode: FluNavigationViewType . NoStack
2023-08-24 15:50:37 +08:00
items: ItemsOriginal
footerItems: ItemsFooter
2023-12-13 18:13:35 +08:00
topPadding: {
if ( window . useSystemAppBar ) {
return 0
}
return FluTools . isMacos ( ) ? 20 : 0
}
2023-09-12 18:45:15 +08:00
displayMode: viewmodel_settings . displayMode
2023-08-24 15:50:37 +08:00
logo: "qrc:/example/res/image/favicon.ico"
title: "FluentUI"
onLogoClicked: {
clickCount += 1
2024-03-09 15:35:48 +08:00
showSuccess ( "%1:%2" . arg ( qsTr ( "Click Time" ) ) . arg ( clickCount ) )
2023-08-24 15:50:37 +08:00
if ( clickCount === 5 ) {
loader . reload ( )
flipable . flipped = true
clickCount = 0
}
}
autoSuggestBox: FluAutoSuggestBox {
iconSource: FluentIcons . Search
items: ItemsOriginal . getSearchData ( )
2024-03-09 15:35:48 +08:00
placeholderText: qsTr ( "Search" )
2023-08-24 15:50:37 +08:00
onItemClicked:
( data ) = > {
ItemsOriginal . startPageByItem ( data )
}
}
Component.onCompleted: {
ItemsOriginal . navigationView = nav_view
2023-10-19 22:52:36 +08:00
ItemsOriginal . paneItemMenu = nav_item_right_menu
2023-08-24 15:50:37 +08:00
ItemsFooter . navigationView = nav_view
2023-10-19 22:52:36 +08:00
ItemsFooter . paneItemMenu = nav_item_right_menu
2024-02-26 15:50:42 +08:00
appBar . setHitTestVisible ( nav_view . buttonMenu )
appBar . setHitTestVisible ( nav_view . buttonBack )
appBar . setHitTestVisible ( nav_view . imageLogo )
2023-08-24 15:50:37 +08:00
setCurrentIndex ( 0 )
}
}
}
}
Component {
id:com_reveal
CircularReveal {
id:reveal
2024-03-11 18:55:33 +08:00
target: window . contentItem
2023-08-24 15:50:37 +08:00
anchors.fill: parent
onAnimationFinished: {
//动画结束后释放资源
loader_reveal . sourceComponent = undefined
}
onImageChanged: {
changeDark ( )
}
}
}
2023-11-02 23:02:08 +08:00
FluLoader {
2023-08-24 15:50:37 +08:00
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 ) {
2023-11-27 16:45:37 +08:00
if ( ! FluTheme . enableAnimation || window . fitsAppBarWindows === false ) {
2023-08-24 15:50:37 +08:00
changeDark ( )
} else {
2023-12-05 00:20:40 +08:00
if ( loader_reveal . sourceComponent ) {
return
}
2023-08-24 15:50:37 +08:00
loader_reveal . sourceComponent = com_reveal
2024-03-11 18:55:33 +08:00
var target = window . contentItem
2023-08-24 15:50:37 +08:00
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 {
2024-03-09 15:35:48 +08:00
id: tour
finishText: qsTr ( "Finish" )
nextText: qsTr ( "Next" )
previousText: qsTr ( "Previous" )
2023-11-21 14:28:37 +08:00
steps: {
var data = [ ]
2023-12-13 17:31:08 +08:00
if ( ! window . useSystemAppBar ) {
2024-03-09 15:35:48 +08:00
data . push ( { title: qsTr ( "Dark Mode" ) , description: qsTr ( "Here you can switch to night mode." ) , target: ( ) = > appBar . buttonDark } )
2023-11-21 14:28:37 +08:00
}
2024-03-09 15:35:48 +08:00
data . push ( { title: qsTr ( "Hide Easter eggs" ) , description: qsTr ( "Try a few more clicks!!" ) , target: ( ) = > nav_view . imageLogo } )
2023-11-21 14:28:37 +08:00
return data
}
2023-08-24 15:50:37 +08:00
}
2023-08-28 17:14:21 +08:00
FpsItem {
id:fps_item
}
FluText {
2024-03-09 15:35:48 +08:00
text: "fps %1" . arg ( fps_item . fps )
2023-08-28 17:14:21 +08:00
opacity: 0.3
anchors {
bottom: parent . bottom
right: parent . right
bottomMargin: 5
rightMargin: 5
}
}
2023-08-27 09:11:44 +08:00
FluContentDialog {
property string newVerson
property string body
2024-03-09 15:35:48 +08:00
id: dialog_update
title: qsTr ( "Upgrade Tips" )
message: qsTr ( "FluentUI is currently up to date " ) + newVerson + qsTr ( " -- The current app version" ) + AppInfo . version + qsTr ( " \nNow go and download the new version? \n\nUpdated content: \n" ) + body
2023-08-27 09:11:44 +08:00
buttonFlags: FluContentDialogType . NegativeButton | FluContentDialogType . PositiveButton
2024-03-09 15:35:48 +08:00
negativeText: qsTr ( "Cancel" )
positiveText: qsTr ( "OK" )
2023-08-27 09:11:44 +08:00
onPositiveClicked: {
Qt . openUrlExternally ( "https://github.com/zhuzichu520/FluentUI/releases/latest" )
}
}
2023-11-29 21:35:06 +08:00
FluNetworkCallable {
2023-09-04 18:37:55 +08:00
id:callable
2023-09-11 18:10:50 +08:00
property bool silent: true
2023-09-04 18:37:55 +08:00
onStart: {
2023-08-27 09:11:44 +08:00
console . debug ( "satrt check update..." )
}
2023-09-04 18:37:55 +08:00
onFinish: {
2023-08-27 09:11:44 +08:00
console . debug ( "check update finish" )
2023-09-11 18:10:50 +08:00
FluEventBus . post ( "checkUpdateFinish" ) ;
2023-08-27 09:11:44 +08:00
}
2023-09-04 18:37:55 +08:00
onSuccess:
( result ) = > {
var data = JSON . parse ( result )
2023-09-17 20:36:33 +08:00
console . debug ( "current version " + AppInfo . version )
2023-09-04 18:37:55 +08:00
console . debug ( "new version " + data . tag_name )
2023-09-17 20:36:33 +08:00
if ( data . tag_name !== AppInfo . version ) {
2023-09-04 18:37:55 +08:00
dialog_update . newVerson = data . tag_name
dialog_update . body = data . body
dialog_update . open ( )
2023-09-11 18:10:50 +08:00
} else {
if ( ! silent ) {
2024-03-09 15:35:48 +08:00
showInfo ( qsTr ( "The current version is already the latest" ) )
2023-09-11 18:10:50 +08:00
}
2023-09-04 18:37:55 +08:00
}
2023-08-27 09:11:44 +08:00
}
2023-09-04 18:37:55 +08:00
onError:
( status , errorString ) = > {
2023-09-11 18:10:50 +08:00
if ( ! silent ) {
2024-03-09 15:35:48 +08:00
showError ( qsTr ( "The network is abnormal" ) )
2023-09-11 18:10:50 +08:00
}
2023-09-04 18:37:55 +08:00
console . debug ( status + ";" + errorString )
}
}
2023-09-11 18:10:50 +08:00
function checkUpdate ( silent ) {
callable . silent = silent
2023-11-29 21:35:06 +08:00
FluNetwork . get ( "https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest" )
2023-11-30 01:12:57 +08:00
. go ( callable )
2023-08-27 09:11:44 +08:00
}
2023-08-24 15:50:37 +08:00
}