forked from Shinonome/dots-hyprland
tiny reload popup design tweaks
This commit is contained in:
@@ -1,160 +1,172 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
|
|
||||||
Scope {
|
Scope {
|
||||||
id: root
|
id: root
|
||||||
property bool failed;
|
property bool failed
|
||||||
property string errorString;
|
property string errorString
|
||||||
|
property real progressHeight: 3
|
||||||
|
|
||||||
// Connect to the Quickshell global to listen for the reload signals.
|
// Connect to the Quickshell global to listen for the reload signals.
|
||||||
Connections {
|
Connections {
|
||||||
target: Quickshell
|
target: Quickshell
|
||||||
|
|
||||||
function onReloadCompleted() {
|
function onReloadCompleted() {
|
||||||
root.failed = false;
|
root.failed = false;
|
||||||
popupLoader.loading = true;
|
popupLoader.loading = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onReloadFailed(error: string) {
|
function onReloadFailed(error: string) {
|
||||||
// Close any existing popup before making a new one.
|
// Close any existing popup before making a new one.
|
||||||
popupLoader.active = false;
|
popupLoader.active = false;
|
||||||
|
|
||||||
root.failed = true;
|
root.failed = true;
|
||||||
root.errorString = error;
|
root.errorString = error;
|
||||||
popupLoader.loading = true;
|
popupLoader.loading = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the popup in a loader because it isn't needed most of the time
|
// Keep the popup in a loader because it isn't needed most of the time
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: popupLoader
|
id: popupLoader
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: popup
|
id: popup
|
||||||
|
|
||||||
exclusiveZone: 0
|
exclusiveZone: 0
|
||||||
anchors.top: true
|
anchors.top: true
|
||||||
margins.top: 0
|
margins.top: 0
|
||||||
|
|
||||||
implicitWidth: rect.width + shadow.radius * 2
|
implicitWidth: rect.width + 8 * 2
|
||||||
implicitHeight: rect.height + shadow.radius * 2
|
implicitHeight: rect.height + 8 * 2
|
||||||
|
|
||||||
WlrLayershell.namespace: "quickshell:reloadPopup"
|
WlrLayershell.namespace: "quickshell:reloadPopup"
|
||||||
|
|
||||||
// color blending is a bit odd as detailed in the type reference.
|
// color blending is a bit odd as detailed in the type reference.
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Rectangle {
|
RectangularShadow {
|
||||||
id: rect
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: failed ? "#ffe99195" : "#ffD1E8D5"
|
|
||||||
|
|
||||||
implicitHeight: layout.implicitHeight + 30
|
|
||||||
implicitWidth: layout.implicitWidth + 30
|
|
||||||
radius: 12
|
|
||||||
|
|
||||||
// Fills the whole area of the rectangle, making any clicks go to it,
|
|
||||||
// which dismiss the popup.
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
onPressed: {
|
|
||||||
popupLoader.active = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// makes the mouse area track mouse hovering, so the hide animation
|
|
||||||
// can be paused when hovering.
|
|
||||||
hoverEnabled: true
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: layout
|
|
||||||
spacing: 10
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 10
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
renderType: Text.NativeRendering
|
|
||||||
font.family: "Google Sans Flex"
|
|
||||||
font.pointSize: 14
|
|
||||||
text: root.failed ? "Quickshell: Reload failed" : "Quickshell reloaded"
|
|
||||||
color: failed ? "#ff93000A" : "#ff0C1F13"
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
renderType: Text.NativeRendering
|
|
||||||
font.family: "JetBrains Mono NF"
|
|
||||||
font.pointSize: 11
|
|
||||||
text: root.errorString
|
|
||||||
color: failed ? "#ff93000A" : "#ff0C1F13"
|
|
||||||
// When visible is false, it also takes up no space.
|
|
||||||
visible: root.errorString != ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A progress bar on the bottom of the screen, showing how long until the
|
|
||||||
// popup is removed.
|
|
||||||
Rectangle {
|
|
||||||
z: 2
|
|
||||||
id: bar
|
|
||||||
color: failed ? "#ff93000A" : "#ff0C1F13"
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: 10
|
|
||||||
height: 5
|
|
||||||
radius: 9999
|
|
||||||
|
|
||||||
PropertyAnimation {
|
|
||||||
id: anim
|
|
||||||
target: bar
|
|
||||||
property: "width"
|
|
||||||
from: rect.width - bar.anchors.margins * 2
|
|
||||||
to: 0
|
|
||||||
duration: failed ? 10000 : 1000
|
|
||||||
onFinished: popupLoader.active = false
|
|
||||||
|
|
||||||
// Pause the animation when the mouse is hovering over the popup,
|
|
||||||
// so it stays onscreen while reading. This updates reactively
|
|
||||||
// when the mouse moves on and off the popup.
|
|
||||||
paused: mouseArea.containsMouse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Its bg
|
|
||||||
Rectangle {
|
|
||||||
z: 1
|
|
||||||
id: bar_bg
|
|
||||||
color: failed ? "#30af1b25" : "#4027643e"
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: 10
|
|
||||||
height: 5
|
|
||||||
radius: 9999
|
|
||||||
width: rect.width - bar.anchors.margins * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// We could set `running: true` inside the animation, but the width of the
|
|
||||||
// rectangle might not be calculated yet, due to the layout.
|
|
||||||
// In the `Component.onCompleted` event handler, all of the component's
|
|
||||||
// properties and children have been initialized.
|
|
||||||
Component.onCompleted: anim.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
DropShadow {
|
|
||||||
id: shadow
|
|
||||||
anchors.fill: rect
|
anchors.fill: rect
|
||||||
horizontalOffset: 0
|
radius: rect.radius
|
||||||
verticalOffset: 2
|
blur: 6.3
|
||||||
radius: 6
|
offset: Qt.vector2d(0.0, 1.0)
|
||||||
samples: radius * 2 + 1 // Ideally should be 2 * radius + 1, see qt docs
|
spread: 1
|
||||||
color: "#44000000"
|
color: "#55000000"
|
||||||
source: rect
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
Rectangle {
|
||||||
|
id: rect
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: root.failed ? "#ffe99195" : "#ffD1E8D5"
|
||||||
|
|
||||||
|
implicitHeight: layout.implicitHeight + 30
|
||||||
|
implicitWidth: layout.implicitWidth + 30
|
||||||
|
radius: 8
|
||||||
|
|
||||||
|
// Fills the whole area of the rectangle, making any clicks go to it,
|
||||||
|
// which dismiss the popup.
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onPressed: {
|
||||||
|
popupLoader.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// makes the mouse area track mouse hovering, so the hide animation
|
||||||
|
// can be paused when hovering.
|
||||||
|
hoverEnabled: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: layout
|
||||||
|
spacing: 10
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 10
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: title
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
font.family: "Google Sans Flex"
|
||||||
|
font.pointSize: 14
|
||||||
|
text: root.failed ? "Quickshell: Reload failed" : "Quickshell reloaded"
|
||||||
|
color: root.failed ? "#ff93000A" : "#ff0C1F13"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: info
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
font.family: "JetBrains Mono NF"
|
||||||
|
font.pointSize: 11
|
||||||
|
text: root.errorString
|
||||||
|
color: root.failed ? "#ff93000A" : "#ff0C1F13"
|
||||||
|
// When visible is false, it also takes up no space.
|
||||||
|
visible: root.errorString != ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A progress bar on the bottom of the screen, showing how long until the
|
||||||
|
// popup is removed.
|
||||||
|
Rectangle {
|
||||||
|
id: bar
|
||||||
|
z: 2
|
||||||
|
color: root.failed ? "#ff93000A" : "#ff0C1F13"
|
||||||
|
property real maxWidth: Math.max(title.width, info.width)
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: (parent.width - maxWidth) / 2
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: 10
|
||||||
|
}
|
||||||
|
height: root.progressHeight
|
||||||
|
radius: 9999
|
||||||
|
|
||||||
|
PropertyAnimation {
|
||||||
|
id: anim
|
||||||
|
target: bar
|
||||||
|
property: "width"
|
||||||
|
from: Math.max(title.width, info.width)
|
||||||
|
to: 0
|
||||||
|
duration: root.failed ? 10000 : 1000
|
||||||
|
onFinished: popupLoader.active = false
|
||||||
|
|
||||||
|
// Pause the animation when the mouse is hovering over the popup,
|
||||||
|
// so it stays onscreen while reading. This updates reactively
|
||||||
|
// when the mouse moves on and off the popup.
|
||||||
|
paused: mouseArea.containsMouse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Its bg
|
||||||
|
Rectangle {
|
||||||
|
id: bar_bg
|
||||||
|
z: 1
|
||||||
|
color: root.failed ? "#30af1b25" : "#4027643e"
|
||||||
|
property real maxWidth: Math.max(title.width, info.width)
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
leftMargin: (parent.width - maxWidth) / 2
|
||||||
|
rightMargin: anchors.leftMargin
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: 10
|
||||||
|
}
|
||||||
|
height: root.progressHeight
|
||||||
|
radius: 9999
|
||||||
|
width: bar.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// We could set `running: true` inside the animation, but the width of the
|
||||||
|
// rectangle might not be calculated yet, due to the layout.
|
||||||
|
// In the `Component.onCompleted` event handler, all of the component's
|
||||||
|
// properties and children have been initialized.
|
||||||
|
Component.onCompleted: anim.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user