mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 23:09:26 -05:00
Merge branch 'end-4:main' into clean-testing
This commit is contained in:
@@ -119,6 +119,17 @@ bind = Super+Alt, code:16, exec, ~/.config/hypr/hyprland/scripts/workspace_actio
|
||||
bind = Super+Alt, code:17, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 8 # [hidden]
|
||||
bind = Super+Alt, code:18, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 9 # [hidden]
|
||||
bind = Super+Alt, code:19, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 10 # [hidden]
|
||||
# keypad numbers
|
||||
bind = Super+Alt, code:87, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 1 # [hidden]
|
||||
bind = Super+Alt, code:88, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 2 # [hidden]
|
||||
bind = Super+Alt, code:89, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 3 # [hidden]
|
||||
bind = Super+Alt, code:83, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 4 # [hidden]
|
||||
bind = Super+Alt, code:84, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 5 # [hidden]
|
||||
bind = Super+Alt, code:85, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 6 # [hidden]
|
||||
bind = Super+Alt, code:79, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 7 # [hidden]
|
||||
bind = Super+Alt, code:80, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 8 # [hidden]
|
||||
bind = Super+Alt, code:81, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 9 # [hidden]
|
||||
bind = Super+Alt, code:90, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh movetoworkspacesilent 10 # [hidden]
|
||||
|
||||
# #/# bind = Super+Shift, Scroll ↑/↓,, # Send to workspace left/right
|
||||
bind = Super+Shift, mouse_down, movetoworkspace, r-1 # [hidden]
|
||||
@@ -152,6 +163,17 @@ bind = Super, code:16, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh
|
||||
bind = Super, code:17, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 8 # [hidden]
|
||||
bind = Super, code:18, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 9 # [hidden]
|
||||
bind = Super, code:19, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 10 # [hidden]
|
||||
# keypad numbers
|
||||
bindp = Super, code:87, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 1 # [hidden]
|
||||
bindp = Super, code:88, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 2 # [hidden]
|
||||
bindp = Super, code:89, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 3 # [hidden]
|
||||
bindp = Super, code:83, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 4 # [hidden]
|
||||
bindp = Super, code:84, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 5 # [hidden]
|
||||
bindp = Super, code:85, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 6 # [hidden]
|
||||
bindp = Super, code:79, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 7 # [hidden]
|
||||
bindp = Super, code:80, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 8 # [hidden]
|
||||
bindp = Super, code:81, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 9 # [hidden]
|
||||
bindp = Super, code:90, exec, ~/.config/hypr/hyprland/scripts/workspace_action.sh workspace 10 # [hidden]
|
||||
|
||||
#/# bind = Ctrl+Super, ←/→,, # Focus left/right
|
||||
bind = Ctrl+Super, Right, workspace, r+1 # [hidden]
|
||||
@@ -201,6 +223,11 @@ binde = Super, Minus, exec, qs -c $qsConfig ipc call zoom zoomOut # Zoom out
|
||||
binde = Super, Equal, exec, qs -c $qsConfig ipc call zoom zoomIn # Zoom in
|
||||
binde = Super, Minus, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh decrease 0.1 # [hidden] Zoom out
|
||||
binde = Super, Equal, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh increase 0.1 # [hidden] Zoom in
|
||||
# Zoom with keypad
|
||||
binde = Super, code:82, exec, qs -c $qsConfig ipc call zoom zoomOut # Zoom out
|
||||
binde = Super, code:86, exec, qs -c $qsConfig ipc call zoom zoomIn # Zoom in
|
||||
binde = Super, code:82, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh decrease 0.1 # [hidden] Zoom out
|
||||
binde = Super, code:86, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/hypr/hyprland/scripts/zoom.sh increase 0.1 # [hidden] Zoom in
|
||||
|
||||
##! Media
|
||||
bindl= Super+Shift, N, exec, playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` # Next track
|
||||
|
||||
@@ -14,6 +14,8 @@ import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
import "./cookieClock"
|
||||
|
||||
Variants {
|
||||
id: root
|
||||
readonly property bool fixedClockPosition: Config.options.background.clock.fixedPosition
|
||||
@@ -22,6 +24,7 @@ Variants {
|
||||
readonly property real clockSizePadding: 20
|
||||
readonly property real screenSizePadding: 50
|
||||
readonly property string clockStyle: Config.options.background.clock.style
|
||||
readonly property bool showCookieQuote: Config.options.background.showQuote && Config.options.background.quote !== "" && !GlobalStates.screenLocked && Config.options.background.clock.style === "cookie"
|
||||
model: Quickshell.screens
|
||||
|
||||
PanelWindow {
|
||||
@@ -314,7 +317,7 @@ Variants {
|
||||
}
|
||||
StyledText {
|
||||
// Somehow gets fucked up if made a ClockText???
|
||||
visible: Config.options.background.quote.length > 0
|
||||
visible: Config.options.background.showQuote && Config.options.background.quote.length > 0
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: bgRoot.textHorizontalAlignment
|
||||
font {
|
||||
@@ -333,10 +336,19 @@ Variants {
|
||||
|
||||
Loader {
|
||||
id: cookieClockLoader
|
||||
visible: root.clockStyle === "cookie"
|
||||
visible: root.clockStyle === "cookie"
|
||||
active: visible
|
||||
sourceComponent: CookieClock {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: cookieQuoteLoader
|
||||
visible: root.showCookieQuote
|
||||
active: visible
|
||||
sourceComponent: CookieQuote {}
|
||||
anchors.horizontalCenter: cookieClockLoader.horizontalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
@@ -410,7 +422,7 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
// Components
|
||||
// ComponentsCookieClock {}
|
||||
component ClockText: StyledText {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: bgRoot.textHorizontalAlignment
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.functions
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property real implicitSize: 230
|
||||
property real hourHandLength: 72
|
||||
property real hourHandWidth: 16
|
||||
property real minuteHandLength: 95
|
||||
property real minuteHandWidth: 8
|
||||
property real centerDotSize: 10
|
||||
property real hourDotSize: minuteHandWidth
|
||||
|
||||
property color colShadow: Appearance.colors.colShadow
|
||||
property color colBackground: Appearance.colors.colSecondaryContainer
|
||||
property color colOnBackground: ColorUtils.mix(Appearance.colors.colPrimary, Appearance.colors.colSecondaryContainer, 0.5)
|
||||
property color colHourHand: Appearance.colors.colPrimary
|
||||
property color colMinuteHand: Appearance.colors.colSecondary
|
||||
property color colOnHourHand: Appearance.colors.colOnPrimary
|
||||
|
||||
readonly property list<string> clockNumbers: DateTime.time.split(/[: ]/)
|
||||
readonly property int clockHour: parseInt(clockNumbers[0]) % 12
|
||||
readonly property int clockMinute: parseInt(clockNumbers[1])
|
||||
implicitWidth: implicitSize
|
||||
implicitHeight: implicitSize
|
||||
|
||||
DropShadow {
|
||||
source: cookie
|
||||
anchors.fill: source
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 12
|
||||
samples: radius * 2 + 1
|
||||
color: root.colShadow
|
||||
transparentBorder: true
|
||||
}
|
||||
|
||||
MaterialCookie {
|
||||
id: cookie
|
||||
z: 0
|
||||
implicitSize: root.implicitSize
|
||||
amplitude: implicitSize / 70
|
||||
sides: 12
|
||||
color: root.colBackground
|
||||
|
||||
// 12 dots around the cookie
|
||||
Repeater {
|
||||
model: 12
|
||||
Item {
|
||||
required property int index
|
||||
rotation: 360 / 12 * index
|
||||
anchors.fill: parent
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 10
|
||||
}
|
||||
implicitWidth: root.hourDotSize
|
||||
implicitHeight: implicitWidth
|
||||
radius: implicitWidth / 2
|
||||
color: root.colOnBackground
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: timeIndicators
|
||||
z: 1
|
||||
anchors.centerIn: cookie
|
||||
spacing: -16
|
||||
|
||||
// Numbers
|
||||
Repeater {
|
||||
model: root.clockNumbers
|
||||
delegate: StyledText {
|
||||
required property string modelData
|
||||
|
||||
anchors.horizontalCenter: parent?.horizontalCenter
|
||||
font {
|
||||
pixelSize: modelData.match(/am|pm/i) ? 26 : 68
|
||||
family: Appearance.font.family.expressive
|
||||
weight: Font.Bold
|
||||
}
|
||||
color: root.colOnBackground
|
||||
text: modelData.padStart(2, "0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hour hand
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
z: 2
|
||||
rotation: -90 + (360 / 12) * (root.clockHour + root.clockMinute / 60)
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: parent.width / 2 - hourHandWidth / 2
|
||||
width: hourHandLength
|
||||
height: hourHandWidth
|
||||
radius: hourHandWidth / 2
|
||||
color: root.colHourHand
|
||||
}
|
||||
}
|
||||
|
||||
// Minute hand
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
z: 3
|
||||
rotation: -90 + (360 / 60) * root.clockMinute
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: parent.width / 2 - minuteHandWidth / 2
|
||||
width: minuteHandLength
|
||||
height: minuteHandWidth
|
||||
radius: minuteHandWidth / 2
|
||||
color: root.colMinuteHand
|
||||
}
|
||||
}
|
||||
|
||||
// Center dot
|
||||
Rectangle {
|
||||
z: 4
|
||||
color: root.colOnHourHand
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: centerDotSize
|
||||
implicitHeight: implicitWidth
|
||||
radius: implicitWidth / 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.functions
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import "./dateIndicator"
|
||||
import "./minuteMarks"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
readonly property string clockStyle: Config.options.background.clock.style
|
||||
|
||||
property real implicitSize: 230
|
||||
|
||||
property color colShadow: Appearance.colors.colShadow
|
||||
property color colBackground: Appearance.colors.colSecondaryContainer
|
||||
property color colOnBackground: ColorUtils.mix(Appearance.colors.colSecondary, Appearance.colors.colSecondaryContainer, 0.15)
|
||||
property color colBackgroundInfo: ColorUtils.mix(Appearance.colors.colPrimary, Appearance.colors.colSecondaryContainer, 0.55)
|
||||
property color colHourHand: Appearance.colors.colPrimary
|
||||
property color colMinuteHand: Appearance.colors.colSecondary
|
||||
property color colSecondHand: Appearance.colors.colTertiary
|
||||
|
||||
readonly property list<string> clockNumbers: DateTime.time.split(/[: ]/)
|
||||
readonly property int clockHour: parseInt(clockNumbers[0]) % 12
|
||||
readonly property int clockMinute: DateTime.clock.minutes
|
||||
readonly property int clockSecond: DateTime.clock.seconds
|
||||
|
||||
implicitWidth: implicitSize
|
||||
implicitHeight: implicitSize
|
||||
|
||||
DropShadow {
|
||||
source: cookie
|
||||
anchors.fill: source
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 12
|
||||
samples: radius * 2 + 1
|
||||
color: root.colShadow
|
||||
transparentBorder: true
|
||||
}
|
||||
|
||||
MaterialCookie {
|
||||
id: cookie
|
||||
z: 0
|
||||
implicitSize: root.implicitSize
|
||||
amplitude: implicitSize / 70
|
||||
sides: Config.options.background.clock.cookie.sides
|
||||
color: root.colBackground
|
||||
constantlyRotate: Config.options.background.clock.cookie.constantlyRotate
|
||||
}
|
||||
|
||||
// Hour/minutes numbers/dots/lines
|
||||
MinuteMarks {
|
||||
anchors.fill: parent
|
||||
color: root.colOnBackground
|
||||
}
|
||||
|
||||
// Stupid extra hour marks in the middle
|
||||
FadeLoader {
|
||||
id: hourMarksLoader
|
||||
anchors.centerIn: parent
|
||||
shown: Config.options.background.clock.cookie.hourMarks
|
||||
sourceComponent: HourMarks {
|
||||
implicitSize: 135 * (1.75 - 0.75 * hourMarksLoader.opacity)
|
||||
color: root.colOnBackground
|
||||
colOnBackground: ColorUtils.mix(root.colBackgroundInfo, root.colOnBackground, 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
// Number column in the middle
|
||||
FadeLoader {
|
||||
id: timeColumnLoader
|
||||
anchors.centerIn: parent
|
||||
shown: Config.options.background.clock.cookie.timeIndicators
|
||||
scale: 1.4 - 0.4 * timeColumnLoader.shown
|
||||
Behavior on scale {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
sourceComponent: TimeColumn {
|
||||
color: root.colBackgroundInfo
|
||||
}
|
||||
}
|
||||
|
||||
// Hour hand
|
||||
FadeLoader {
|
||||
anchors.fill: parent
|
||||
z: 1
|
||||
shown: Config.options.background.clock.cookie.hourHandStyle !== "hide"
|
||||
sourceComponent: HourHand {
|
||||
clockHour: root.clockHour
|
||||
clockMinute: root.clockMinute
|
||||
style: Config.options.background.clock.cookie.hourHandStyle
|
||||
color: root.colHourHand
|
||||
}
|
||||
}
|
||||
|
||||
// Minute hand
|
||||
FadeLoader {
|
||||
anchors.fill: parent
|
||||
z: 2
|
||||
shown: Config.options.background.clock.cookie.minuteHandStyle !== "hide"
|
||||
sourceComponent: MinuteHand {
|
||||
anchors.fill: parent
|
||||
clockMinute: root.clockMinute
|
||||
style: Config.options.background.clock.cookie.minuteHandStyle
|
||||
color: root.colMinuteHand
|
||||
}
|
||||
}
|
||||
|
||||
// Second hand
|
||||
FadeLoader {
|
||||
id: secondHandLoader
|
||||
z: (Config.options.background.clock.cookie.secondHandStyle === "line") ? 2 : 3
|
||||
shown: Config.options.time.secondPrecision && Config.options.background.clock.cookie.secondHandStyle !== "hide"
|
||||
anchors.fill: parent
|
||||
sourceComponent: SecondHand {
|
||||
id: secondHand
|
||||
clockSecond: root.clockSecond
|
||||
style: Config.options.background.clock.cookie.secondHandStyle
|
||||
color: root.colSecondHand
|
||||
}
|
||||
}
|
||||
|
||||
// Center dot
|
||||
FadeLoader {
|
||||
z: 4
|
||||
anchors.centerIn: parent
|
||||
shown: Config.options.background.clock.cookie.minuteHandStyle !== "bold"
|
||||
sourceComponent: Rectangle {
|
||||
color: Config.options.background.clock.cookie.minuteHandStyle === "medium" ? root.colBackground : root.colMinuteHand
|
||||
implicitWidth: 6
|
||||
implicitHeight: implicitWidth
|
||||
radius: width / 2
|
||||
}
|
||||
}
|
||||
|
||||
// Date
|
||||
FadeLoader {
|
||||
anchors.fill: parent
|
||||
shown: Config.options.background.clock.cookie.dateStyle !== "hide"
|
||||
|
||||
sourceComponent: DateIndicator {
|
||||
color: root.colBackgroundInfo
|
||||
style: Config.options.background.clock.cookie.dateStyle
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
readonly property string quoteText: Config.options.background.quote
|
||||
|
||||
implicitWidth: quoteBox.implicitWidth
|
||||
implicitHeight: quoteBox.implicitHeight
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: -24
|
||||
|
||||
DropShadow {
|
||||
source: quoteBox
|
||||
anchors.fill: quoteBox
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 12
|
||||
samples: radius * 2 + 1
|
||||
color: Appearance.colors.colShadow
|
||||
transparentBorder: true
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: quoteBox
|
||||
|
||||
implicitWidth: quoteStyledText.width + quoteIcon.width + 16 // for spacing on both sides
|
||||
implicitHeight: quoteStyledText.height + 8
|
||||
radius: Appearance.rounding.small
|
||||
color: Appearance.colors.colSecondaryContainer
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
MaterialSymbol {
|
||||
id: quoteIcon
|
||||
anchors.top: parent.top
|
||||
iconSize: Appearance.font.pixelSize.huge
|
||||
text: "format_quote"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
StyledText {
|
||||
id: quoteStyledText
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
text: Config.options.background.quote
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
font {
|
||||
family: Appearance.font.family.reading
|
||||
pixelSize: Appearance.font.pixelSize.large
|
||||
weight: Font.Normal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property int clockHour
|
||||
required property int clockMinute
|
||||
property real handLength: 72
|
||||
property real handWidth: 18
|
||||
property string style: "fill"
|
||||
property color color: Appearance.colors.colPrimary
|
||||
|
||||
property real fillColorAlpha: root.style === "hollow" ? 0 : 1
|
||||
Behavior on fillColorAlpha {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
rotation: -90 + (360 / 12) * (root.clockHour + root.clockMinute / 60)
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: (parent.width - root.handWidth) / 2 - 15 * (root.style === "classic")
|
||||
width: root.handLength
|
||||
height: root.style === "classic" ? 8 : root.handWidth
|
||||
radius: root.style === "classic" ? 2 : root.handWidth / 2
|
||||
color : Qt.rgba(root.color.r, root.color.g, root.color.b, root.fillColorAlpha)
|
||||
border.color: root.color
|
||||
border.width: 4
|
||||
|
||||
Behavior on x {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.functions
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property real implicitSize: 135
|
||||
property real markLength: 12
|
||||
property real markWidth: 4
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
property color colOnBackground: Appearance.colors.colSecondaryContainer
|
||||
property real padding: 8
|
||||
|
||||
Rectangle {
|
||||
color: root.color
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: root.implicitSize
|
||||
implicitHeight: root.implicitSize
|
||||
radius: width / 2
|
||||
|
||||
// Hour mark lines
|
||||
Repeater {
|
||||
model: 12
|
||||
|
||||
Item {
|
||||
required property int index
|
||||
anchors.fill: parent
|
||||
rotation: 360 / 12 * index
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: root.padding
|
||||
}
|
||||
implicitWidth: root.markLength
|
||||
implicitHeight: root.markWidth
|
||||
|
||||
radius: width / 2
|
||||
color: root.colOnBackground
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
required property int clockMinute
|
||||
property string style: "medium"
|
||||
property real handLength: 95
|
||||
property real handWidth: style === "bold" ? 18 : style === "medium" ? 12 : 5
|
||||
property color color: Appearance.colors.colSecondary
|
||||
|
||||
rotation: -90 + (360 / 60) * root.clockMinute
|
||||
|
||||
Behavior on rotation {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: {
|
||||
let position = parent.width / 2 - root.handWidth / 2;
|
||||
if (root.style === "classic") position -= 15;
|
||||
return position;
|
||||
}
|
||||
width: root.handLength
|
||||
height: root.handWidth
|
||||
|
||||
radius: root.style === "classic" ? 2 : root.handWidth / 2
|
||||
color: Appearance.colors.colSecondary
|
||||
|
||||
Behavior on height {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
required property int clockSecond
|
||||
property real handWidth: 2
|
||||
property real handLength: 100
|
||||
property real dotSize: 20
|
||||
property string style: "hide"
|
||||
property color color: Appearance.colors.colSecondary
|
||||
|
||||
rotation: (360 / 60 * clockSecond) + 90
|
||||
|
||||
Behavior on rotation {
|
||||
enabled: Config.options.background.clock.cookie.constantlyRotate // Animating every second is expensive...
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 10
|
||||
}
|
||||
implicitWidth: root.style === "dot" ? root.dotSize : root.handLength
|
||||
implicitHeight: root.style === "dot" ? root.dotSize : root.handWidth
|
||||
radius: Math.min(width, height) / 2
|
||||
color: root.color
|
||||
Behavior on implicitHeight {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
Behavior on implicitWidth {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
|
||||
// Classic style dot in the middle of the hand
|
||||
FadeLoader {
|
||||
id: classicDotLoader
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
shown: root.style === "classic"
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 40
|
||||
}
|
||||
implicitWidth: root.style === "classic" ? 14 : 0
|
||||
implicitHeight: implicitWidth
|
||||
color: root.color
|
||||
radius: Appearance.rounding.small
|
||||
|
||||
Behavior on implicitWidth {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.functions
|
||||
import QtQuick
|
||||
|
||||
Column {
|
||||
id: root
|
||||
property list<string> clockNumbers: DateTime.time.split(/[: ]/)
|
||||
property bool isEnabled: Config.options.background.clock.cookie.timeIndicators
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
|
||||
property bool hourMarksEnabled: Config.options.background.clock.cookie.hourMarks
|
||||
spacing: -16
|
||||
|
||||
Repeater {
|
||||
model: root.clockNumbers
|
||||
|
||||
delegate: StyledText {
|
||||
required property string modelData
|
||||
text: modelData.padStart(2, "0")
|
||||
property bool isAmPm: !text.match(/\d{2}/i)
|
||||
property real numberSizeWithoutGlow: isAmPm ? 26 : 68
|
||||
property real numberSizeWithGlow: isAmPm ? 20 : 40
|
||||
property real numberSize: root.hourMarksEnabled ? numberSizeWithGlow : numberSizeWithoutGlow
|
||||
|
||||
anchors.horizontalCenter: root.horizontalCenter
|
||||
color: root.color
|
||||
font {
|
||||
family: Appearance.font.family.expressive
|
||||
weight: Font.Bold
|
||||
pixelSize: numberSize
|
||||
}
|
||||
|
||||
Behavior on numberSize {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
property int bubbleIndex: 0
|
||||
property real targetSize: 0
|
||||
|
||||
MaterialCookie {
|
||||
z: 5
|
||||
sides: bubbleIndex === 0 ? 4 : 1
|
||||
anchors.centerIn: parent
|
||||
color: bubbleIndex === 0.0 ? Appearance.colors.colTertiaryContainer : Appearance.colors.colPrimaryContainer
|
||||
implicitSize: targetSize
|
||||
constantlyRotate: Config.options.background.clock.cookie.constantlyRotate
|
||||
}
|
||||
StyledText {
|
||||
z: 6
|
||||
anchors.centerIn: parent
|
||||
text: bubbleIndex === 0.0 ? DateTime.date.substring(5, 7) : DateTime.date.substring(8, 10)
|
||||
color: bubbleIndex === 0.0 ? Appearance.colors.colTertiary : Appearance.colors.colPrimary
|
||||
opacity: root.style === "bubble" ? 1.0 : 0
|
||||
font {
|
||||
family: Appearance.font.family.expressive
|
||||
pixelSize: 30
|
||||
weight: 1000
|
||||
}
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.functions
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string style: "bubble"
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
property real dateSquareSize: 64
|
||||
|
||||
// Rotating date
|
||||
FadeLoader {
|
||||
anchors.fill: parent
|
||||
shown: Config.options.background.clock.cookie.dateStyle === "border"
|
||||
sourceComponent: RotatingDate {
|
||||
color: root.color
|
||||
}
|
||||
}
|
||||
|
||||
// Rectangle date (only today's number) in right side of the clock
|
||||
FadeLoader {
|
||||
id: rectLoader
|
||||
shown: root.style === "rect"
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 40 - rectLoader.opacity * 30
|
||||
}
|
||||
|
||||
sourceComponent: RectangleDate {
|
||||
color: ColorUtils.mix(root.color, Appearance.colors.colSecondaryContainerHover, 0.5)
|
||||
radius: Appearance.rounding.small
|
||||
implicitWidth: 45 * rectLoader.opacity
|
||||
implicitHeight: 30 * rectLoader.opacity
|
||||
}
|
||||
}
|
||||
|
||||
// Bubble style: day of month
|
||||
FadeLoader {
|
||||
id: dayBubbleLoader
|
||||
shown: root.style === "bubble"
|
||||
property real targetSize: root.dateSquareSize * opacity
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
sourceComponent: BubbleDate {
|
||||
implicitWidth: dayBubbleLoader.targetSize
|
||||
implicitHeight: dayBubbleLoader.targetSize
|
||||
bubbleIndex: 0
|
||||
targetSize: dayBubbleLoader.targetSize
|
||||
}
|
||||
}
|
||||
|
||||
// Bubble style: month
|
||||
FadeLoader {
|
||||
id: monthBubbleLoader
|
||||
shown: root.style === "bubble"
|
||||
property real targetSize: root.dateSquareSize * opacity
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
sourceComponent: BubbleDate {
|
||||
implicitWidth: monthBubbleLoader.targetSize
|
||||
implicitHeight: monthBubbleLoader.targetSize
|
||||
bubbleIndex: 1
|
||||
targetSize: monthBubbleLoader.targetSize
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Rectangle {
|
||||
id: rect
|
||||
readonly property string dialStyle: Config.options.background.clock.cookie.dialNumberStyle
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
color: Appearance.colors.colSecondaryHover
|
||||
text: Qt.locale().toString(DateTime.clock.date, "dd")
|
||||
font {
|
||||
family: Appearance.font.family.expressive
|
||||
pixelSize: 20
|
||||
weight: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string style: Config.options.background.clock.cookie.dateStyle
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
property real angleStep: 12 * Math.PI / 180
|
||||
property string dateText: Qt.locale().toString(DateTime.clock.date, "ddd dd")
|
||||
|
||||
readonly property int clockSecond: DateTime.clock.seconds
|
||||
readonly property string dialStyle: Config.options.background.clock.cookie.dialNumberStyle
|
||||
readonly property bool timeIndicators: Config.options.background.clock.cookie.timeIndicators
|
||||
|
||||
property real radius: style === "border" ? 90 : 0
|
||||
Behavior on radius {
|
||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
rotation: {
|
||||
if (!Config.options.time.secondPrecision) return 0
|
||||
else return (360 / 60 * clockSecond) + 180 - (angleStep / Math.PI * 180 * dateText.length) / 2
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.dateText.length
|
||||
|
||||
delegate: Text {
|
||||
required property int index
|
||||
property real angle: index * root.angleStep - Math.PI / 2
|
||||
x: root.width / 2 + root.radius * Math.cos(angle) - width / 2
|
||||
y: root.height / 2 + root.radius * Math.sin(angle) - height / 2
|
||||
rotation: angle * 180 / Math.PI + 90
|
||||
|
||||
color: root.color
|
||||
font {
|
||||
family: Appearance.font.family.title
|
||||
pixelSize: 30
|
||||
weight: Font.DemiBold
|
||||
}
|
||||
|
||||
text: root.dateText.charAt(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property real numberSize: 80
|
||||
property real margins: 10
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
|
||||
property int hours: 12
|
||||
property int numbers: 4
|
||||
property int fontSize: 80
|
||||
|
||||
Repeater {
|
||||
model: root.numbers
|
||||
|
||||
Item {
|
||||
id: numberItem
|
||||
required property int index
|
||||
rotation: 360 / root.numbers * (index + 1)
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
implicitWidth: root.numberSize
|
||||
implicitHeight: implicitWidth
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
topMargin: root.margins
|
||||
}
|
||||
StyledText {
|
||||
color: root.color
|
||||
anchors.centerIn: parent
|
||||
text: root.hours / root.numbers * (numberItem.index + 1)
|
||||
rotation: -numberItem.rotation
|
||||
|
||||
font {
|
||||
family: Appearance.font.family.reading
|
||||
pixelSize: root.fontSize
|
||||
weight: Font.Black
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property real implicitSize: 12
|
||||
property real margins: 10
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
|
||||
Repeater {
|
||||
model: 12
|
||||
|
||||
Item {
|
||||
required property int index
|
||||
anchors.fill: parent // Ensures rotation works properly
|
||||
rotation: 360 / 12 * index
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: root.margins
|
||||
}
|
||||
implicitWidth: root.implicitSize
|
||||
implicitHeight: implicitWidth
|
||||
radius: implicitWidth / 2
|
||||
color: root.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property real numberSize: 80
|
||||
property real margins: 10
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
|
||||
property real hourLineSize: 4
|
||||
property real minuteLineSize: 2
|
||||
property real hourLineLength: 18
|
||||
property real minuteLineLength: 7
|
||||
|
||||
property int hours: 12
|
||||
property int minutes: 60
|
||||
|
||||
// Full dial style hour lines
|
||||
Repeater {
|
||||
model: root.hours
|
||||
|
||||
Item {
|
||||
required property int index
|
||||
rotation: 360 / root.hours * index
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: root.margins
|
||||
}
|
||||
implicitWidth: root.hourLineLength
|
||||
implicitHeight: root.hourLineSize
|
||||
radius: implicitWidth / 2
|
||||
color: root.color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Minute lines
|
||||
Repeater {
|
||||
model: root.minutes
|
||||
|
||||
Item {
|
||||
required property int index
|
||||
rotation: 360 / root.minutes * index
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: root.margins
|
||||
}
|
||||
implicitWidth: root.minuteLineLength
|
||||
implicitHeight: root.minuteLineSize
|
||||
radius: implicitWidth / 2
|
||||
color: root.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property color color: Appearance.colors.colOnSecondaryContainer
|
||||
property string style: Config.options.background.clock.cookie.dialNumberStyle // "dots", "numbers", "full", "hide"
|
||||
property string dateStyle : Config.options.background.clock.cookie.dateStyle
|
||||
|
||||
// 12 Dots
|
||||
FadeLoader {
|
||||
id: dotsLoader
|
||||
anchors.fill: parent
|
||||
shown: root.style === "dots"
|
||||
sourceComponent: Dots {
|
||||
color: root.color
|
||||
margins: 46 - dotsLoader.opacity * 34
|
||||
}
|
||||
}
|
||||
|
||||
// 3-6-9-12 hour numbers (pls don't realize you can have more than 4 numbers)
|
||||
FadeLoader {
|
||||
id: bigHourNumbersLoader
|
||||
anchors.fill: parent
|
||||
shown: root.style === "numbers"
|
||||
sourceComponent: BigHourNumbers {
|
||||
numberSize: 80
|
||||
color: root.color
|
||||
margins: 20 - 10 * bigHourNumbersLoader.opacity
|
||||
}
|
||||
}
|
||||
|
||||
// Lines
|
||||
FadeLoader {
|
||||
id: linesLoader
|
||||
anchors.fill: parent
|
||||
shown: root.style === "full"
|
||||
sourceComponent: Lines {
|
||||
color: root.color
|
||||
margins: 46 - linesLoader.opacity * 34
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -101,7 +101,7 @@ Item {
|
||||
StyledPopup {
|
||||
id: overflowPopup
|
||||
hoverTarget: trayOverflowButton
|
||||
active: root.trayOverflowOpen
|
||||
active: root.trayOverflowOpen && root.unpinnedItems.length > 0
|
||||
popupBackgroundMargin: 300 // This should be plenty... makes sure tooltips don't get cutoff (easily)
|
||||
|
||||
GridLayout {
|
||||
|
||||
@@ -129,10 +129,24 @@ Singleton {
|
||||
property bool show: true
|
||||
property string style: "cookie" // Options: "cookie", "digital"
|
||||
property real scale: 1
|
||||
property JsonObject cookie: JsonObject {
|
||||
property int sides: 14
|
||||
property string dialNumberStyle: "full" // Options: "dots" , "numbers", "full" , "none"
|
||||
property string hourHandStyle: "fill" // Options: "classic", "fill", "hollow", "hide"
|
||||
property string minuteHandStyle: "medium" // Options "classic", "thin", "medium", "bold", "hide"
|
||||
property string secondHandStyle: "dot" // Options: "dot", "line" , "hide"
|
||||
property string dateStyle: "bubble" // Options: "border", "rect", "bubble" , "hide"
|
||||
property bool timeIndicators: true
|
||||
property bool hourMarks: true
|
||||
property bool dateInClock: true
|
||||
property bool constantlyRotate: false
|
||||
}
|
||||
|
||||
}
|
||||
property string wallpaperPath: ""
|
||||
property string thumbnailPath: ""
|
||||
property string quote: ""
|
||||
property bool showQuote: false
|
||||
property bool hideWhenFullscreen: true
|
||||
property JsonObject parallax: JsonObject {
|
||||
property bool vertical: false
|
||||
@@ -315,6 +329,7 @@ Singleton {
|
||||
property JsonObject prefix: JsonObject {
|
||||
property bool showDefaultActionsWithoutPrefix: true
|
||||
property string action: "/"
|
||||
property string app: ">"
|
||||
property string clipboard: ";"
|
||||
property string emojis: ":"
|
||||
property string math: "="
|
||||
@@ -359,6 +374,7 @@ Singleton {
|
||||
property int focus: 1500
|
||||
property int longBreak: 900
|
||||
}
|
||||
property bool secondPrecision: false
|
||||
}
|
||||
|
||||
property JsonObject wallpaperSelector: JsonObject {
|
||||
|
||||
@@ -257,4 +257,32 @@ Singleton {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given prefix from the string if present.
|
||||
* @param { string } str
|
||||
* @param { string } prefix
|
||||
* @returns { string }
|
||||
*/
|
||||
function cleanPrefix(str, prefix) {
|
||||
if (str.startsWith(prefix)) {
|
||||
return str.slice(prefix.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first matching prefix from the string if present.
|
||||
* @param { string } str
|
||||
* @param { string[] } prefixes
|
||||
* @returns { string }
|
||||
*/
|
||||
function cleanOnePrefix(str, prefixes) {
|
||||
for (let i = 0; i < prefixes.length; ++i) {
|
||||
if (str.startsWith(prefixes[i])) {
|
||||
return str.slice(prefixes[i].length);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import QtQuick
|
||||
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
|
||||
Loader {
|
||||
id: root
|
||||
property bool shown: true
|
||||
opacity: shown ? 1 : 0
|
||||
visible: opacity > 0
|
||||
active: opacity > 0
|
||||
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,39 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import Quickshell
|
||||
import qs.modules.common
|
||||
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property int sides: 12
|
||||
property real sides: 12
|
||||
property int implicitSize: 100
|
||||
property real amplitude: implicitSize / 50
|
||||
property int renderPoints: 360
|
||||
property color color: "#605790"
|
||||
property alias strokeWidth: shapePath.strokeWidth
|
||||
property bool constantlyRotate: false
|
||||
|
||||
implicitWidth: implicitSize
|
||||
implicitHeight: implicitSize
|
||||
|
||||
property real shapeRotation: 0
|
||||
|
||||
Loader {
|
||||
active: constantlyRotate
|
||||
sourceComponent: FrameAnimation {
|
||||
running: true
|
||||
onTriggered: {
|
||||
shapeRotation += 0.05
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on sides {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Shape {
|
||||
id: shape
|
||||
anchors.fill: parent
|
||||
@@ -35,7 +54,8 @@ Item {
|
||||
var radius = root.implicitSize / 2 - root.amplitude
|
||||
for (var i = 0; i <= steps; i++) {
|
||||
var angle = (i / steps) * 2 * Math.PI
|
||||
var wave = Math.sin(angle * root.sides + Math.PI/2) * root.amplitude
|
||||
var rotatedAngle = angle * root.sides + Math.PI/2 + (root.shapeRotation * root.constantlyRotate)
|
||||
var wave = Math.sin(rotatedAngle) * root.amplitude
|
||||
var x = Math.cos(angle) * (radius + wave) + cx
|
||||
var y = Math.sin(angle) * (radius + wave) + cy
|
||||
points.push(Qt.point(x, y))
|
||||
@@ -45,6 +65,7 @@ Item {
|
||||
|
||||
path: pointsList
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ GroupButton {
|
||||
colBackgroundActive: Appearance.colors.colSecondaryContainerActive
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 4
|
||||
spacing: 4 * (root.buttonText?.length > 0)
|
||||
|
||||
Loader {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@@ -42,7 +42,7 @@ GroupButton {
|
||||
}
|
||||
|
||||
Item {
|
||||
implicitWidth: textItem.implicitWidth
|
||||
implicitWidth: root.buttonText?.length > 0 ? textItem.implicitWidth : 0
|
||||
implicitHeight: textMetrics.height // Force height to that of regular text
|
||||
|
||||
TextMetrics {
|
||||
|
||||
@@ -21,9 +21,7 @@ Scope {
|
||||
readonly property real osdWidth: Appearance.sizes.osdWidth
|
||||
readonly property real widgetWidth: Appearance.sizes.mediaControlsWidth
|
||||
readonly property real widgetHeight: Appearance.sizes.mediaControlsHeight
|
||||
property real contentPadding: 13
|
||||
property real popupRounding: Appearance.rounding.screenRounding - Appearance.sizes.elevationMargin + 1
|
||||
property real artRounding: Appearance.rounding.verysmall
|
||||
property list<real> visualizerPoints: []
|
||||
|
||||
property bool hasPlasmaIntegration: false
|
||||
|
||||
@@ -13,11 +13,11 @@ import Quickshell.Io
|
||||
import Quickshell.Services.Mpris
|
||||
|
||||
Item { // Player instance
|
||||
id: playerController
|
||||
id: root
|
||||
required property MprisPlayer player
|
||||
property var artUrl: player?.trackArtUrl
|
||||
property string artDownloadLocation: Directories.coverArt
|
||||
property string artFileName: Qt.md5(artUrl) + ".jpg"
|
||||
property string artFileName: Qt.md5(artUrl)
|
||||
property string artFilePath: `${artDownloadLocation}/${artFileName}`
|
||||
property color artDominantColor: ColorUtils.mix((colorQuantizer?.colors[0] ?? Appearance.colors.colPrimary), Appearance.colors.colPrimaryContainer, 0.8) || Appearance.m3colors.m3secondaryContainer
|
||||
property bool downloaded: false
|
||||
@@ -26,6 +26,8 @@ Item { // Player instance
|
||||
property int visualizerSmoothing: 2 // Number of points to average for smoothing
|
||||
property real radius
|
||||
|
||||
property string displayedArtFilePath: root.downloaded ? Qt.resolvedUrl(artFilePath) : ""
|
||||
|
||||
component TrackChangeButton: RippleButton {
|
||||
implicitWidth: 24
|
||||
implicitHeight: 24
|
||||
@@ -49,37 +51,41 @@ Item { // Player instance
|
||||
}
|
||||
|
||||
Timer { // Force update for revision
|
||||
running: playerController.player?.playbackState == MprisPlaybackState.Playing
|
||||
running: root.player?.playbackState == MprisPlaybackState.Playing
|
||||
interval: Config.options.resources.updateInterval
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
playerController.player.positionChanged()
|
||||
root.player.positionChanged()
|
||||
}
|
||||
}
|
||||
|
||||
onArtUrlChanged: {
|
||||
if (playerController.artUrl.length == 0) {
|
||||
playerController.artDominantColor = Appearance.m3colors.m3secondaryContainer
|
||||
onArtFilePathChanged: {
|
||||
if (root.artUrl.length == 0) {
|
||||
root.artDominantColor = Appearance.m3colors.m3secondaryContainer
|
||||
return;
|
||||
}
|
||||
// console.log("PlayerControl: Art URL changed to", playerController.artUrl)
|
||||
// console.log("Download cmd:", coverArtDownloader.command.join(" "))
|
||||
playerController.downloaded = false
|
||||
|
||||
// Binding does not work in Process
|
||||
coverArtDownloader.targetFile = root.artUrl
|
||||
coverArtDownloader.artFilePath = root.artFilePath
|
||||
// Download
|
||||
root.downloaded = false
|
||||
coverArtDownloader.running = true
|
||||
}
|
||||
|
||||
Process { // Cover art downloader
|
||||
id: coverArtDownloader
|
||||
property string targetFile: playerController.artUrl
|
||||
property string targetFile: root.artUrl
|
||||
property string artFilePath: root.artFilePath
|
||||
command: [ "bash", "-c", `[ -f ${artFilePath} ] || curl -sSL '${targetFile}' -o '${artFilePath}'` ]
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
playerController.downloaded = true
|
||||
root.downloaded = true
|
||||
}
|
||||
}
|
||||
|
||||
ColorQuantizer {
|
||||
id: colorQuantizer
|
||||
source: playerController.downloaded ? Qt.resolvedUrl(artFilePath) : ""
|
||||
source: root.displayedArtFilePath
|
||||
depth: 0 // 2^0 = 1 color
|
||||
rescaleSize: 1 // Rescale to 1x1 pixel for faster processing
|
||||
}
|
||||
@@ -96,7 +102,7 @@ Item { // Player instance
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.sizes.elevationMargin
|
||||
color: blendedColors.colLayer0
|
||||
radius: playerController.radius
|
||||
radius: root.radius
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
@@ -110,7 +116,7 @@ Item { // Player instance
|
||||
Image {
|
||||
id: blurredArt
|
||||
anchors.fill: parent
|
||||
source: playerController.downloaded ? Qt.resolvedUrl(artFilePath) : ""
|
||||
source: root.displayedArtFilePath
|
||||
sourceSize.width: background.width
|
||||
sourceSize.height: background.height
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
@@ -126,30 +132,30 @@ Item { // Player instance
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: ColorUtils.transparentize(blendedColors.colLayer0, 0.3)
|
||||
radius: playerController.radius
|
||||
radius: root.radius
|
||||
}
|
||||
}
|
||||
|
||||
WaveVisualizer {
|
||||
id: visualizerCanvas
|
||||
anchors.fill: parent
|
||||
live: playerController.player?.isPlaying
|
||||
points: playerController.visualizerPoints
|
||||
maxVisualizerValue: playerController.maxVisualizerValue
|
||||
smoothing: playerController.visualizerSmoothing
|
||||
live: root.player?.isPlaying
|
||||
points: root.visualizerPoints
|
||||
maxVisualizerValue: root.maxVisualizerValue
|
||||
smoothing: root.visualizerSmoothing
|
||||
color: blendedColors.colPrimary
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.contentPadding
|
||||
anchors.margins: 13
|
||||
spacing: 15
|
||||
|
||||
Rectangle { // Art background
|
||||
id: artBackground
|
||||
Layout.fillHeight: true
|
||||
implicitWidth: height
|
||||
radius: root.artRounding
|
||||
radius: Appearance.rounding.verysmall
|
||||
color: ColorUtils.transparentize(blendedColors.colLayer1, 0.5)
|
||||
|
||||
layer.enabled: true
|
||||
@@ -166,7 +172,7 @@ Item { // Player instance
|
||||
property int size: parent.height
|
||||
anchors.fill: parent
|
||||
|
||||
source: playerController.downloaded ? Qt.resolvedUrl(artFilePath) : ""
|
||||
source: root.displayedArtFilePath
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
cache: false
|
||||
antialiasing: true
|
||||
@@ -188,7 +194,7 @@ Item { // Player instance
|
||||
font.pixelSize: Appearance.font.pixelSize.large
|
||||
color: blendedColors.colOnLayer0
|
||||
elide: Text.ElideRight
|
||||
text: StringUtils.cleanMusicTitle(playerController.player?.trackTitle) || "Untitled"
|
||||
text: StringUtils.cleanMusicTitle(root.player?.trackTitle) || "Untitled"
|
||||
animateChange: true
|
||||
animationDistanceX: 6
|
||||
animationDistanceY: 0
|
||||
@@ -199,7 +205,7 @@ Item { // Player instance
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: blendedColors.colSubtext
|
||||
elide: Text.ElideRight
|
||||
text: playerController.player?.trackArtist
|
||||
text: root.player?.trackArtist
|
||||
animateChange: true
|
||||
animationDistanceX: 6
|
||||
animationDistanceY: 0
|
||||
@@ -217,7 +223,7 @@ Item { // Player instance
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
color: blendedColors.colSubtext
|
||||
elide: Text.ElideRight
|
||||
text: `${StringUtils.friendlyTimeForSeconds(playerController.player?.position)} / ${StringUtils.friendlyTimeForSeconds(playerController.player?.length)}`
|
||||
text: `${StringUtils.friendlyTimeForSeconds(root.player?.position)} / ${StringUtils.friendlyTimeForSeconds(root.player?.length)}`
|
||||
}
|
||||
RowLayout {
|
||||
id: sliderRow
|
||||
@@ -228,7 +234,7 @@ Item { // Player instance
|
||||
}
|
||||
TrackChangeButton {
|
||||
iconName: "skip_previous"
|
||||
onClicked: playerController.player?.previous()
|
||||
onClicked: root.player?.previous()
|
||||
}
|
||||
Item {
|
||||
id: progressBarContainer
|
||||
@@ -238,15 +244,15 @@ Item { // Player instance
|
||||
Loader {
|
||||
id: sliderLoader
|
||||
anchors.fill: parent
|
||||
active: playerController.player?.canSeek ?? false
|
||||
active: root.player?.canSeek ?? false
|
||||
sourceComponent: StyledSlider {
|
||||
configuration: StyledSlider.Configuration.Wavy
|
||||
highlightColor: blendedColors.colPrimary
|
||||
trackColor: blendedColors.colSecondaryContainer
|
||||
handleColor: blendedColors.colPrimary
|
||||
value: playerController.player?.position / playerController.player?.length
|
||||
value: root.player?.position / root.player?.length
|
||||
onMoved: {
|
||||
playerController.player.position = value * playerController.player.length;
|
||||
root.player.position = value * root.player.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,12 +264,12 @@ Item { // Player instance
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
active: !(playerController.player?.canSeek ?? false)
|
||||
active: !(root.player?.canSeek ?? false)
|
||||
sourceComponent: StyledProgressBar {
|
||||
wavy: playerController.player?.isPlaying
|
||||
wavy: root.player?.isPlaying
|
||||
highlightColor: blendedColors.colPrimary
|
||||
trackColor: blendedColors.colSecondaryContainer
|
||||
value: playerController.player?.position / playerController.player?.length
|
||||
value: root.player?.position / root.player?.length
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +277,7 @@ Item { // Player instance
|
||||
}
|
||||
TrackChangeButton {
|
||||
iconName: "skip_next"
|
||||
onClicked: playerController.player?.next()
|
||||
onClicked: root.player?.next()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,19 +289,19 @@ Item { // Player instance
|
||||
property real size: 44
|
||||
implicitWidth: size
|
||||
implicitHeight: size
|
||||
onClicked: playerController.player.togglePlaying();
|
||||
onClicked: root.player.togglePlaying();
|
||||
|
||||
buttonRadius: playerController.player?.isPlaying ? Appearance?.rounding.normal : size / 2
|
||||
colBackground: playerController.player?.isPlaying ? blendedColors.colPrimary : blendedColors.colSecondaryContainer
|
||||
colBackgroundHover: playerController.player?.isPlaying ? blendedColors.colPrimaryHover : blendedColors.colSecondaryContainerHover
|
||||
colRipple: playerController.player?.isPlaying ? blendedColors.colPrimaryActive : blendedColors.colSecondaryContainerActive
|
||||
buttonRadius: root.player?.isPlaying ? Appearance?.rounding.normal : size / 2
|
||||
colBackground: root.player?.isPlaying ? blendedColors.colPrimary : blendedColors.colSecondaryContainer
|
||||
colBackgroundHover: root.player?.isPlaying ? blendedColors.colPrimaryHover : blendedColors.colSecondaryContainerHover
|
||||
colRipple: root.player?.isPlaying ? blendedColors.colPrimaryActive : blendedColors.colSecondaryContainerActive
|
||||
|
||||
contentItem: MaterialSymbol {
|
||||
iconSize: Appearance.font.pixelSize.huge
|
||||
fill: 1
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: playerController.player?.isPlaying ? blendedColors.colOnPrimary : blendedColors.colOnSecondaryContainer
|
||||
text: playerController.player?.isPlaying ? "pause" : "play_arrow"
|
||||
color: root.player?.isPlaying ? blendedColors.colOnPrimary : blendedColors.colOnSecondaryContainer
|
||||
text: root.player?.isPlaying ? "pause" : "play_arrow"
|
||||
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
|
||||
@@ -327,7 +327,7 @@ Item { // Wrapper
|
||||
///////////// Special cases ///////////////
|
||||
if (root.searchingText.startsWith(Config.options.search.prefix.clipboard)) {
|
||||
// Clipboard
|
||||
const searchString = root.searchingText.slice(Config.options.search.prefix.clipboard.length);
|
||||
const searchString = StringUtils.cleanPrefix(root.searchingText, Config.options.search.prefix.clipboard);
|
||||
return Cliphist.fuzzyQuery(searchString).map((entry, index, array) => {
|
||||
const mightBlurImage = Cliphist.entryIsImage(entry) && root.clipboardWorkSafetyActive;
|
||||
let shouldBlurImage = mightBlurImage;
|
||||
@@ -365,7 +365,7 @@ Item { // Wrapper
|
||||
}
|
||||
else if (root.searchingText.startsWith(Config.options.search.prefix.emojis)) {
|
||||
// Clipboard
|
||||
const searchString = root.searchingText.slice(Config.options.search.prefix.emojis.length);
|
||||
const searchString = StringUtils.cleanPrefix(root.searchingText, Config.options.search.prefix.emojis);
|
||||
return Emojis.fuzzyQuery(searchString).map(entry => {
|
||||
return {
|
||||
cliphistRawString: entry,
|
||||
@@ -392,14 +392,20 @@ Item { // Wrapper
|
||||
Quickshell.clipboardText = root.mathResult;
|
||||
}
|
||||
};
|
||||
const appResultObjects = AppSearch.fuzzyQuery(StringUtils.cleanPrefix(root.searchingText, Config.options.search.prefix.app)).map(entry => {
|
||||
entry.clickActionName = Translation.tr("Launch");
|
||||
entry.type = Translation.tr("App");
|
||||
return entry;
|
||||
})
|
||||
const commandResultObject = {
|
||||
name: searchingText.replace("file://", ""),
|
||||
name: StringUtils.cleanPrefix(root.searchingText, Config.options.search.prefix.shellCommand).replace("file://", ""),
|
||||
clickActionName: Translation.tr("Run"),
|
||||
type: Translation.tr("Run command"),
|
||||
fontType: "monospace",
|
||||
materialSymbol: 'terminal',
|
||||
execute: () => {
|
||||
let cleanedCommand = root.searchingText.replace("file://", "");
|
||||
cleanedCommand = StringUtils.cleanPrefix(cleanedCommand, Config.options.search.prefix.shellCommand);
|
||||
if (cleanedCommand.startsWith(Config.options.search.prefix.shellCommand)) {
|
||||
cleanedCommand = cleanedCommand.slice(Config.options.search.prefix.shellCommand.length);
|
||||
}
|
||||
@@ -407,15 +413,12 @@ Item { // Wrapper
|
||||
}
|
||||
};
|
||||
const webSearchResultObject = {
|
||||
name: root.searchingText,
|
||||
name: StringUtils.cleanPrefix(root.searchingText, Config.options.search.prefix.webSearch),
|
||||
clickActionName: Translation.tr("Search"),
|
||||
type: Translation.tr("Search the web"),
|
||||
materialSymbol: 'travel_explore',
|
||||
execute: () => {
|
||||
let query = root.searchingText;
|
||||
if (query.startsWith(Config.options.search.prefix.webSearch)) {
|
||||
query = query.slice(Config.options.search.prefix.webSearch.length);
|
||||
}
|
||||
let query = StringUtils.cleanPrefix(root.searchingText, Config.options.search.prefix.webSearch);
|
||||
let url = Config.options.search.engineBaseUrl + query;
|
||||
for (let site of Config.options.search.excludedSites) {
|
||||
url += ` -site:${site}`;
|
||||
@@ -454,11 +457,7 @@ Item { // Wrapper
|
||||
}
|
||||
|
||||
//////////////// Apps //////////////////
|
||||
result = result.concat(AppSearch.fuzzyQuery(root.searchingText).map(entry => {
|
||||
entry.clickActionName = Translation.tr("Launch");
|
||||
entry.type = Translation.tr("App");
|
||||
return entry;
|
||||
}));
|
||||
result = result.concat(appResultObjects);
|
||||
|
||||
////////// Launcher actions ////////////
|
||||
result = result.concat(launcherActionObjects);
|
||||
@@ -480,7 +479,15 @@ Item { // Wrapper
|
||||
anchors.left: parent?.left
|
||||
anchors.right: parent?.right
|
||||
entry: modelData
|
||||
query: root.searchingText.startsWith(Config.options.search.prefix.clipboard) ? root.searchingText.slice(Config.options.search.prefix.clipboard.length) : root.searchingText
|
||||
query: StringUtils.cleanOnePrefix(root.searchingText, [
|
||||
Config.options.search.prefix.action,
|
||||
Config.options.search.prefix.app,
|
||||
Config.options.search.prefix.clipboard,
|
||||
Config.options.search.prefix.emojis,
|
||||
Config.options.search.prefix.math,
|
||||
Config.options.search.prefix.shellCommand,
|
||||
Config.options.search.prefix.webSearch
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,12 @@ Scope {
|
||||
|
||||
Loader {
|
||||
id: sidebarCornerOpenInteractionLoader
|
||||
active: (!cornerPanelWindow.fullscreen && Config.options.sidebar.cornerOpen.enable && (Config.options.sidebar.cornerOpen.bottom == cornerWidget.isBottom))
|
||||
active: {
|
||||
if (!Config.options.sidebar.cornerOpen.enable) return false;
|
||||
if (!Config.options.bar.vertical && Config.options.sidebar.cornerOpen.bottom == Config.options.bar.bottom) return false;
|
||||
if (cornerPanelWindow.fullscreen) return false;
|
||||
return (Config.options.sidebar.cornerOpen.bottom == cornerWidget.isBottom);
|
||||
}
|
||||
anchors {
|
||||
top: (cornerWidget.isTopLeft || cornerWidget.isTopRight) ? parent.top : undefined
|
||||
bottom: (cornerWidget.isBottomLeft || cornerWidget.isBottomRight) ? parent.bottom : undefined
|
||||
|
||||
@@ -210,6 +210,18 @@ ContentPage {
|
||||
icon: "nest_clock_farsight_analog"
|
||||
title: Translation.tr("Time")
|
||||
|
||||
ConfigSwitch {
|
||||
buttonIcon: "pace"
|
||||
text: Translation.tr("Second precision")
|
||||
checked: Config.options.time.secondPrecision
|
||||
onCheckedChanged: {
|
||||
Config.options.time.secondPrecision = checked;
|
||||
}
|
||||
StyledToolTip {
|
||||
text: Translation.tr("Enable if you want clocks to show seconds accurately")
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
title: Translation.tr("Format")
|
||||
tooltip: ""
|
||||
|
||||
@@ -20,6 +20,7 @@ ContentPage {
|
||||
Config.options.background.clock.show = checked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ConfigSpinBox {
|
||||
icon: "loupe"
|
||||
@@ -50,11 +51,277 @@ ContentPage {
|
||||
displayName: Translation.tr("Material cookie"),
|
||||
icon: "cookie",
|
||||
value: "cookie"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
title: Translation.tr("Cookie clock settings")
|
||||
ConfigSpinBox {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
icon: "add_triangle"
|
||||
text: Translation.tr("Sides")
|
||||
value: Config.options.background.clock.cookie.sides
|
||||
from: 1
|
||||
to: 36
|
||||
stepSize: 1
|
||||
onValueChanged: {
|
||||
Config.options.background.clock.cookie.sides = value;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSwitch {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
buttonIcon: "autoplay"
|
||||
text: Translation.tr("Constantly rotate")
|
||||
checked: Config.options.background.clock.cookie.constantlyRotate
|
||||
onCheckedChanged: {
|
||||
Config.options.background.clock.cookie.constantlyRotate = checked;
|
||||
}
|
||||
StyledToolTip {
|
||||
text: "Makes the clock always rotate. This is extremely expensive\n(expect 50% usage on Intel UHD Graphics) and thus impractical."
|
||||
}
|
||||
}
|
||||
|
||||
ConfigRow {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
|
||||
ConfigSwitch {
|
||||
enabled: Config.options.background.clock.style === "cookie" && Config.options.background.clock.cookie.dialNumberStyle === "dots" || Config.options.background.clock.cookie.dialNumberStyle === "full"
|
||||
buttonIcon: "brightness_7"
|
||||
text: Translation.tr("Hour marks")
|
||||
checked: Config.options.background.clock.cookie.hourMarks
|
||||
onEnabledChanged: {
|
||||
checked = Config.options.background.clock.cookie.hourMarks;
|
||||
}
|
||||
onCheckedChanged: {
|
||||
Config.options.background.clock.cookie.hourMarks = checked;
|
||||
}
|
||||
StyledToolTip {
|
||||
text: "Can only be turned on using the 'Dots' or 'Full' dial style for aesthetic reasons"
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSwitch {
|
||||
enabled: Config.options.background.clock.style === "cookie" && Config.options.background.clock.cookie.dialNumberStyle !== "numbers"
|
||||
buttonIcon: "timer_10"
|
||||
text: Translation.tr("Digits in the middle")
|
||||
checked: Config.options.background.clock.cookie.timeIndicators
|
||||
onEnabledChanged: {
|
||||
checked = Config.options.background.clock.cookie.timeIndicators;
|
||||
}
|
||||
onCheckedChanged: {
|
||||
Config.options.background.clock.cookie.timeIndicators = checked;
|
||||
}
|
||||
StyledToolTip {
|
||||
text: "Can't be turned on when using 'Numbers' dial style for aesthetic reasons"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
title: Translation.tr("Dial style")
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.clock.cookie.dialNumberStyle
|
||||
onSelected: newValue => {
|
||||
Config.options.background.clock.cookie.dialNumberStyle = newValue;
|
||||
if (newValue !== "dots" && newValue !== "full") {
|
||||
Config.options.background.clock.cookie.hourMarks = false;
|
||||
}
|
||||
if (newValue === "numbers") {
|
||||
Config.options.background.clock.cookie.timeIndicators = false;
|
||||
}
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: "",
|
||||
icon: "block",
|
||||
value: "none"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Dots"),
|
||||
icon: "graph_6",
|
||||
value: "dots"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Full"),
|
||||
icon: "history_toggle_off",
|
||||
value: "full"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Numbers"),
|
||||
icon: "counter_1",
|
||||
value: "numbers"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
title: Translation.tr("Hour hand")
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.clock.cookie.hourHandStyle
|
||||
onSelected: newValue => {
|
||||
Config.options.background.clock.cookie.hourHandStyle = newValue;
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: "",
|
||||
icon: "block",
|
||||
value: "hide"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Classic"),
|
||||
icon: "radio",
|
||||
value: "classic"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Hollow"),
|
||||
icon: "circle",
|
||||
value: "hollow"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Fill"),
|
||||
icon: "eraser_size_5",
|
||||
value: "fill"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
title: Translation.tr("Minute hand")
|
||||
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.clock.cookie.minuteHandStyle
|
||||
onSelected: newValue => {
|
||||
Config.options.background.clock.cookie.minuteHandStyle = newValue;
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: "",
|
||||
icon: "block",
|
||||
value: "hide"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Classic"),
|
||||
icon: "radio",
|
||||
value: "classic"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Thin"),
|
||||
icon: "line_end",
|
||||
value: "thin"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Medium"),
|
||||
icon: "eraser_size_2",
|
||||
value: "medium"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Bold"),
|
||||
icon: "eraser_size_4",
|
||||
value: "bold"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
title: Translation.tr("Second hand")
|
||||
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.clock.cookie.secondHandStyle
|
||||
onSelected: newValue => {
|
||||
Config.options.background.clock.cookie.secondHandStyle = newValue;
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: "",
|
||||
icon: "block",
|
||||
value: "hide"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Classic"),
|
||||
icon: "radio",
|
||||
value: "classic"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Line"),
|
||||
icon: "line_end",
|
||||
value: "line"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Dot"),
|
||||
icon: "adjust",
|
||||
value: "dot"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
visible: Config.options.background.clock.style === "cookie"
|
||||
title: Translation.tr("Date style")
|
||||
|
||||
ConfigSelectionArray {
|
||||
currentValue: Config.options.background.clock.cookie.dateStyle
|
||||
onSelected: newValue => {
|
||||
Config.options.background.clock.cookie.dateStyle = newValue;
|
||||
}
|
||||
options: [
|
||||
{
|
||||
displayName: "",
|
||||
icon: "block",
|
||||
value: "hide"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Bubble"),
|
||||
icon: "bubble_chart",
|
||||
value: "bubble"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Border"),
|
||||
icon: "rotate_right",
|
||||
value: "border"
|
||||
},
|
||||
{
|
||||
displayName: Translation.tr("Rect"),
|
||||
icon: "rectangle",
|
||||
value: "rect"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
title: Translation.tr("Quote settings")
|
||||
ConfigSwitch {
|
||||
buttonIcon: "format_quote"
|
||||
text: Translation.tr("Show quote")
|
||||
checked: Config.options.background.showQuote
|
||||
onCheckedChanged: {
|
||||
Config.options.background.showQuote = checked;
|
||||
}
|
||||
}
|
||||
MaterialTextArea {
|
||||
Layout.fillWidth: true
|
||||
placeholderText: Translation.tr("Quote")
|
||||
text: Config.options.background.quote
|
||||
wrapMode: TextEdit.Wrap
|
||||
onTextChanged: {
|
||||
Config.options.background.quote = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSubsection {
|
||||
title: Translation.tr("Wallpaper parallax")
|
||||
|
||||
@@ -121,7 +388,9 @@ ContentPage {
|
||||
font.pixelSize: Appearance.font.pixelSize.smallie
|
||||
text: Translation.tr("Press Super+G to toggle appearance")
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
id: editorButton
|
||||
buttonRadius: Appearance.rounding.full
|
||||
@@ -231,7 +500,7 @@ ContentPage {
|
||||
Config.options.lock.centerClock = checked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ConfigSwitch {
|
||||
buttonIcon: "info"
|
||||
text: Translation.tr('Show "Locked" text')
|
||||
@@ -264,8 +533,6 @@ ContentPage {
|
||||
Config.options.lock.blur.extraZoom = value / 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,5 +740,4 @@ ContentPage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ Singleton {
|
||||
property bool ready: Pipewire.defaultAudioSink?.ready ?? false
|
||||
property PwNode sink: Pipewire.defaultAudioSink
|
||||
property PwNode source: Pipewire.defaultAudioSource
|
||||
readonly property real hardMaxValue: 2.00 // People keep joking about setting volume to 5172% so...
|
||||
|
||||
signal sinkProtectionTriggered(string reason);
|
||||
|
||||
@@ -38,9 +39,9 @@ Singleton {
|
||||
|
||||
if (newVolume - lastVolume > maxAllowedIncrease) {
|
||||
sink.audio.volume = lastVolume;
|
||||
root.sinkProtectionTriggered("Illegal increment");
|
||||
} else if (newVolume > maxAllowed) {
|
||||
root.sinkProtectionTriggered("Exceeded max allowed");
|
||||
root.sinkProtectionTriggered(Translation.tr("Illegal increment"));
|
||||
} else if (newVolume > maxAllowed || newVolume > root.hardMaxValue) {
|
||||
root.sinkProtectionTriggered(Translation.tr("Exceeded max allowed"));
|
||||
sink.audio.volume = Math.min(lastVolume, maxAllowed);
|
||||
}
|
||||
if (sink.ready && (isNaN(sink.audio.volume) || sink.audio.volume === undefined || sink.audio.volume === null)) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
/**
|
||||
* A nice wrapper for date and time strings.
|
||||
@@ -12,7 +12,11 @@ pragma ComponentBehavior: Bound
|
||||
Singleton {
|
||||
property var clock: SystemClock {
|
||||
id: clock
|
||||
precision: GlobalStates.screenLocked ? SystemClock.Seconds : SystemClock.Minutes // Hack to ensure clock is correct after waking up from suspend
|
||||
precision: {
|
||||
if (Config.options.time.secondPrecision || GlobalStates.screenLocked)
|
||||
return SystemClock.Seconds;
|
||||
return SystemClock.Minutes;
|
||||
}
|
||||
}
|
||||
property string time: Qt.locale().toString(clock.date, Config.options?.time.format ?? "hh:mm")
|
||||
property string shortDate: Qt.locale().toString(clock.date, Config.options?.time.shortDateFormat ?? "dd/MM")
|
||||
@@ -25,22 +29,25 @@ Singleton {
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
fileUptime.reload()
|
||||
const textUptime = fileUptime.text()
|
||||
const uptimeSeconds = Number(textUptime.split(" ")[0] ?? 0)
|
||||
fileUptime.reload();
|
||||
const textUptime = fileUptime.text();
|
||||
const uptimeSeconds = Number(textUptime.split(" ")[0] ?? 0);
|
||||
|
||||
// Convert seconds to days, hours, and minutes
|
||||
const days = Math.floor(uptimeSeconds / 86400)
|
||||
const hours = Math.floor((uptimeSeconds % 86400) / 3600)
|
||||
const minutes = Math.floor((uptimeSeconds % 3600) / 60)
|
||||
const days = Math.floor(uptimeSeconds / 86400);
|
||||
const hours = Math.floor((uptimeSeconds % 86400) / 3600);
|
||||
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
|
||||
|
||||
// Build the formatted uptime string
|
||||
let formatted = ""
|
||||
if (days > 0) formatted += `${days}d`
|
||||
if (hours > 0) formatted += `${formatted ? ", " : ""}${hours}h`
|
||||
if (minutes > 0 || !formatted) formatted += `${formatted ? ", " : ""}${minutes}m`
|
||||
uptime = formatted
|
||||
interval = Config.options?.resources?.updateInterval ?? 3000
|
||||
let formatted = "";
|
||||
if (days > 0)
|
||||
formatted += `${days}d`;
|
||||
if (hours > 0)
|
||||
formatted += `${formatted ? ", " : ""}${hours}h`;
|
||||
if (minutes > 0 || !formatted)
|
||||
formatted += `${formatted ? ", " : ""}${minutes}m`;
|
||||
uptime = formatted;
|
||||
interval = Config.options?.resources?.updateInterval ?? 3000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,5 +56,4 @@ Singleton {
|
||||
|
||||
path: "/proc/uptime"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,21 @@ Singleton {
|
||||
Appearance.m3colors.darkmode = (Appearance.m3colors.m3background.hslLightness < 0.5)
|
||||
}
|
||||
|
||||
function resetFilePathNextTime() {
|
||||
resetFilePathNextWallpaperChange.enabled = true
|
||||
}
|
||||
|
||||
Connections {
|
||||
id: resetFilePathNextWallpaperChange
|
||||
enabled: false
|
||||
target: Config.options.background
|
||||
onWallpaperPathChanged: {
|
||||
root.filePath = ""
|
||||
root.filePath = Directories.generatedMaterialThemePath
|
||||
resetFilePathNextWallpaperChange.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: delayedFileRead
|
||||
interval: Config.options?.hacks?.arbitraryRaceConditionDelay ?? 100
|
||||
@@ -54,5 +69,6 @@ Singleton {
|
||||
const fileContent = themeFileView.text()
|
||||
root.applyColors(fileContent)
|
||||
}
|
||||
onLoadFailed: root.resetFilePathNextTime();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ printf "${STY_CYAN}Press ${STY_BG_CYAN} Ctrl+Super+T ${STY_BG_CYAN} to select a
|
||||
printf "${STY_CYAN}Press ${STY_BG_CYAN} Super+/ ${STY_CYAN} for a list of keybinds${STY_RESET}\n"
|
||||
printf "\n"
|
||||
printf "${STY_CYAN}For suggestions/hints after installation:${STY_RESET}\n"
|
||||
printf "${STY_CYAN}${STY_UNDERLINE} https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/01setup/#post-installation ${STY_RESET}\n"
|
||||
printf "${STY_CYAN}${STY_UNDERLINE} https://ii.clsty.link/en/ii-qs/01setup/#post-installation ${STY_RESET}\n"
|
||||
printf "\n"
|
||||
|
||||
case $existed_hypr_conf_firstrun in
|
||||
|
||||
Reference in New Issue
Block a user