Kylin/Fluent/qml/ApplicationWindow.qml
2024-09-05 22:05:05 +08:00

388 lines
12 KiB
QML

import QtQuick as Quick
import QtQuick.Controls
import QtQuick.Layouts
import Fluent
Quick.Window {
id: window
default property alias contentData : layout_content.data
property string windowIcon: App.windowIcon
property int launchMode: WindowType.Standard
property var argument:({})
property var background : com_background
property bool fixSize: false
property Quick.Component loadingItem: com_loading
property bool fitsAppBarWindows: false
property var tintOpacity: Theme.dark ? 0.80 : 0.75
property int blurRadius: 60
property alias effect: frameless.effect
readonly property alias effective: frameless.effective
readonly property var availableEffects: frameless.availableEffects
property AppBar appBar: AppBar {
title: window.title
height: 30
showDark: window.showDark
showClose: window.showClose
showMinimize: window.showMinimize
showMaximize: window.showMaximize
showStayTop: window.showStayTop
icon: window.windowIcon
}
property Quick.color backgroundColor: {
if(frameless.effective && active){
var backcolor
if(frameless.effect==="dwm-blur"){
backcolor = Utilities.withOpacity(Theme.windowActiveBackgroundColor, window.tintOpacity)
}else{
backcolor = "transparent"
}
return backcolor
}
if(active){
return Theme.windowActiveBackgroundColor
}
return Theme.windowBackgroundColor
}
property bool stayTop: false
property bool showDark: false
property bool showClose: true
property bool showMinimize: true
property bool showMaximize: true
property bool showStayTop: false
property bool autoMaximize: false
property bool autoVisible: true
property bool autoCenter: true
property bool autoDestroy: true
property bool useSystemAppBar
property int __margins: 0
property Quick.color resizeBorderColor: {
if(window.active){
return Theme.dark ? Qt.rgba(51/255,51/255,51/255,1) : Qt.rgba(110/255,110/255,110/255,1)
}
return Theme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(167/255,167/255,167/255,1)
}
property int resizeBorderWidth: 1
property var closeListener: function(event){
if(autoDestroy){
Router.removeWindow(window)
}else{
window.visibility = Window.Hidden
event.accepted = false
}
}
signal initArgument(var argument)
signal lazyLoad()
property var _windowRegister
property string _route
property bool _hideShadow: false
color: Utilities.isSoftware() ? window.backgroundColor : "transparent"
Quick.Component.onCompleted: {
Router.addWindow(window)
useSystemAppBar = App.useSystemAppBar
if(!useSystemAppBar && autoCenter){
moveWindowToDesktopCenter()
}
fixWindowSize()
initArgument(argument)
if(window.autoVisible){
if(window.autoMaximize){
window.visibility = Window.Maximized
}else{
window.show()
}
}
}
onVisibleChanged: {
if(visible && d.isLazyInit){
window.lazyLoad()
d.isLazyInit = false
}
}
Quick.QtObject{
id:d
property bool isLazyInit: true
}
Quick.Connections{
target: window
function onClosing(event){closeListener(event)}
}
Frameless{
id: frameless
appBar: window.appBar
maximizeButton: appBar.buttonMaximize
fixSize: window.fixSize
topmost: window.stayTop
disabled: App.useSystemAppBar
Quick.Component.onCompleted: {
frameless.setHitTestVisible(appBar.layoutMacosButtons)
frameless.setHitTestVisible(appBar.layoutStandardbuttons)
}
Quick.Component.onDestruction: {
frameless.onDestruction()
}
onEffectiveChanged: {
if(effective){
Theme.blurBehindWindowEnabled = false
}
}
}
Quick.Component{
id:com_background
Quick.Item{
Quick.Rectangle{
anchors.fill: parent
color: window.backgroundColor
}
Quick.Image{
id:img_back
visible: false
cache: false
fillMode: Quick.Image.PreserveAspectCrop
asynchronous: true
Quick.Component.onCompleted: {
img_back.updateLayout()
source = Utilities.getUrlByFilePath(Theme.desktopImagePath)
}
Quick.Connections{
target: window
function onScreenChanged(){
img_back.updateLayout()
}
}
function updateLayout(){
var geometry = Utilities.desktopAvailableGeometry(window)
img_back.width = geometry.width
img_back.height = geometry.height
img_back.sourceSize = Qt.size(img_back.width,img_back.height)
}
Quick.Connections{
target: Theme
function onDesktopImagePathChanged(){
timer_update_image.restart()
}
function onBlurBehindWindowEnabledChanged(){
if(Theme.blurBehindWindowEnabled){
img_back.source = Utilities.getUrlByFilePath(Theme.desktopImagePath)
}else{
img_back.source = ""
}
}
}
Quick.Timer{
id:timer_update_image
interval: 150
onTriggered: {
img_back.source = ""
img_back.source = Utilities.getUrlByFilePath(Theme.desktopImagePath)
}
}
}
Acrylic{
anchors.fill: parent
target: img_back
tintOpacity: window.tintOpacity
blurRadius: window.blurRadius
visible: window.active && Theme.blurBehindWindowEnabled
tintColor: Theme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1)
targetRect: Qt.rect(window.x-window.screen.virtualX,window.y-window.screen.virtualY,window.width,window.height)
}
}
}
Quick.Component{
id:com_app_bar
Quick.Item{
data: window.appBar
Quick.Component.onCompleted: {
window.appBar.width = Qt.binding(function(){
return this.parent.width
})
}
}
}
Quick.Component{
id:com_loading
Popup{
id:popup_loading
focus: true
width: window.width
height: window.height
anchors.centerIn: Overlay.overlay
closePolicy: {
if(cancel){
return Popup.CloseOnEscape | Popup.CloseOnPressOutside
}
return Popup.NoAutoClose
}
Overlay.modal: Quick.Item {}
onVisibleChanged: {
if(!visible){
loader_loading.sourceComponent = undefined
}
}
padding: 0
opacity: 0
visible:true
Quick.Behavior on opacity {
Quick.SequentialAnimation {
Quick.PauseAnimation {
duration: 83
}
Quick.NumberAnimation{
duration: 167
}
}
}
Quick.Component.onCompleted: {
opacity = 1
}
background: Quick.Rectangle{
color:"#44000000"
}
contentItem: Quick.Item{
Quick.MouseArea{
anchors.fill: parent
onClicked: {
if (cancel){
popup_loading.visible = false
}
}
}
ColumnLayout{
spacing: 8
anchors.centerIn: parent
ProgressRing{
Layout.alignment: Qt.AlignHCenter
}
Text{
text:loadingText
Layout.alignment: Qt.AlignHCenter
}
}
}
}
}
Quick.Component{
id:com_border
Quick.Rectangle{
color:"transparent"
border.width: window.resizeBorderWidth
border.color: window.resizeBorderColor
}
}
Quick.Item{
id: layout_container
anchors.fill: parent
anchors.margins: window.__margins
Loader{
anchors.fill: parent
sourceComponent: background
}
Loader{
id:loader_app_bar
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: {
if(window.useSystemAppBar){
return 0
}
return window.fitsAppBarWindows ? 0 : window.appBar.height
}
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
}
Quick.Item{
id: layout_content
anchors{
top: loader_app_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
Loader{
property string loadingText
property bool cancel: false
id:loader_loading
anchors.fill: parent
}
InfoBar{
id:info_bar
root: layout_container
}
Loader{
id:loader_border
anchors.fill: parent
sourceComponent: {
if(window.useSystemAppBar || Utilities.isWin() || window.visibility === Quick.Window.Maximized || window.visibility === Quick.Window.FullScreen){
return undefined
}
return com_border
}
}
}
function hideLoading(){
loader_loading.sourceComponent = undefined
}
function showSuccess(text,duration,moremsg){
return info_bar.showSuccess(text,duration,moremsg)
}
function showInfo(text,duration,moremsg){
return info_bar.showInfo(text,duration,moremsg)
}
function showWarning(text,duration,moremsg){
return info_bar.showWarning(text,duration,moremsg)
}
function showError(text,duration,moremsg){
return info_bar.showError(text,duration,moremsg)
}
function clearAllInfo(){
return info_bar.clearAllInfo()
}
function moveWindowToDesktopCenter(){
var availableGeometry = Utilities.desktopAvailableGeometry(window)
window.setGeometry((availableGeometry.width-window.width)/2+Quick.Screen.virtualX,(availableGeometry.height-window.height)/2+Quick.Screen.virtualY,window.width,window.height)
}
function fixWindowSize(){
if(fixSize){
window.maximumWidth = window.width
window.maximumHeight = window.height
window.minimumWidth = window.width
window.minimumHeight = window.height
}
}
function setResult(data){
if(_windowRegister){
_windowRegister.setResult(data)
}
}
function showMaximized(){
frameless.showMaximized()
}
function showMinimized(){
frameless.showMinimized()
}
function showNormal(){
frameless.showNormal()
}
function showLoading(text = "",cancel = true){
if(text===""){
text = qsTr("Loading...")
}
loader_loading.loadingText = text
loader_loading.cancel = cancel
loader_loading.sourceComponent = com_loading
}
function setHitTestVisible(val){
frameless.setHitTestVisible(val)
}
function deleteLater(){
Utilities.deleteLater(window)
}
function containerItem(){
return layout_container
}
}