Files
komplex-hub/KomplexHubContent/MainScreen.qml
T
2026-08-25 19:22:39 -04:00

467 lines
14 KiB
QML

/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick
import QtQuick.Controls 2.0
import QtQuick.Layouts
import KomplexHub
import KomplexHub.Controls
import KomplexHub.Kero
import KomplexHubContent
Rectangle
{
property MenuButton currentMenuButton
property bool popup: false
id: windowRoot
color: palette.window
RowLayout
{
id: windowRootLayout
anchors.fill: parent
spacing: 0
Rectangle
{
id: windowMenu
Layout.fillWidth: false
Layout.fillHeight: true
Layout.preferredWidth: 100
Layout.minimumWidth: 100
Layout.maximumWidth: 100
color: palette.base.lighter()
ColumnLayout
{
height: popup ? 64 : 0
opacity: popup ? 1 : 0
MenuButton
{
Layout.alignment: Qt.AlignTop
height: 64
width: 100
text: qsTr("Back")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-reply-arrow.svg"
onTriggered: () => {
pageLoader.item.closePopup()
selected = false
}
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
}
}
ColumnLayout
{
opacity: popup ? 0 : 1
visible: opacity > 0.01
id: windowMenuLayout
Layout.fillHeight: true
anchors.fill: parent
MenuButton {
id: homeMenubutton
Layout.alignment: Qt.AlignTop
height: 64
width: 100
text: qsTr("Home")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-famous.svg"
onTriggered: () =>
{
pageLoader.page = "pages/HomePage.qml"
if(currentMenuButton !== null)
{
currentMenuButton.selected = false
}
currentMenuButton = this
searchContainer.preferredHeight = 0
searchContainer.reset()
}
}
MenuButton
{
Layout.alignment: Qt.AlignTop
height: 64
width: 100
text: qsTr("Images")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-image.svg"
onTriggered: () => {
pageLoader.page = "pages/ImageSearchPage.qml"
currentMenuButton.selected = false
currentMenuButton = this
searchContainer.preferredHeight = 50
searchContainer.reset()
}
}
MenuButton
{
Layout.alignment: Qt.AlignTop
height: 64
width: 100
text: qsTr("Videos")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-video.svg"
onTriggered: () => {
pageLoader.page = "pages/VideoSearchPage.qml"
currentMenuButton.selected = false
currentMenuButton = this
searchContainer.preferredHeight = 50
searchContainer.reset()
}
}
MenuButton
{
Layout.alignment: Qt.AlignTop
height: 64
width: 100
text: qsTr("Komplex")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-biotech.svg"
onTriggered: () => {
pageLoader.page = "pages/LiveSearchPage.qml"
currentMenuButton.selected = false
currentMenuButton = this
searchContainer.preferredHeight = 50
searchContainer.reset()
}
}
MenuButton
{
Layout.alignment: Qt.AlignTop
height: 64
width: 100
text: qsTr("Installed")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-hdd.svg"
onTriggered: () => {
pageLoader.page = "pages/InstalledWallpaperPage.qml"
currentMenuButton.selected = false
currentMenuButton = this
searchContainer.preferredHeight = 0
searchContainer.reset()
}
}
Item
{
Layout.fillHeight: true
Layout.minimumHeight: 100
}
MenuButton
{
Layout.alignment: Qt.AlignBottom
height: 64
width: 100
text: qsTr("Settings")
icon.height: 32
icon.width: 32
icon.url: "qrc:/images/icons/icons8-settings.svg"
onTriggered: () => {
pageLoader.page = "pages/SettingsPage.qml"
currentMenuButton.selected = false
currentMenuButton = this
searchContainer.preferredHeight = 0
searchContainer.reset()
}
}
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ? settings.normalAnimationDuration : 0
}
}
}
}
Rectangle
{
id: windowContainer
Layout.fillHeight: true
Layout.fillWidth: true
color: "transparent"
ColumnLayout
{
id: windowContainerLayout
anchors.fill: parent
spacing: 0
SearchBar
{
property int preferredHeight: 50
id: searchContainer
color: palette.base.lighter()
Layout.fillHeight: false
Layout.fillWidth: true
Layout.preferredHeight: preferredHeight
icon: "qrc:/images/icons/icons8-search.svg"
onSearchTermChanged: () =>
{
pageLoader.setSearchTerm()
}
Behavior on preferredHeight
{
NumberAnimation
{
duration: settings.animationsEnabled ? settings.normalAnimationDuration : 0
}
}
}
Rectangle
{
id: windowContent
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: 0
Layout.topMargin: 0
color: palette.base.darker()
Loader
{
property bool loading: false
property string page
anchors.fill: parent
onPageChanged: () =>
{
loading = true
fadeOutPage()
}
id: pageLoader
OpacityAnimator on opacity
{
id: pageLoaderAnimation
target: pageLoader
duration: settings.animationsEnabled ? settings.pageChangeAnimationDuration : 0
onFinished: () => {
if(pageLoader.loading && pageLoader.opacity === 0)
{
pageLoader.loadPage()
}
else if(pageLoader.loading && pageLoader.opacity === 1)
{
pageLoader.loading = false
pageLoader.updateSearchTerm();
popupConnection.target = pageLoader.item
}
}
}
function fadeOutPage()
{
pageLoaderAnimation.from = 1
pageLoaderAnimation.to = 0
pageLoaderAnimation.start()
}
function fadeInPage()
{
if(pageLoader.sourceComponent.status != Component.Ready)
{
return
}
pageLoaderAnimation.from = 0
pageLoaderAnimation.to = 1
pageLoaderAnimation.start()
}
function loadPage()
{
sourceComponent = Qt.createComponent(page)
if(sourceComponent.status == Component.Ready)
{
fadeInPage()
}
else
{
statusChanged.connect(fadeInPage)
}
}
function updateSearchTerm()
{
if(isSearchPage())
{
searchContainer.searchTerm = pageLoader.item.query
}
}
function setSearchTerm()
{
if(isSearchPage())
{
pageLoader.item.query = searchContainer.searchTerm
}
}
function isSearchPage()
{
return(
pageLoader.item instanceof ImageSearchPage ||
pageLoader.item instanceof LiveSearchPage ||
pageLoader.item instanceof VideoSearchPage
);
}
}
}
}
}
}
Connections
{
id: popupConnection
target: pageLoader.item
function onPopupChanged()
{
windowRoot.popup = pageLoader.item.popup
}
}
Component.onCompleted: () => {
homeMenubutton.selected = true
currentMenuButton = homeMenubutton
pageLoader.page = "pages/HomePage.qml"
searchContainer.preferredHeight = 0
}
states: [
State {
name: "build_error"
PropertyChanges {
target: windowOverlay
visible: true
}
},
State {
name: "building"
PropertyChanges {
target: buildingOverlay
visible: true
}
},
State {
name: "build_complete"
},
State
{
name: "popup"
when: popup
PropertyChanges {
target: searchContainer
preferredHeight: 0
}
}
]
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
}