159 lines
3.3 KiB
QML
159 lines
3.3 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Widgets
|
|
|
|
PanelWindow {
|
|
id: launcher
|
|
|
|
required property bool open
|
|
required property string repoRoot
|
|
required property string flavorName
|
|
|
|
signal closeRequested()
|
|
|
|
visible: open
|
|
focusable: true
|
|
aboveWindows: true
|
|
color: "transparent"
|
|
|
|
anchors {
|
|
top: true
|
|
right: true
|
|
bottom: true
|
|
left: true
|
|
}
|
|
|
|
FileView {
|
|
id: flavorFile
|
|
|
|
path: launcher.repoRoot + "/theme/flavors/" + launcher.flavorName + "/launcher.json"
|
|
blockLoading: true
|
|
watchChanges: true
|
|
|
|
onFileChanged: reload()
|
|
}
|
|
|
|
readonly property var flavor: JSON.parse(flavorFile.text())
|
|
|
|
Process {
|
|
id: appProcess
|
|
}
|
|
|
|
function fileUrl(path) {
|
|
if (!path || path.length === 0)
|
|
return ""
|
|
|
|
if (path.startsWith("/"))
|
|
return "file://" + path
|
|
|
|
return "file://" + launcher.repoRoot + "/" + path
|
|
}
|
|
|
|
function launchProgram(program) {
|
|
launcher.closeRequested()
|
|
|
|
appProcess.command = program.command
|
|
appProcess.startDetached()
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: launcher.flavor.colors.overlay
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: launcher.closeRequested()
|
|
}
|
|
|
|
Item {
|
|
id: dial
|
|
|
|
property real r: launcher.flavor.radius
|
|
property real appR: launcher.flavor.appRadius
|
|
property real orbit: launcher.flavor.orbitMultiplier * r
|
|
|
|
width: orbit * 2 + appR * 2
|
|
height: orbit * 2 + appR * 2
|
|
|
|
anchors.centerIn: parent
|
|
|
|
Rectangle {
|
|
id: center
|
|
|
|
width: dial.r * 2
|
|
height: dial.r * 2
|
|
radius: dial.r
|
|
|
|
anchors.centerIn: parent
|
|
|
|
color: launcher.flavor.colors.centerBackground
|
|
border.color: launcher.flavor.colors.centerBorder
|
|
border.width: 2
|
|
|
|
clip: true
|
|
|
|
Image {
|
|
anchors.fill: parent
|
|
anchors.margins: 6
|
|
|
|
source: launcher.fileUrl(launcher.flavor.centerIcon)
|
|
fillMode: Image.PreserveAspectFit
|
|
smooth: true
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
model: launcher.flavor.programs
|
|
|
|
delegate: Item {
|
|
id: appButton
|
|
|
|
required property int index
|
|
required property var modelData
|
|
|
|
property real angle: (index * 45 - 90) * Math.PI / 180
|
|
|
|
width: dial.appR * 2
|
|
height: dial.appR * 2
|
|
|
|
x: dial.width / 2 + Math.cos(angle) * dial.orbit - width / 2
|
|
y: dial.height / 2 + Math.sin(angle) * dial.orbit - height / 2
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: width / 2
|
|
|
|
color: mouse.containsMouse
|
|
? launcher.flavor.colors.appHoverBackground
|
|
: launcher.flavor.colors.appBackground
|
|
|
|
border.color: launcher.flavor.colors.appBorder
|
|
border.width: 2
|
|
|
|
clip: true
|
|
|
|
Image {
|
|
anchors.fill: parent
|
|
anchors.margins: 7
|
|
|
|
source: launcher.fileUrl(appButton.modelData.icon)
|
|
fillMode: Image.PreserveAspectFit
|
|
smooth: true
|
|
}
|
|
|
|
MouseArea {
|
|
id: mouse
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
|
|
onClicked: launcher.launchProgram(appButton.modelData)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|