+59
-108
@@ -1,131 +1,82 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
import QtCore
|
import QtCore
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
QtObject {
|
Singleton {
|
||||||
id: configLoader
|
id: root
|
||||||
property string gifFolder: ""
|
|
||||||
property bool loaded: false
|
|
||||||
property string configDir: StandardPaths.homeLocation + "/.config/QTPet"
|
|
||||||
property string configPath: configDir + "/config.json"
|
|
||||||
|
|
||||||
signal folderChanged()
|
property alias gifFolder: adapter.gifFolder
|
||||||
|
property alias ready: root.loaded
|
||||||
|
|
||||||
// Process to check/create directory
|
property bool loaded: false
|
||||||
property var dirCheckProcess: Process {
|
property string configDir: Quickshell.env("HOME") + "/.config/QtDesktopPet"
|
||||||
id: dirCheck
|
property string configPath: configDir + "/config.json"
|
||||||
running: false
|
|
||||||
command: ["test", "-d", configLoader.configDir]
|
|
||||||
|
|
||||||
onExited: {
|
signal folderChanged()
|
||||||
if (exitCode !== 0) {
|
|
||||||
// Directory doesn't exist, create it
|
|
||||||
dirCreateProcess.running = true
|
|
||||||
} else {
|
|
||||||
// Directory exists, check for config file
|
|
||||||
fileCheckProcess.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process to create directory
|
Process {
|
||||||
property var dirCreateProcess: Process {
|
id: dirCheck
|
||||||
id: dirCreate
|
running: true
|
||||||
running: false
|
command: ["test", "-d", root.configDir]
|
||||||
command: ["mkdir", "-p", configLoader.configDir]
|
|
||||||
|
|
||||||
onExited: {
|
onExited: function( exitCode ) {
|
||||||
console.log("Created config directory:", configLoader.configDir)
|
if (exitCode !== 0) {
|
||||||
// After creating directory, create default config
|
dirCreate.running = true
|
||||||
fileCreateProcess.running = true
|
} else {
|
||||||
}
|
fileCheck.running = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process to check if config file exists
|
Process {
|
||||||
property var fileCheckProcess: Process {
|
id: dirCreate
|
||||||
id: fileCheck
|
running: false
|
||||||
running: false
|
command: ["mkdir", "-p", root.configDir]
|
||||||
command: ["test", "-f", configLoader.configPath]
|
|
||||||
|
|
||||||
onExited: {
|
onExited: function(): void {
|
||||||
if (exitCode !== 0) {
|
console.log("Created config directory:", root.configDir)
|
||||||
// File doesn't exist, create default config
|
fileCreate.running = true
|
||||||
fileCreateProcess.running = true
|
}
|
||||||
} else {
|
}
|
||||||
// File exists, load it
|
|
||||||
loadConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process to create default config file
|
Process {
|
||||||
property var fileCreateProcess: Process {
|
id: fileCheck
|
||||||
id: fileCreate
|
running: false
|
||||||
running: false
|
command: ["test", "-f", root.configPath]
|
||||||
command: ["sh", "-c", "echo '{\"gifFolder\": \"$HOME/.config/quickshell/QtDesktopPet/Gifs\"}' > " + configLoader.configPath]
|
|
||||||
|
|
||||||
onExited: {
|
onExited: function( exitCode ): void {
|
||||||
console.log("Created default config file:", configLoader.configPath)
|
if (exitCode !== 0) {
|
||||||
loadConfig()
|
fileCreate.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Timer to watch for config file changes
|
Process {
|
||||||
property var configWatcher: Timer {
|
id: fileCreate
|
||||||
id: watcher
|
|
||||||
interval: 2000 // Check every 2 seconds
|
|
||||||
running: configLoader.loaded
|
|
||||||
repeat: true
|
|
||||||
|
|
||||||
property string lastContent: ""
|
property string homeDir: Quickshell.env("HOME")
|
||||||
|
|
||||||
onTriggered: {
|
running: false
|
||||||
try {
|
command: ["sh", "-c", `echo '{\"gifFolder\": \"${homeDir}/.config/quickshell/QtDesktopPet/Gifs\"}' > ` + root.configPath]
|
||||||
let currentContent = Qt.readFile(configLoader.configPath)
|
}
|
||||||
if (lastContent !== "" && currentContent !== lastContent) {
|
|
||||||
console.log("Config file changed, reloading...")
|
|
||||||
loadConfig()
|
|
||||||
configLoader.folderChanged()
|
|
||||||
}
|
|
||||||
lastContent = currentContent
|
|
||||||
} catch (e) {
|
|
||||||
// File might have been deleted, ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadConfig() {
|
FileView {
|
||||||
try {
|
id: watcher
|
||||||
let configText = Qt.readFile(configPath)
|
path: root.configPath
|
||||||
let configData = JSON.parse(configText)
|
|
||||||
|
|
||||||
// Replace $HOME with actual home directory
|
watchChanges: true
|
||||||
let newFolder = configData.gifFolder.replace("$HOME", StandardPaths.homeLocation)
|
|
||||||
|
|
||||||
if (gifFolder !== newFolder && loaded) {
|
onFileChanged: reload()
|
||||||
// Folder changed, emit signal
|
|
||||||
gifFolder = newFolder
|
|
||||||
folderChanged()
|
|
||||||
} else {
|
|
||||||
gifFolder = newFolder
|
|
||||||
}
|
|
||||||
|
|
||||||
loaded = true
|
onLoaded: root.loaded = true
|
||||||
|
|
||||||
// Initialize watcher's lastContent on first load
|
JsonAdapter {
|
||||||
if (watcher.lastContent === "") {
|
id: adapter
|
||||||
watcher.lastContent = configText
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to load config:", e)
|
|
||||||
// Fallback to default path
|
|
||||||
gifFolder = StandardPaths.homeLocation + "/.config/quickshell/QtDesktopPet/Gifs"
|
|
||||||
loaded = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
property string gifFolder: ""
|
||||||
// Start the check/create chain
|
}
|
||||||
dirCheckProcess.running = true
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function reload() {
|
function reload() {
|
||||||
// Clear current list and restart the process
|
|
||||||
gifsList = []
|
gifsList = []
|
||||||
running = false
|
running = false
|
||||||
running = true
|
running = true
|
||||||
|
|||||||
+18
-2
@@ -1,3 +1,5 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Modules
|
import qs.Modules
|
||||||
|
|
||||||
@@ -8,14 +10,28 @@ Repeater {
|
|||||||
property int lastWidth
|
property int lastWidth
|
||||||
model: gifsList
|
model: gifsList
|
||||||
Item {
|
Item {
|
||||||
x: index === 0 ? 0 : gifRepeater.itemAt(index - 1).x + gifRepeater.itemAt(index - 1).width
|
id: gifItem
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property string modelData
|
||||||
|
|
||||||
|
function xPos(): void {
|
||||||
|
let xPos = 0;
|
||||||
|
const item = gifRepeater.itemAt(index - 1);
|
||||||
|
if ( item ) xPos += item.x + item.width;
|
||||||
|
return xPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: x = xPos()
|
||||||
|
|
||||||
|
x: 0
|
||||||
y: Screen.height - height
|
y: Screen.height - height
|
||||||
width: gif.width
|
width: gif.width
|
||||||
height: gif.height
|
height: gif.height
|
||||||
|
|
||||||
AnimatedImage {
|
AnimatedImage {
|
||||||
id: gif
|
id: gif
|
||||||
source: modelData
|
source: gifItem.modelData
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
@@ -10,14 +11,15 @@ PanelWindow {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
WlrLayershell.layer: WlrLayer.Top
|
WlrLayershell.layer: WlrLayer.Top
|
||||||
surfaceFormat.opaque: false
|
surfaceFormat.opaque: false
|
||||||
implicitWidth: Screen.width
|
|
||||||
implicitHeight: Screen.height
|
|
||||||
|
|
||||||
property bool onTop: true
|
property bool onTop: true
|
||||||
|
property list<Item> repeaterItems: []
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: true
|
left: true
|
||||||
bottom: true
|
bottom: true
|
||||||
|
right: true
|
||||||
|
top: true
|
||||||
}
|
}
|
||||||
|
|
||||||
margins {
|
margins {
|
||||||
@@ -27,32 +29,43 @@ PanelWindow {
|
|||||||
bottom: 9
|
bottom: 9
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigLoader {
|
|
||||||
id: configLoader
|
|
||||||
onFolderChanged: {
|
|
||||||
console.log("Folder changed to:", gifFolder)
|
|
||||||
getGifs.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetGifs {
|
GetGifs {
|
||||||
id: getGifs
|
id: getGifs
|
||||||
gifFolder: configLoader.gifFolder
|
gifFolder: ConfigLoader.gifFolder
|
||||||
running: configLoader.loaded
|
running: ConfigLoader.ready
|
||||||
}
|
}
|
||||||
|
|
||||||
GifsLoader {
|
GifsLoader {
|
||||||
id: gifloader
|
id: gifLoader
|
||||||
gifsList: getGifs.gifsList
|
gifsList: getGifs.gifsList
|
||||||
onItemAdded: {
|
onItemAdded: function( index, item ) {
|
||||||
mainWindow.petRegion( item )
|
mainWindow.repeaterItems.push( item )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
id: maskVariants
|
||||||
|
|
||||||
|
model: [ ...mainWindow.repeaterItems ]
|
||||||
|
|
||||||
|
Region {
|
||||||
|
required property Item modelData
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
console.log(modelData)
|
||||||
|
}
|
||||||
|
|
||||||
|
x: modelData.x
|
||||||
|
y: modelData.y
|
||||||
|
width: modelData.width
|
||||||
|
height: modelData.height
|
||||||
|
intersection: Intersection.Subtract
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
target: "command"
|
target: "command"
|
||||||
|
|
||||||
// Keybind swap layer
|
|
||||||
function toggleLayer(): void {
|
function toggleLayer(): void {
|
||||||
if ( !mainWindow.onTop ) {
|
if ( !mainWindow.onTop ) {
|
||||||
mainWindow.WlrLayershell.layer = WlrLayer.Top
|
mainWindow.WlrLayershell.layer = WlrLayer.Top
|
||||||
@@ -63,7 +76,6 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keybind swap overlay
|
|
||||||
function toggleOverlay(): void {
|
function toggleOverlay(): void {
|
||||||
if (!mainWindow.onTop) {
|
if (!mainWindow.onTop) {
|
||||||
mainWindow.WlrLayershell.layer = WlrLayer.Overlay
|
mainWindow.WlrLayershell.layer = WlrLayer.Overlay
|
||||||
@@ -85,7 +97,12 @@ PanelWindow {
|
|||||||
Region { }
|
Region { }
|
||||||
}
|
}
|
||||||
|
|
||||||
mask: Region {}
|
mask: Region {
|
||||||
|
width: Screen.width
|
||||||
|
height: Screen.height
|
||||||
|
intersection: Intersection.Xor
|
||||||
|
regions: maskVariants.instances
|
||||||
|
}
|
||||||
|
|
||||||
property var petMove: Region { id: pets }
|
property var petMove: Region { id: pets }
|
||||||
|
|
||||||
@@ -98,10 +115,10 @@ PanelWindow {
|
|||||||
|
|
||||||
function edmask(): void {
|
function edmask(): void {
|
||||||
if ( !mainWindow.setMask ) {
|
if ( !mainWindow.setMask ) {
|
||||||
mainWindow.mask = petMove
|
mainWindow.mask = mainWindow.petMove
|
||||||
mainWindow.setMask = true
|
mainWindow.setMask = true
|
||||||
} else {
|
} else {
|
||||||
mainWindow.mask = noMove
|
mainWindow.mask = mainWindow.noMove
|
||||||
mainWindow.setMask = false
|
mainWindow.setMask = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user