forked from Shinonome/dots-hyprland
make bg clock draggable
This commit is contained in:
@@ -4,6 +4,7 @@ import qs
|
|||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.common.widgets.widgetCanvas
|
||||||
import qs.modules.common.functions as CF
|
import qs.modules.common.functions as CF
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
@@ -13,18 +14,11 @@ import Quickshell.Io
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
import qs.modules.background.cookieClock
|
import qs.modules.background.widgets
|
||||||
|
import qs.modules.background.widgets.clock
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
id: root
|
id: root
|
||||||
readonly property bool fixedClockPosition: Config.options.background.clock.fixedPosition
|
|
||||||
readonly property real fixedClockX: Config.options.background.clock.x
|
|
||||||
readonly property real fixedClockY: Config.options.background.clock.y
|
|
||||||
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"
|
|
||||||
readonly property real clockParallaxFactor: Config.options.background.parallax.clockFactor // 0 = full parallax, 1 = no parallax
|
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
@@ -46,9 +40,9 @@ Variants {
|
|||||||
property bool wallpaperIsVideo: Config.options.background.wallpaperPath.endsWith(".mp4") || Config.options.background.wallpaperPath.endsWith(".webm") || Config.options.background.wallpaperPath.endsWith(".mkv") || Config.options.background.wallpaperPath.endsWith(".avi") || Config.options.background.wallpaperPath.endsWith(".mov")
|
property bool wallpaperIsVideo: Config.options.background.wallpaperPath.endsWith(".mp4") || Config.options.background.wallpaperPath.endsWith(".webm") || Config.options.background.wallpaperPath.endsWith(".mkv") || Config.options.background.wallpaperPath.endsWith(".avi") || Config.options.background.wallpaperPath.endsWith(".mov")
|
||||||
property string wallpaperPath: wallpaperIsVideo ? Config.options.background.thumbnailPath : Config.options.background.wallpaperPath
|
property string wallpaperPath: wallpaperIsVideo ? Config.options.background.thumbnailPath : Config.options.background.wallpaperPath
|
||||||
property bool wallpaperSafetyTriggered: {
|
property bool wallpaperSafetyTriggered: {
|
||||||
const enabled = Config.options.workSafety.enable.wallpaper
|
const enabled = Config.options.workSafety.enable.wallpaper;
|
||||||
const sensitiveWallpaper = (CF.StringUtils.stringListContainsSubstring(wallpaperPath.toLowerCase(), Config.options.workSafety.triggerCondition.fileKeywords))
|
const sensitiveWallpaper = (CF.StringUtils.stringListContainsSubstring(wallpaperPath.toLowerCase(), Config.options.workSafety.triggerCondition.fileKeywords));
|
||||||
const sensitiveNetwork = (CF.StringUtils.stringListContainsSubstring(Network.networkName.toLowerCase(), Config.options.workSafety.triggerCondition.networkNameKeywords))
|
const sensitiveNetwork = (CF.StringUtils.stringListContainsSubstring(Network.networkName.toLowerCase(), Config.options.workSafety.triggerCondition.networkNameKeywords));
|
||||||
return enabled && sensitiveWallpaper && sensitiveNetwork;
|
return enabled && sensitiveWallpaper && sensitiveNetwork;
|
||||||
}
|
}
|
||||||
property real wallpaperToScreenRatio: Math.min(wallpaperWidth / screen.width, wallpaperHeight / screen.height)
|
property real wallpaperToScreenRatio: Math.min(wallpaperWidth / screen.width, wallpaperHeight / screen.height)
|
||||||
@@ -59,18 +53,6 @@ Variants {
|
|||||||
property real movableXSpace: ((wallpaperWidth / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.width) / 2
|
property real movableXSpace: ((wallpaperWidth / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.width) / 2
|
||||||
property real movableYSpace: ((wallpaperHeight / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.height) / 2
|
property real movableYSpace: ((wallpaperHeight / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.height) / 2
|
||||||
readonly property bool verticalParallax: (Config.options.background.parallax.autoVertical && wallpaperHeight > wallpaperWidth) || Config.options.background.parallax.vertical
|
readonly property bool verticalParallax: (Config.options.background.parallax.autoVertical && wallpaperHeight > wallpaperWidth) || Config.options.background.parallax.vertical
|
||||||
// Position
|
|
||||||
property real clockX: (modelData.width / 2)
|
|
||||||
property real clockY: (modelData.height / 2)
|
|
||||||
property var textHorizontalAlignment: {
|
|
||||||
if ((Config.options.lock.centerClock && GlobalStates.screenLocked) || wallpaperSafetyTriggered)
|
|
||||||
return Text.AlignHCenter;
|
|
||||||
if (clockX < screen.width / 3)
|
|
||||||
return Text.AlignLeft;
|
|
||||||
if (clockX > screen.width * 2 / 3)
|
|
||||||
return Text.AlignRight;
|
|
||||||
return Text.AlignHCenter;
|
|
||||||
}
|
|
||||||
// Colors
|
// Colors
|
||||||
property bool shouldBlur: (GlobalStates.screenLocked && Config.options.lock.blur.enable)
|
property bool shouldBlur: (GlobalStates.screenLocked && Config.options.lock.blur.enable)
|
||||||
property color dominantColor: Appearance.colors.colPrimary // Default, to be changed
|
property color dominantColor: Appearance.colors.colPrimary // Default, to be changed
|
||||||
@@ -97,8 +79,9 @@ Variants {
|
|||||||
right: true
|
right: true
|
||||||
}
|
}
|
||||||
color: {
|
color: {
|
||||||
if (!bgRoot.wallpaperSafetyTriggered || bgRoot.wallpaperIsVideo) return "transparent";
|
if (!bgRoot.wallpaperSafetyTriggered || bgRoot.wallpaperIsVideo)
|
||||||
return CF.ColorUtils.mix(Appearance.colors.colLayer0, Appearance.colors.colPrimary, 0.75)
|
return "transparent";
|
||||||
|
return CF.ColorUtils.mix(Appearance.colors.colLayer0, Appearance.colors.colPrimary, 0.75);
|
||||||
}
|
}
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||||
@@ -134,53 +117,15 @@ Variants {
|
|||||||
// Oversized = can be zoomed for parallax, yay
|
// Oversized = can be zoomed for parallax, yay
|
||||||
bgRoot.effectiveWallpaperScale = Math.min(bgRoot.preferredWallpaperScale, width / screenWidth, height / screenHeight);
|
bgRoot.effectiveWallpaperScale = Math.min(bgRoot.preferredWallpaperScale, width / screenWidth, height / screenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
bgRoot.updateClockPosition();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clock positioning
|
|
||||||
function updateClockPosition() {
|
|
||||||
// Somehow all this manual setting is needed to make the proc correctly use the new values
|
|
||||||
leastBusyRegionProc.path = bgRoot.wallpaperPath;
|
|
||||||
leastBusyRegionProc.contentWidth = clockLoader.implicitWidth + root.clockSizePadding * 2;
|
|
||||||
leastBusyRegionProc.contentHeight = clockLoader.implicitHeight + root.clockSizePadding * 2;
|
|
||||||
leastBusyRegionProc.horizontalPadding = bgRoot.movableXSpace + root.screenSizePadding * 2;
|
|
||||||
leastBusyRegionProc.verticalPadding = bgRoot.movableYSpace + root.screenSizePadding * 2;
|
|
||||||
leastBusyRegionProc.running = false;
|
|
||||||
leastBusyRegionProc.running = true;
|
|
||||||
}
|
|
||||||
Process {
|
|
||||||
id: leastBusyRegionProc
|
|
||||||
property string path: bgRoot.wallpaperPath
|
|
||||||
property int contentWidth: 300
|
|
||||||
property int contentHeight: 300
|
|
||||||
property int horizontalPadding: bgRoot.movableXSpace
|
|
||||||
property int verticalPadding: bgRoot.movableYSpace
|
|
||||||
command: [Quickshell.shellPath("scripts/images/least-busy-region-venv.sh"), "--screen-width", Math.round(bgRoot.screen.width / bgRoot.effectiveWallpaperScale), "--screen-height", Math.round(bgRoot.screen.height / bgRoot.effectiveWallpaperScale), "--width", contentWidth, "--height", contentHeight, "--horizontal-padding", horizontalPadding, "--vertical-padding", verticalPadding, path
|
|
||||||
// "--visual-output",
|
|
||||||
,]
|
|
||||||
stdout: StdioCollector {
|
|
||||||
id: leastBusyRegionOutputCollector
|
|
||||||
onStreamFinished: {
|
|
||||||
const output = leastBusyRegionOutputCollector.text;
|
|
||||||
// console.log("[Background] Least busy region output:", output)
|
|
||||||
if (output.length === 0)
|
|
||||||
return;
|
|
||||||
const parsedContent = JSON.parse(output);
|
|
||||||
bgRoot.clockX = parsedContent.center_x * bgRoot.effectiveWallpaperScale;
|
|
||||||
bgRoot.clockY = parsedContent.center_y * bgRoot.effectiveWallpaperScale;
|
|
||||||
bgRoot.dominantColor = parsedContent.dominant_color || Appearance.colors.colPrimary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wallpaper
|
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
// Wallpaper
|
||||||
StyledImage {
|
StyledImage {
|
||||||
id: wallpaper
|
id: wallpaper
|
||||||
visible: opacity > 0 && !blurLoader.active
|
visible: opacity > 0 && !blurLoader.active
|
||||||
@@ -261,25 +206,23 @@ Variants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The clock
|
WidgetCanvas {
|
||||||
Loader {
|
id: widgetCanvas
|
||||||
id: clockLoader
|
|
||||||
scale: Config.options.background.clock.scale
|
|
||||||
active: Config.options.background.clock.show
|
|
||||||
anchors {
|
anchors {
|
||||||
left: wallpaper.left
|
left: wallpaper.left
|
||||||
|
right: wallpaper.right
|
||||||
top: wallpaper.top
|
top: wallpaper.top
|
||||||
horizontalCenter: undefined
|
bottom: wallpaper.bottom
|
||||||
verticalCenter: undefined
|
readonly property real parallaxFactor: Config.options.background.parallax.widgetsFactor
|
||||||
leftMargin: {
|
leftMargin: {
|
||||||
const clockXOnWallpaper = bgRoot.movableXSpace + ((root.fixedClockPosition ? root.fixedClockX : bgRoot.clockX * bgRoot.effectiveWallpaperScale) - implicitWidth / 2)
|
const xOnWallpaper = bgRoot.movableXSpace;
|
||||||
const extraMove = (wallpaper.effectiveValueX * 2 * bgRoot.movableXSpace) * (root.clockParallaxFactor - 1);
|
const extraMove = (wallpaper.effectiveValueX * 2 * bgRoot.movableXSpace) * (parallaxFactor - 1);
|
||||||
return clockXOnWallpaper - extraMove;
|
return xOnWallpaper - extraMove;
|
||||||
}
|
}
|
||||||
topMargin: {
|
topMargin: {
|
||||||
const clockYOnWallpaper = bgRoot.movableYSpace + ((root.fixedClockPosition ? root.fixedClockY : bgRoot.clockY * bgRoot.effectiveWallpaperScale) - implicitHeight / 2)
|
const yOnWallpaper = bgRoot.movableYSpace;
|
||||||
const extraMove = (wallpaper.effectiveValueY * 2 * bgRoot.movableYSpace) * (root.clockParallaxFactor - 1);
|
const extraMove = (wallpaper.effectiveValueY * 2 * bgRoot.movableYSpace) * (parallaxFactor - 1);
|
||||||
return clockYOnWallpaper - extraMove;
|
return yOnWallpaper - extraMove;
|
||||||
}
|
}
|
||||||
Behavior on leftMargin {
|
Behavior on leftMargin {
|
||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
@@ -288,193 +231,54 @@ Variants {
|
|||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
width: wallpaper.width
|
||||||
|
height: wallpaper.height
|
||||||
states: State {
|
states: State {
|
||||||
name: "centered"
|
name: "centered"
|
||||||
when: (GlobalStates.screenLocked && Config.options.lock.centerClock) || bgRoot.wallpaperSafetyTriggered
|
when: GlobalStates.screenLocked || bgRoot.wallpaperSafetyTriggered
|
||||||
|
PropertyChanges {
|
||||||
|
target: widgetCanvas
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
AnchorChanges {
|
AnchorChanges {
|
||||||
target: clockLoader
|
target: widgetCanvas
|
||||||
anchors {
|
anchors {
|
||||||
left: undefined
|
left: undefined
|
||||||
right: undefined
|
right: undefined
|
||||||
top: undefined
|
top: undefined
|
||||||
verticalCenter: parent.verticalCenter
|
bottom: undefined
|
||||||
horizontalCenter: parent.horizontalCenter
|
// horizontalCenter: parent.horizontalCenter
|
||||||
|
// verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transitions: Transition {
|
transitions: Transition {
|
||||||
|
PropertyAnimation {
|
||||||
|
properties: "width,height"
|
||||||
|
duration: Appearance.animation.elementMove.duration
|
||||||
|
easing.type: Appearance.animation.elementMove.type
|
||||||
|
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
||||||
|
}
|
||||||
AnchorAnimation {
|
AnchorAnimation {
|
||||||
duration: Appearance.animation.elementMove.duration
|
duration: Appearance.animation.elementMove.duration
|
||||||
easing.type: Appearance.animation.elementMove.type
|
easing.type: Appearance.animation.elementMove.type
|
||||||
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceComponent: Column {
|
|
||||||
Loader {
|
|
||||||
id: digitalClockLoader
|
|
||||||
visible: root.clockStyle === "digital"
|
|
||||||
active: visible
|
|
||||||
sourceComponent: ColumnLayout {
|
|
||||||
id: clockColumn
|
|
||||||
spacing: 6
|
|
||||||
|
|
||||||
ClockText {
|
FadeLoader {
|
||||||
font.pixelSize: 90
|
shown: Config.options.background.widgets.clock.enable
|
||||||
text: DateTime.time
|
sourceComponent: ClockWidget {
|
||||||
}
|
screenWidth: bgRoot.screen.width
|
||||||
ClockText {
|
screenHeight: bgRoot.screen.height
|
||||||
Layout.topMargin: -5
|
scaledScreenWidth: bgRoot.screen.width / bgRoot.effectiveWallpaperScale
|
||||||
text: DateTime.date
|
scaledScreenHeight: bgRoot.screen.height / bgRoot.effectiveWallpaperScale
|
||||||
}
|
wallpaperScale: bgRoot.effectiveWallpaperScale
|
||||||
StyledText {
|
wallpaperSafetyTriggered: bgRoot.wallpaperSafetyTriggered
|
||||||
// Somehow gets fucked up if made a ClockText???
|
|
||||||
visible: Config.options.background.showQuote && Config.options.background.quote.length > 0
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: bgRoot.textHorizontalAlignment
|
|
||||||
font {
|
|
||||||
pixelSize: Appearance.font.pixelSize.normal
|
|
||||||
weight: 350
|
|
||||||
}
|
|
||||||
color: bgRoot.colText
|
|
||||||
style: Text.Raised
|
|
||||||
styleColor: Appearance.colors.colShadow
|
|
||||||
text: Config.options.background.quote
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: cookieClockLoader
|
|
||||||
visible: root.clockStyle === "cookie"
|
|
||||||
active: visible
|
|
||||||
sourceComponent: CookieClock {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: cookieQuoteLoader
|
|
||||||
visible: root.showCookieQuote
|
|
||||||
active: visible
|
|
||||||
sourceComponent: CookieQuote {}
|
|
||||||
anchors.horizontalCenter: cookieClockLoader.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors {
|
|
||||||
top: clockLoader.bottom
|
|
||||||
topMargin: 8
|
|
||||||
horizontalCenter: (bgRoot.textHorizontalAlignment === Text.AlignHCenter || root.clockStyle === "cookie") ? clockLoader.horizontalCenter : undefined
|
|
||||||
left: (bgRoot.textHorizontalAlignment === Text.AlignLeft) ? clockLoader.left : undefined
|
|
||||||
right: (bgRoot.textHorizontalAlignment === Text.AlignRight) ? clockLoader.right : undefined
|
|
||||||
leftMargin: -26
|
|
||||||
rightMargin: -26
|
|
||||||
}
|
|
||||||
implicitWidth: statusTextBg.implicitWidth
|
|
||||||
implicitHeight: statusTextBg.implicitHeight
|
|
||||||
|
|
||||||
StyledRectangularShadow {
|
|
||||||
target: statusTextBg
|
|
||||||
visible: statusTextBg.visible && root.clockStyle === "cookie"
|
|
||||||
opacity: statusTextBg.opacity
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: statusTextBg
|
|
||||||
anchors.centerIn: parent
|
|
||||||
clip: true
|
|
||||||
opacity: (safetyStatusText.shown || lockStatusText.shown) ? 1 : 0
|
|
||||||
visible: opacity > 0
|
|
||||||
implicitHeight: statusTextRow.implicitHeight + 5 * 2
|
|
||||||
implicitWidth: statusTextRow.implicitWidth + 5 * 2
|
|
||||||
radius: Appearance.rounding.small
|
|
||||||
color: CF.ColorUtils.transparentize(Appearance.colors.colSecondaryContainer, root.clockStyle === "cookie" ? 0 : 1)
|
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
|
||||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
Behavior on implicitHeight {
|
|
||||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
Behavior on opacity {
|
|
||||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: statusTextRow
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 14
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: bgRoot.textHorizontalAlignment !== Text.AlignLeft
|
|
||||||
implicitWidth: 1
|
|
||||||
}
|
|
||||||
ClockStatusText {
|
|
||||||
id: safetyStatusText
|
|
||||||
shown: bgRoot.wallpaperSafetyTriggered
|
|
||||||
statusIcon: "hide_image"
|
|
||||||
statusText: Translation.tr("Wallpaper safety enforced")
|
|
||||||
}
|
|
||||||
ClockStatusText {
|
|
||||||
id: lockStatusText
|
|
||||||
shown: GlobalStates.screenLocked && Config.options.lock.showLockedText
|
|
||||||
statusIcon: "lock"
|
|
||||||
statusText: Translation.tr("Locked")
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: bgRoot.textHorizontalAlignment !== Text.AlignRight
|
|
||||||
implicitWidth: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComponentsCookieClock {}
|
|
||||||
component ClockText: StyledText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: bgRoot.textHorizontalAlignment
|
|
||||||
font {
|
|
||||||
family: Appearance.font.family.expressive
|
|
||||||
pixelSize: 20
|
|
||||||
weight: Font.DemiBold
|
|
||||||
}
|
|
||||||
color: bgRoot.colText
|
|
||||||
style: Text.Raised
|
|
||||||
styleColor: Appearance.colors.colShadow
|
|
||||||
animateChange: Config.options.background.clock.digital.animateChange
|
|
||||||
}
|
|
||||||
component ClockStatusText: Row {
|
|
||||||
id: statusTextRow
|
|
||||||
property alias statusIcon: statusIconWidget.text
|
|
||||||
property alias statusText: statusTextWidget.text
|
|
||||||
property bool shown: true
|
|
||||||
property color textColor: root.clockStyle === "cookie" ? Appearance.colors.colOnSecondaryContainer : bgRoot.colText
|
|
||||||
opacity: shown ? 1 : 0
|
|
||||||
visible: opacity > 0
|
|
||||||
Behavior on opacity {
|
|
||||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
spacing: 4
|
|
||||||
MaterialSymbol {
|
|
||||||
id: statusIconWidget
|
|
||||||
anchors.verticalCenter: statusTextRow.verticalCenter
|
|
||||||
iconSize: Appearance.font.pixelSize.huge
|
|
||||||
color: statusTextRow.textColor
|
|
||||||
style: Text.Raised
|
|
||||||
styleColor: Appearance.colors.colShadow
|
|
||||||
}
|
|
||||||
ClockText {
|
|
||||||
id: statusTextWidget
|
|
||||||
color: statusTextRow.textColor
|
|
||||||
anchors.verticalCenter: statusTextRow.verticalCenter
|
|
||||||
font {
|
|
||||||
pixelSize: Appearance.font.pixelSize.large
|
|
||||||
weight: Font.Normal
|
|
||||||
}
|
|
||||||
style: Text.Raised
|
|
||||||
styleColor: Appearance.colors.colShadow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.common.widgets.widgetCanvas
|
||||||
|
|
||||||
|
AbstractWidget {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property string configEntryName
|
||||||
|
required property int screenWidth
|
||||||
|
required property int screenHeight
|
||||||
|
required property int scaledScreenWidth
|
||||||
|
required property int scaledScreenHeight
|
||||||
|
required property real wallpaperScale
|
||||||
|
property bool visibleWhenLocked: false
|
||||||
|
property var configEntry: Config.options.background.widgets[configEntryName]
|
||||||
|
property string placementStrategy: configEntry.placementStrategy
|
||||||
|
property real targetX: Math.max(0, Math.min(configEntry.x, scaledScreenWidth - width))
|
||||||
|
property real targetY : Math.max(0, Math.min(configEntry.y, scaledScreenHeight - height))
|
||||||
|
x: targetX
|
||||||
|
y: targetY
|
||||||
|
visible: opacity > 0
|
||||||
|
opacity: (GlobalStates.screenLocked && !visibleWhenLocked) ? 0 : 1
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
draggable: placementStrategy === "free"
|
||||||
|
onReleased: {
|
||||||
|
root.targetX = root.x;
|
||||||
|
root.targetY = root.y;
|
||||||
|
configEntry.x = root.targetX;
|
||||||
|
configEntry.y = root.targetY ;
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool needsColText: false
|
||||||
|
property color dominantColor: Appearance.colors.colPrimary
|
||||||
|
property bool dominantColorIsDark: dominantColor.hslLightness < 0.5
|
||||||
|
property color colText: {
|
||||||
|
const onNormalBackground = (GlobalStates.screenLocked && Config.options.lock.blur.enable)
|
||||||
|
const adaptiveColor = ColorUtils.colorWithLightness(Appearance.colors.colPrimary, (dominantColorIsDark ? 0.8 : 0.12))
|
||||||
|
return onNormalBackground ? Appearance.colors.colOnLayer0 : adaptiveColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool wallpaperIsVideo: Config.options.background.wallpaperPath.endsWith(".mp4") || Config.options.background.wallpaperPath.endsWith(".webm") || Config.options.background.wallpaperPath.endsWith(".mkv") || Config.options.background.wallpaperPath.endsWith(".avi") || Config.options.background.wallpaperPath.endsWith(".mov")
|
||||||
|
property string wallpaperPath: wallpaperIsVideo ? Config.options.background.thumbnailPath : Config.options.background.wallpaperPath
|
||||||
|
|
||||||
|
onWallpaperPathChanged: refreshPlacementIfNeeded()
|
||||||
|
onPlacementStrategyChanged: refreshPlacementIfNeeded()
|
||||||
|
Connections {
|
||||||
|
target: Config
|
||||||
|
function onReadyChanged() { refreshPlacementIfNeeded() }
|
||||||
|
}
|
||||||
|
function refreshPlacementIfNeeded() {
|
||||||
|
if (!Config.ready || (root.placementStrategy === "free" && root.needsColText)) return;
|
||||||
|
leastBusyRegionProc.wallpaperPath = root.wallpaperPath;
|
||||||
|
leastBusyRegionProc.running = false;
|
||||||
|
leastBusyRegionProc.running = true;
|
||||||
|
}
|
||||||
|
Process {
|
||||||
|
id: leastBusyRegionProc
|
||||||
|
property string wallpaperPath: root.wallpaperPath
|
||||||
|
// TODO: make these less arbitrary
|
||||||
|
property int contentWidth: 300
|
||||||
|
property int contentHeight: 300
|
||||||
|
property int horizontalPadding: 200
|
||||||
|
property int verticalPadding: 200
|
||||||
|
command: [Quickshell.shellPath("scripts/images/least-busy-region-venv.sh") // Comments to force the formatter to break lines
|
||||||
|
, "--screen-width", Math.round(root.scaledScreenWidth) //
|
||||||
|
, "--screen-height", Math.round(root.scaledScreenHeight) //
|
||||||
|
, "--width", contentWidth //
|
||||||
|
, "--height", contentHeight //
|
||||||
|
, "--horizontal-padding", horizontalPadding //
|
||||||
|
, "--vertical-padding", verticalPadding //
|
||||||
|
, wallpaperPath //
|
||||||
|
, ...(root.placementStrategy === "mostBusy" ? ["--busiest"] : [])
|
||||||
|
// "--visual-output",
|
||||||
|
]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: leastBusyRegionOutputCollector
|
||||||
|
onStreamFinished: {
|
||||||
|
const output = leastBusyRegionOutputCollector.text;
|
||||||
|
// console.log("[Background] Least busy region output:", output)
|
||||||
|
if (output.length === 0) return;
|
||||||
|
const parsedContent = JSON.parse(output);
|
||||||
|
root.dominantColor = parsedContent.dominant_color || Appearance.colors.colPrimary;
|
||||||
|
if (root.placementStrategy === "free") return;
|
||||||
|
root.targetX = parsedContent.center_x * root.wallpaperScale - root.width / 2;
|
||||||
|
root.targetY = parsedContent.center_y * root.wallpaperScale - root.height / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.common.widgets.widgetCanvas
|
||||||
|
import qs.modules.background.widgets
|
||||||
|
|
||||||
|
AbstractBackgroundWidget {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
configEntryName: "clock"
|
||||||
|
|
||||||
|
implicitHeight: contentColumn.implicitHeight
|
||||||
|
implicitWidth: contentColumn.implicitWidth
|
||||||
|
|
||||||
|
property string clockStyle: Config.options.background.widgets.clock.style
|
||||||
|
property bool forceCenter: (GlobalStates.screenLocked && Config.options.lock.centerClock)
|
||||||
|
property bool wallpaperSafetyTriggered: false
|
||||||
|
needsColText: clockStyle === "digital"
|
||||||
|
x: forceCenter ? ((root.screenWidth - root.width) / 2) : targetX
|
||||||
|
y: forceCenter ? ((root.screenHeight - root.height) / 2) : targetY
|
||||||
|
visibleWhenLocked: true
|
||||||
|
|
||||||
|
property var textHorizontalAlignment: {
|
||||||
|
if (root.forceCenter)
|
||||||
|
return Text.AlignHCenter;
|
||||||
|
if (root.x < root.scaledScreenWidth / 3)
|
||||||
|
return Text.AlignLeft;
|
||||||
|
if (root.x > root.scaledScreenWidth * 2 / 3)
|
||||||
|
return Text.AlignRight;
|
||||||
|
return Text.AlignHCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: contentColumn
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
FadeLoader {
|
||||||
|
id: cookieClockLoader
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
shown: root.clockStyle === "cookie"
|
||||||
|
sourceComponent: Column {
|
||||||
|
CookieClock {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
FadeLoader {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
shown: Config.options.background.showQuote && Config.options.background.quote !== ""
|
||||||
|
sourceComponent: CookieQuote {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FadeLoader {
|
||||||
|
id: digitalClockLoader
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
shown: root.clockStyle === "digital"
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
id: clockColumn
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
ClockText {
|
||||||
|
font.pixelSize: 90
|
||||||
|
text: DateTime.time
|
||||||
|
}
|
||||||
|
ClockText {
|
||||||
|
Layout.topMargin: -5
|
||||||
|
text: DateTime.date
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
// Somehow gets fucked up if made a ClockText???
|
||||||
|
visible: Config.options.background.showQuote && Config.options.background.quote.length > 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: root.textHorizontalAlignment
|
||||||
|
font {
|
||||||
|
pixelSize: Appearance.font.pixelSize.normal
|
||||||
|
weight: 350
|
||||||
|
}
|
||||||
|
color: root.colText
|
||||||
|
style: Text.Raised
|
||||||
|
styleColor: Appearance.colors.colShadow
|
||||||
|
text: Config.options.background.quote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: statusText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
implicitHeight: statusTextBg.implicitHeight
|
||||||
|
implicitWidth: statusTextBg.implicitWidth
|
||||||
|
StyledRectangularShadow {
|
||||||
|
target: statusTextBg
|
||||||
|
visible: statusTextBg.visible && root.clockStyle === "cookie"
|
||||||
|
opacity: statusTextBg.opacity
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: statusTextBg
|
||||||
|
anchors.centerIn: parent
|
||||||
|
clip: true
|
||||||
|
opacity: (safetyStatusText.shown || lockStatusText.shown) ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
|
implicitHeight: statusTextRow.implicitHeight + 5 * 2
|
||||||
|
implicitWidth: statusTextRow.implicitWidth + 5 * 2
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
color: ColorUtils.transparentize(Appearance.colors.colSecondaryContainer, root.clockStyle === "cookie" ? 0 : 1)
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: statusTextRow
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 14
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: root.textHorizontalAlignment !== Text.AlignLeft
|
||||||
|
implicitWidth: 1
|
||||||
|
}
|
||||||
|
ClockStatusText {
|
||||||
|
id: safetyStatusText
|
||||||
|
shown: root.wallpaperSafetyTriggered
|
||||||
|
statusIcon: "hide_image"
|
||||||
|
statusText: Translation.tr("Wallpaper safety enforced")
|
||||||
|
}
|
||||||
|
ClockStatusText {
|
||||||
|
id: lockStatusText
|
||||||
|
shown: GlobalStates.screenLocked && Config.options.lock.showLockedText
|
||||||
|
statusIcon: "lock"
|
||||||
|
statusText: Translation.tr("Locked")
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: root.textHorizontalAlignment !== Text.AlignRight
|
||||||
|
implicitWidth: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component ClockText: StyledText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: root.textHorizontalAlignment
|
||||||
|
font {
|
||||||
|
family: Appearance.font.family.expressive
|
||||||
|
pixelSize: 20
|
||||||
|
weight: Font.DemiBold
|
||||||
|
}
|
||||||
|
color: root.colText
|
||||||
|
style: Text.Raised
|
||||||
|
styleColor: Appearance.colors.colShadow
|
||||||
|
animateChange: Config.options.background.widgets.clock.digital.animateChange
|
||||||
|
}
|
||||||
|
component ClockStatusText: Row {
|
||||||
|
id: statusTextRow
|
||||||
|
property alias statusIcon: statusIconWidget.text
|
||||||
|
property alias statusText: statusTextWidget.text
|
||||||
|
property bool shown: true
|
||||||
|
property color textColor: root.clockStyle === "cookie" ? Appearance.colors.colOnSecondaryContainer : root.colText
|
||||||
|
opacity: shown ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
spacing: 4
|
||||||
|
MaterialSymbol {
|
||||||
|
id: statusIconWidget
|
||||||
|
anchors.verticalCenter: statusTextRow.verticalCenter
|
||||||
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
|
color: statusTextRow.textColor
|
||||||
|
style: Text.Raised
|
||||||
|
styleColor: Appearance.colors.colShadow
|
||||||
|
}
|
||||||
|
ClockText {
|
||||||
|
id: statusTextWidget
|
||||||
|
color: statusTextRow.textColor
|
||||||
|
anchors.verticalCenter: statusTextRow.verticalCenter
|
||||||
|
font {
|
||||||
|
pixelSize: Appearance.font.pixelSize.large
|
||||||
|
weight: Font.Normal
|
||||||
|
}
|
||||||
|
style: Text.Raised
|
||||||
|
styleColor: Appearance.colors.colShadow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
-27
@@ -9,13 +9,13 @@ import QtQuick.Layouts
|
|||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
|
|
||||||
import qs.modules.background.cookieClock.dateIndicator
|
import qs.modules.background.widgets.clock.dateIndicator
|
||||||
import qs.modules.background.cookieClock.minuteMarks
|
import qs.modules.background.widgets.clock.minuteMarks
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property string clockStyle: Config.options.background.clock.style
|
readonly property string clockStyle: Config.options.background.widgets.clock.style
|
||||||
|
|
||||||
property real implicitSize: 230
|
property real implicitSize: 230
|
||||||
|
|
||||||
@@ -36,16 +36,16 @@ Item {
|
|||||||
implicitHeight: implicitSize
|
implicitHeight: implicitSize
|
||||||
|
|
||||||
function applyStyle(sides, dialStyle, hourHandStyle, minuteHandStyle, secondHandStyle, dateStyle) {
|
function applyStyle(sides, dialStyle, hourHandStyle, minuteHandStyle, secondHandStyle, dateStyle) {
|
||||||
Config.options.background.clock.cookie.sides = sides
|
Config.options.background.widgets.clock.cookie.sides = sides
|
||||||
Config.options.background.clock.cookie.dialNumberStyle = dialStyle
|
Config.options.background.widgets.clock.cookie.dialNumberStyle = dialStyle
|
||||||
Config.options.background.clock.cookie.hourHandStyle = hourHandStyle
|
Config.options.background.widgets.clock.cookie.hourHandStyle = hourHandStyle
|
||||||
Config.options.background.clock.cookie.minuteHandStyle = minuteHandStyle
|
Config.options.background.widgets.clock.cookie.minuteHandStyle = minuteHandStyle
|
||||||
Config.options.background.clock.cookie.secondHandStyle = secondHandStyle
|
Config.options.background.widgets.clock.cookie.secondHandStyle = secondHandStyle
|
||||||
Config.options.background.clock.cookie.dateStyle = dateStyle
|
Config.options.background.widgets.clock.cookie.dateStyle = dateStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
function setClockPreset(category) {
|
function setClockPreset(category) {
|
||||||
if (!Config.options.background.clock.cookie.aiStyling) return;
|
if (!Config.options.background.widgets.clock.cookie.aiStyling) return;
|
||||||
if (category === "") return;
|
if (category === "") return;
|
||||||
print("[Cookie clock] Setting clock preset for category: " + category)
|
print("[Cookie clock] Setting clock preset for category: " + category)
|
||||||
// "abstract", "anime", "city", "minimalist", "landscape", "plants", "person", "space"
|
// "abstract", "anime", "city", "minimalist", "landscape", "plants", "person", "space"
|
||||||
@@ -83,7 +83,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool useSineCookie: Config.options.background.clock.cookie.useSineCookie
|
property bool useSineCookie: Config.options.background.widgets.clock.cookie.useSineCookie
|
||||||
DropShadow {
|
DropShadow {
|
||||||
source: useSineCookie ? sineCookieLoader : roundedPolygonCookieLoader
|
source: useSineCookie ? sineCookieLoader : roundedPolygonCookieLoader
|
||||||
anchors.fill: source
|
anchors.fill: source
|
||||||
@@ -93,7 +93,7 @@ Item {
|
|||||||
transparentBorder: true
|
transparentBorder: true
|
||||||
|
|
||||||
RotationAnimation on rotation {
|
RotationAnimation on rotation {
|
||||||
running: Config.options.background.clock.cookie.constantlyRotate
|
running: Config.options.background.widgets.clock.cookie.constantlyRotate
|
||||||
duration: 30000
|
duration: 30000
|
||||||
easing.type: Easing.Linear
|
easing.type: Easing.Linear
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
@@ -108,7 +108,7 @@ Item {
|
|||||||
active: useSineCookie
|
active: useSineCookie
|
||||||
sourceComponent: SineCookie {
|
sourceComponent: SineCookie {
|
||||||
implicitSize: root.implicitSize
|
implicitSize: root.implicitSize
|
||||||
sides: Config.options.background.clock.cookie.sides
|
sides: Config.options.background.widgets.clock.cookie.sides
|
||||||
color: root.colBackground
|
color: root.colBackground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ Item {
|
|||||||
active: !useSineCookie
|
active: !useSineCookie
|
||||||
sourceComponent: MaterialCookie {
|
sourceComponent: MaterialCookie {
|
||||||
implicitSize: root.implicitSize
|
implicitSize: root.implicitSize
|
||||||
sides: Config.options.background.clock.cookie.sides
|
sides: Config.options.background.widgets.clock.cookie.sides
|
||||||
color: root.colBackground
|
color: root.colBackground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ Item {
|
|||||||
FadeLoader {
|
FadeLoader {
|
||||||
id: hourMarksLoader
|
id: hourMarksLoader
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
shown: Config.options.background.clock.cookie.hourMarks
|
shown: Config.options.background.widgets.clock.cookie.hourMarks
|
||||||
sourceComponent: HourMarks {
|
sourceComponent: HourMarks {
|
||||||
implicitSize: 135 * (1.75 - 0.75 * hourMarksLoader.opacity)
|
implicitSize: 135 * (1.75 - 0.75 * hourMarksLoader.opacity)
|
||||||
color: root.colOnBackground
|
color: root.colOnBackground
|
||||||
@@ -146,7 +146,7 @@ Item {
|
|||||||
FadeLoader {
|
FadeLoader {
|
||||||
id: timeColumnLoader
|
id: timeColumnLoader
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
shown: Config.options.background.clock.cookie.timeIndicators
|
shown: Config.options.background.widgets.clock.cookie.timeIndicators
|
||||||
scale: 1.4 - 0.4 * timeColumnLoader.shown
|
scale: 1.4 - 0.4 * timeColumnLoader.shown
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementResize.numberAnimation.createObject(this)
|
||||||
@@ -161,11 +161,11 @@ Item {
|
|||||||
FadeLoader {
|
FadeLoader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: 1
|
z: 1
|
||||||
shown: Config.options.background.clock.cookie.minuteHandStyle !== "hide"
|
shown: Config.options.background.widgets.clock.cookie.minuteHandStyle !== "hide"
|
||||||
sourceComponent: MinuteHand {
|
sourceComponent: MinuteHand {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clockMinute: root.clockMinute
|
clockMinute: root.clockMinute
|
||||||
style: Config.options.background.clock.cookie.minuteHandStyle
|
style: Config.options.background.widgets.clock.cookie.minuteHandStyle
|
||||||
color: root.colMinuteHand
|
color: root.colMinuteHand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,11 +174,11 @@ Item {
|
|||||||
FadeLoader {
|
FadeLoader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: item?.style === "hollow" ? 0 : 2
|
z: item?.style === "hollow" ? 0 : 2
|
||||||
shown: Config.options.background.clock.cookie.hourHandStyle !== "hide"
|
shown: Config.options.background.widgets.clock.cookie.hourHandStyle !== "hide"
|
||||||
sourceComponent: HourHand {
|
sourceComponent: HourHand {
|
||||||
clockHour: root.clockHour
|
clockHour: root.clockHour
|
||||||
clockMinute: root.clockMinute
|
clockMinute: root.clockMinute
|
||||||
style: Config.options.background.clock.cookie.hourHandStyle
|
style: Config.options.background.widgets.clock.cookie.hourHandStyle
|
||||||
color: root.colHourHand
|
color: root.colHourHand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,13 +186,13 @@ Item {
|
|||||||
// Second hand
|
// Second hand
|
||||||
FadeLoader {
|
FadeLoader {
|
||||||
id: secondHandLoader
|
id: secondHandLoader
|
||||||
z: (Config.options.background.clock.cookie.secondHandStyle === "line") ? 2 : 3
|
z: (Config.options.background.widgets.clock.cookie.secondHandStyle === "line") ? 2 : 3
|
||||||
shown: Config.options.time.secondPrecision && Config.options.background.clock.cookie.secondHandStyle !== "hide"
|
shown: Config.options.time.secondPrecision && Config.options.background.widgets.clock.cookie.secondHandStyle !== "hide"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceComponent: SecondHand {
|
sourceComponent: SecondHand {
|
||||||
id: secondHand
|
id: secondHand
|
||||||
clockSecond: root.clockSecond
|
clockSecond: root.clockSecond
|
||||||
style: Config.options.background.clock.cookie.secondHandStyle
|
style: Config.options.background.widgets.clock.cookie.secondHandStyle
|
||||||
color: root.colSecondHand
|
color: root.colSecondHand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,9 +201,9 @@ Item {
|
|||||||
FadeLoader {
|
FadeLoader {
|
||||||
z: 4
|
z: 4
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
shown: Config.options.background.clock.cookie.minuteHandStyle !== "bold"
|
shown: Config.options.background.widgets.clock.cookie.minuteHandStyle !== "bold"
|
||||||
sourceComponent: Rectangle {
|
sourceComponent: Rectangle {
|
||||||
color: Config.options.background.clock.cookie.minuteHandStyle === "medium" ? root.colBackground : root.colMinuteHand
|
color: Config.options.background.widgets.clock.cookie.minuteHandStyle === "medium" ? root.colBackground : root.colMinuteHand
|
||||||
implicitWidth: 6
|
implicitWidth: 6
|
||||||
implicitHeight: implicitWidth
|
implicitHeight: implicitWidth
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
@@ -213,11 +213,11 @@ Item {
|
|||||||
// Date
|
// Date
|
||||||
FadeLoader {
|
FadeLoader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
shown: Config.options.background.clock.cookie.dateStyle !== "hide"
|
shown: Config.options.background.widgets.clock.cookie.dateStyle !== "hide"
|
||||||
|
|
||||||
sourceComponent: DateIndicator {
|
sourceComponent: DateIndicator {
|
||||||
color: root.colBackgroundInfo
|
color: root.colBackgroundInfo
|
||||||
style: Config.options.background.clock.cookie.dateStyle
|
style: Config.options.background.widgets.clock.cookie.dateStyle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -18,7 +18,7 @@ Item {
|
|||||||
rotation: (360 / 60 * clockSecond) + 90
|
rotation: (360 / 60 * clockSecond) + 90
|
||||||
|
|
||||||
Behavior on rotation {
|
Behavior on rotation {
|
||||||
enabled: Config.options.background.clock.cookie.constantlyRotate // Animating every second is expensive...
|
enabled: Config.options.background.widgets.clock.cookie.constantlyRotate // Animating every second is expensive...
|
||||||
animation: RotationAnimation {
|
animation: RotationAnimation {
|
||||||
direction: RotationAnimation.Clockwise
|
direction: RotationAnimation.Clockwise
|
||||||
duration: 1000 // 1 second
|
duration: 1000 // 1 second
|
||||||
+2
-2
@@ -8,10 +8,10 @@ import QtQuick
|
|||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
property list<string> clockNumbers: DateTime.time.split(/[: ]/)
|
property list<string> clockNumbers: DateTime.time.split(/[: ]/)
|
||||||
property bool isEnabled: Config.options.background.clock.cookie.timeIndicators
|
property bool isEnabled: Config.options.background.widgets.clock.cookie.timeIndicators
|
||||||
property color color: Appearance.colors.colOnSecondaryContainer
|
property color color: Appearance.colors.colOnSecondaryContainer
|
||||||
|
|
||||||
property bool hourMarksEnabled: Config.options.background.clock.cookie.hourMarks
|
property bool hourMarksEnabled: Config.options.background.widgets.clock.cookie.hourMarks
|
||||||
spacing: -16
|
spacing: -16
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
+1
-1
@@ -14,7 +14,7 @@ Item {
|
|||||||
// Rotating date
|
// Rotating date
|
||||||
FadeLoader {
|
FadeLoader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
shown: Config.options.background.clock.cookie.dateStyle === "border"
|
shown: Config.options.background.widgets.clock.cookie.dateStyle === "border"
|
||||||
sourceComponent: RotatingDate {
|
sourceComponent: RotatingDate {
|
||||||
color: root.color
|
color: root.color
|
||||||
}
|
}
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import QtQuick
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: rect
|
id: rect
|
||||||
readonly property string dialStyle: Config.options.background.clock.cookie.dialNumberStyle
|
readonly property string dialStyle: Config.options.background.widgets.clock.cookie.dialNumberStyle
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
+3
-3
@@ -8,14 +8,14 @@ import QtQuick
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string style: Config.options.background.clock.cookie.dateStyle
|
property string style: Config.options.background.widgets.clock.cookie.dateStyle
|
||||||
property color color: Appearance.colors.colOnSecondaryContainer
|
property color color: Appearance.colors.colOnSecondaryContainer
|
||||||
property real angleStep: 12 * Math.PI / 180
|
property real angleStep: 12 * Math.PI / 180
|
||||||
property string dateText: Qt.locale().toString(DateTime.clock.date, "ddd dd")
|
property string dateText: Qt.locale().toString(DateTime.clock.date, "ddd dd")
|
||||||
|
|
||||||
readonly property int clockSecond: DateTime.clock.seconds
|
readonly property int clockSecond: DateTime.clock.seconds
|
||||||
readonly property string dialStyle: Config.options.background.clock.cookie.dialNumberStyle
|
readonly property string dialStyle: Config.options.background.widgets.clock.cookie.dialNumberStyle
|
||||||
readonly property bool timeIndicators: Config.options.background.clock.cookie.timeIndicators
|
readonly property bool timeIndicators: Config.options.background.widgets.clock.cookie.timeIndicators
|
||||||
|
|
||||||
property real radius: style === "border" ? 90 : 0
|
property real radius: style === "border" ? 90 : 0
|
||||||
Behavior on radius {
|
Behavior on radius {
|
||||||
+2
-2
@@ -8,8 +8,8 @@ Item {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property color color: Appearance.colors.colOnSecondaryContainer
|
property color color: Appearance.colors.colOnSecondaryContainer
|
||||||
property string style: Config.options.background.clock.cookie.dialNumberStyle // "dots", "numbers", "full", "hide"
|
property string style: Config.options.background.widgets.clock.cookie.dialNumberStyle // "dots", "numbers", "full", "hide"
|
||||||
property string dateStyle : Config.options.background.clock.cookie.dateStyle
|
property string dateStyle : Config.options.background.widgets.clock.cookie.dateStyle
|
||||||
|
|
||||||
// 12 Dots
|
// 12 Dots
|
||||||
FadeLoader {
|
FadeLoader {
|
||||||
@@ -145,31 +145,33 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject background: JsonObject {
|
property JsonObject background: JsonObject {
|
||||||
property JsonObject clock: JsonObject {
|
property JsonObject widgets: JsonObject {
|
||||||
property bool fixedPosition: false
|
property JsonObject clock: JsonObject {
|
||||||
property real x: -500
|
property bool enable: true
|
||||||
property real y: -500
|
property string placementStrategy: "leastBusy" // "free", "leastBusy", "mostBusy"
|
||||||
property bool show: true
|
property real x: 100
|
||||||
property string style: "cookie" // Options: "cookie", "digital"
|
property real y: 100
|
||||||
property real scale: 1
|
property string style: "cookie" // Options: "cookie", "digital"
|
||||||
property JsonObject cookie: JsonObject {
|
property real scale: 1
|
||||||
property bool aiStyling: false
|
property JsonObject cookie: JsonObject {
|
||||||
property int sides: 14
|
property bool aiStyling: false
|
||||||
property string dialNumberStyle: "full" // Options: "dots" , "numbers", "full" , "none"
|
property int sides: 14
|
||||||
property string hourHandStyle: "fill" // Options: "classic", "fill", "hollow", "hide"
|
property string dialNumberStyle: "full" // Options: "dots" , "numbers", "full" , "none"
|
||||||
property string minuteHandStyle: "medium" // Options "classic", "thin", "medium", "bold", "hide"
|
property string hourHandStyle: "fill" // Options: "classic", "fill", "hollow", "hide"
|
||||||
property string secondHandStyle: "dot" // Options: "dot", "line", "classic", "hide"
|
property string minuteHandStyle: "medium" // Options "classic", "thin", "medium", "bold", "hide"
|
||||||
property string dateStyle: "bubble" // Options: "border", "rect", "bubble" , "hide"
|
property string secondHandStyle: "dot" // Options: "dot", "line", "classic", "hide"
|
||||||
property bool timeIndicators: true
|
property string dateStyle: "bubble" // Options: "border", "rect", "bubble" , "hide"
|
||||||
property bool hourMarks: false
|
property bool timeIndicators: true
|
||||||
property bool dateInClock: true
|
property bool hourMarks: false
|
||||||
property bool constantlyRotate: false
|
property bool dateInClock: true
|
||||||
property bool useSineCookie: false
|
property bool constantlyRotate: false
|
||||||
}
|
property bool useSineCookie: false
|
||||||
property JsonObject digital: JsonObject {
|
}
|
||||||
property bool animateChange: true
|
property JsonObject digital: JsonObject {
|
||||||
}
|
property bool animateChange: true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
property string wallpaperPath: ""
|
property string wallpaperPath: ""
|
||||||
property string thumbnailPath: ""
|
property string thumbnailPath: ""
|
||||||
@@ -182,7 +184,7 @@ Singleton {
|
|||||||
property bool enableWorkspace: true
|
property bool enableWorkspace: true
|
||||||
property real workspaceZoom: 1.07 // Relative to your screen, not wallpaper size
|
property real workspaceZoom: 1.07 // Relative to your screen, not wallpaper size
|
||||||
property bool enableSidebar: true
|
property bool enableSidebar: true
|
||||||
property real clockFactor: 1.2
|
property real widgetsFactor: 1.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +320,7 @@ Singleton {
|
|||||||
property bool useHyprlock: false
|
property bool useHyprlock: false
|
||||||
property bool launchOnStartup: false
|
property bool launchOnStartup: false
|
||||||
property JsonObject blur: JsonObject {
|
property JsonObject blur: JsonObject {
|
||||||
property bool enable: false
|
property bool enable: true
|
||||||
property real radius: 100
|
property real radius: 100
|
||||||
property real extraZoom: 1.1
|
property real extraZoom: 1.1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.modules.common
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Widget to be placed on a WidgetCanvas
|
||||||
|
*/
|
||||||
|
MouseArea {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool draggable: true
|
||||||
|
drag.target: draggable ? root : undefined
|
||||||
|
cursorShape: drag.active ? Qt.ClosedHandCursor : draggable ? Qt.OpenHandCursor : Qt.ArrowCursor
|
||||||
|
|
||||||
|
function center() {
|
||||||
|
root.x = (root.parent.width - root.width) / 2
|
||||||
|
root.y = (root.parent.height - root.height) / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on y {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// uh this is stupid turns out we don't need anything here
|
||||||
|
}
|
||||||
@@ -14,9 +14,9 @@ ContentPage {
|
|||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "nest_clock_farsight_analog"
|
buttonIcon: "nest_clock_farsight_analog"
|
||||||
text: Translation.tr("Show clock")
|
text: Translation.tr("Show clock")
|
||||||
checked: Config.options.background.clock.show
|
checked: Config.options.background.widgets.clock.enable
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.show = checked;
|
Config.options.background.widgets.clock.enable = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,21 +24,48 @@ ContentPage {
|
|||||||
ConfigSpinBox {
|
ConfigSpinBox {
|
||||||
icon: "loupe"
|
icon: "loupe"
|
||||||
text: Translation.tr("Scale (%)")
|
text: Translation.tr("Scale (%)")
|
||||||
value: Config.options.background.clock.scale * 100
|
value: Config.options.background.widgets.clock.scale * 100
|
||||||
from: 1
|
from: 1
|
||||||
to: 200
|
to: 200
|
||||||
stepSize: 2
|
stepSize: 2
|
||||||
onValueChanged: {
|
onValueChanged: {
|
||||||
Config.options.background.clock.scale = value / 100;
|
Config.options.background.widgets.clock.scale = value / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentSubsection {
|
||||||
|
title: Translation.tr("Clock placement strategy")
|
||||||
|
ConfigSelectionArray {
|
||||||
|
currentValue: Config.options.background.widgets.clock.placementStrategy
|
||||||
|
onSelected: newValue => {
|
||||||
|
Config.options.background.widgets.clock.placementStrategy = newValue;
|
||||||
|
}
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Draggable"),
|
||||||
|
icon: "drag_pan",
|
||||||
|
value: "free"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Least busy"),
|
||||||
|
icon: "arrows_output",
|
||||||
|
value: "leastBusy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Most busy"),
|
||||||
|
icon: "arrows_input",
|
||||||
|
value: "mostBusy"
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
title: Translation.tr("Clock style")
|
title: Translation.tr("Clock style")
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.clock.style
|
currentValue: Config.options.background.widgets.clock.style
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.background.clock.style = newValue;
|
Config.options.background.widgets.clock.style = newValue;
|
||||||
}
|
}
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@@ -56,29 +83,29 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "digital"
|
visible: Config.options.background.widgets.clock.style === "digital"
|
||||||
title: Translation.tr("Digital clock settings")
|
title: Translation.tr("Digital clock settings")
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "animation"
|
buttonIcon: "animation"
|
||||||
text: Translation.tr("Animate time change")
|
text: Translation.tr("Animate time change")
|
||||||
checked: Config.options.background.clock.digital.animateChange
|
checked: Config.options.background.widgets.clock.digital.animateChange
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.digital.animateChange = checked;
|
Config.options.background.widgets.clock.digital.animateChange = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "cookie"
|
visible: Config.options.background.widgets.clock.style === "cookie"
|
||||||
title: Translation.tr("Cookie clock settings")
|
title: Translation.tr("Cookie clock settings")
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "wand_stars"
|
buttonIcon: "wand_stars"
|
||||||
text: Translation.tr("Auto styling with Gemini")
|
text: Translation.tr("Auto styling with Gemini")
|
||||||
checked: Config.options.background.clock.cookie.aiStyling
|
checked: Config.options.background.widgets.clock.cookie.aiStyling
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.cookie.aiStyling = checked;
|
Config.options.background.widgets.clock.cookie.aiStyling = checked;
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
text: Translation.tr("Uses Gemini to categorize the wallpaper then picks a preset based on it.\nYou'll need to set Gemini API key on the left sidebar first.\nImages are downscaled for performance, but just to be safe,\ndo not select wallpapers with sensitive information.")
|
text: Translation.tr("Uses Gemini to categorize the wallpaper then picks a preset based on it.\nYou'll need to set Gemini API key on the left sidebar first.\nImages are downscaled for performance, but just to be safe,\ndo not select wallpapers with sensitive information.")
|
||||||
@@ -88,9 +115,9 @@ ContentPage {
|
|||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "airwave"
|
buttonIcon: "airwave"
|
||||||
text: Translation.tr("Use old sine wave cookie implementation")
|
text: Translation.tr("Use old sine wave cookie implementation")
|
||||||
checked: Config.options.background.clock.cookie.useSineCookie
|
checked: Config.options.background.widgets.clock.cookie.useSineCookie
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.cookie.useSineCookie = checked;
|
Config.options.background.widgets.clock.cookie.useSineCookie = checked;
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
text: "Looks a bit softer and more consistent with different number of sides,\nbut has less impressive morphing"
|
text: "Looks a bit softer and more consistent with different number of sides,\nbut has less impressive morphing"
|
||||||
@@ -100,21 +127,21 @@ ContentPage {
|
|||||||
ConfigSpinBox {
|
ConfigSpinBox {
|
||||||
icon: "add_triangle"
|
icon: "add_triangle"
|
||||||
text: Translation.tr("Sides")
|
text: Translation.tr("Sides")
|
||||||
value: Config.options.background.clock.cookie.sides
|
value: Config.options.background.widgets.clock.cookie.sides
|
||||||
from: 0
|
from: 0
|
||||||
to: 40
|
to: 40
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
onValueChanged: {
|
onValueChanged: {
|
||||||
Config.options.background.clock.cookie.sides = value;
|
Config.options.background.widgets.clock.cookie.sides = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
buttonIcon: "autoplay"
|
buttonIcon: "autoplay"
|
||||||
text: Translation.tr("Constantly rotate")
|
text: Translation.tr("Constantly rotate")
|
||||||
checked: Config.options.background.clock.cookie.constantlyRotate
|
checked: Config.options.background.widgets.clock.cookie.constantlyRotate
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.cookie.constantlyRotate = checked;
|
Config.options.background.widgets.clock.cookie.constantlyRotate = checked;
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
text: "Makes the clock always rotate. This is extremely expensive\n(expect 50% usage on Intel UHD Graphics) and thus impractical."
|
text: "Makes the clock always rotate. This is extremely expensive\n(expect 50% usage on Intel UHD Graphics) and thus impractical."
|
||||||
@@ -124,15 +151,15 @@ ContentPage {
|
|||||||
ConfigRow {
|
ConfigRow {
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
enabled: Config.options.background.clock.style === "cookie" && Config.options.background.clock.cookie.dialNumberStyle === "dots" || Config.options.background.clock.cookie.dialNumberStyle === "full"
|
enabled: Config.options.background.widgets.clock.style === "cookie" && Config.options.background.widgets.clock.cookie.dialNumberStyle === "dots" || Config.options.background.widgets.clock.cookie.dialNumberStyle === "full"
|
||||||
buttonIcon: "brightness_7"
|
buttonIcon: "brightness_7"
|
||||||
text: Translation.tr("Hour marks")
|
text: Translation.tr("Hour marks")
|
||||||
checked: Config.options.background.clock.cookie.hourMarks
|
checked: Config.options.background.widgets.clock.cookie.hourMarks
|
||||||
onEnabledChanged: {
|
onEnabledChanged: {
|
||||||
checked = Config.options.background.clock.cookie.hourMarks;
|
checked = Config.options.background.widgets.clock.cookie.hourMarks;
|
||||||
}
|
}
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.cookie.hourMarks = checked;
|
Config.options.background.widgets.clock.cookie.hourMarks = checked;
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
text: "Can only be turned on using the 'Dots' or 'Full' dial style for aesthetic reasons"
|
text: "Can only be turned on using the 'Dots' or 'Full' dial style for aesthetic reasons"
|
||||||
@@ -140,15 +167,15 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
enabled: Config.options.background.clock.style === "cookie" && Config.options.background.clock.cookie.dialNumberStyle !== "numbers"
|
enabled: Config.options.background.widgets.clock.style === "cookie" && Config.options.background.widgets.clock.cookie.dialNumberStyle !== "numbers"
|
||||||
buttonIcon: "timer_10"
|
buttonIcon: "timer_10"
|
||||||
text: Translation.tr("Digits in the middle")
|
text: Translation.tr("Digits in the middle")
|
||||||
checked: Config.options.background.clock.cookie.timeIndicators
|
checked: Config.options.background.widgets.clock.cookie.timeIndicators
|
||||||
onEnabledChanged: {
|
onEnabledChanged: {
|
||||||
checked = Config.options.background.clock.cookie.timeIndicators;
|
checked = Config.options.background.widgets.clock.cookie.timeIndicators;
|
||||||
}
|
}
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.background.clock.cookie.timeIndicators = checked;
|
Config.options.background.widgets.clock.cookie.timeIndicators = checked;
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
text: "Can't be turned on when using 'Numbers' dial style for aesthetic reasons"
|
text: "Can't be turned on when using 'Numbers' dial style for aesthetic reasons"
|
||||||
@@ -158,17 +185,17 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "cookie"
|
visible: Config.options.background.widgets.clock.style === "cookie"
|
||||||
title: Translation.tr("Dial style")
|
title: Translation.tr("Dial style")
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.clock.cookie.dialNumberStyle
|
currentValue: Config.options.background.widgets.clock.cookie.dialNumberStyle
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.background.clock.cookie.dialNumberStyle = newValue;
|
Config.options.background.widgets.clock.cookie.dialNumberStyle = newValue;
|
||||||
if (newValue !== "dots" && newValue !== "full") {
|
if (newValue !== "dots" && newValue !== "full") {
|
||||||
Config.options.background.clock.cookie.hourMarks = false;
|
Config.options.background.widgets.clock.cookie.hourMarks = false;
|
||||||
}
|
}
|
||||||
if (newValue === "numbers") {
|
if (newValue === "numbers") {
|
||||||
Config.options.background.clock.cookie.timeIndicators = false;
|
Config.options.background.widgets.clock.cookie.timeIndicators = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
options: [
|
options: [
|
||||||
@@ -197,12 +224,12 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "cookie"
|
visible: Config.options.background.widgets.clock.style === "cookie"
|
||||||
title: Translation.tr("Hour hand")
|
title: Translation.tr("Hour hand")
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.clock.cookie.hourHandStyle
|
currentValue: Config.options.background.widgets.clock.cookie.hourHandStyle
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.background.clock.cookie.hourHandStyle = newValue;
|
Config.options.background.widgets.clock.cookie.hourHandStyle = newValue;
|
||||||
}
|
}
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@@ -230,13 +257,13 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "cookie"
|
visible: Config.options.background.widgets.clock.style === "cookie"
|
||||||
title: Translation.tr("Minute hand")
|
title: Translation.tr("Minute hand")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.clock.cookie.minuteHandStyle
|
currentValue: Config.options.background.widgets.clock.cookie.minuteHandStyle
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.background.clock.cookie.minuteHandStyle = newValue;
|
Config.options.background.widgets.clock.cookie.minuteHandStyle = newValue;
|
||||||
}
|
}
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@@ -269,13 +296,13 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "cookie"
|
visible: Config.options.background.widgets.clock.style === "cookie"
|
||||||
title: Translation.tr("Second hand")
|
title: Translation.tr("Second hand")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.clock.cookie.secondHandStyle
|
currentValue: Config.options.background.widgets.clock.cookie.secondHandStyle
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.background.clock.cookie.secondHandStyle = newValue;
|
Config.options.background.widgets.clock.cookie.secondHandStyle = newValue;
|
||||||
}
|
}
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@@ -303,13 +330,13 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
visible: Config.options.background.clock.style === "cookie"
|
visible: Config.options.background.widgets.clock.style === "cookie"
|
||||||
title: Translation.tr("Date style")
|
title: Translation.tr("Date style")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.background.clock.cookie.dateStyle
|
currentValue: Config.options.background.widgets.clock.cookie.dateStyle
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.background.clock.cookie.dateStyle = newValue;
|
Config.options.background.widgets.clock.cookie.dateStyle = newValue;
|
||||||
}
|
}
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ def center_crop(img, target_w, target_h):
|
|||||||
y2 = y1 + target_h
|
y2 = y1 + target_h
|
||||||
return img[y1:y2, x1:x2]
|
return img[y1:y2, x1:x2]
|
||||||
|
|
||||||
def find_least_busy_region(image_path, region_width=300, region_height=200, screen_width=None, screen_height=None, verbose=False, stride=2, screen_mode="fill", horizontal_padding=50, vertical_padding=50):
|
def find_least_busy_region(image_path, region_width=300, region_height=200, screen_width=None, screen_height=None, verbose=False, stride=2, screen_mode="fill", horizontal_padding=50, vertical_padding=50, busiest=False):
|
||||||
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
|
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
|
||||||
if img is None:
|
if img is None:
|
||||||
raise FileNotFoundError(f"Image not found: {image_path}")
|
raise FileNotFoundError(f"Image not found: {image_path}")
|
||||||
@@ -77,7 +77,9 @@ def find_least_busy_region(image_path, region_width=300, region_height=200, scre
|
|||||||
total += ii[y1-1, x1-1]
|
total += ii[y1-1, x1-1]
|
||||||
return total
|
return total
|
||||||
min_var = None
|
min_var = None
|
||||||
|
max_var = None
|
||||||
min_coords = (horizontal_padding, vertical_padding)
|
min_coords = (horizontal_padding, vertical_padding)
|
||||||
|
max_coords = (horizontal_padding, vertical_padding)
|
||||||
area = region_width * region_height
|
area = region_width * region_height
|
||||||
x_start = horizontal_padding
|
x_start = horizontal_padding
|
||||||
y_start = vertical_padding
|
y_start = vertical_padding
|
||||||
@@ -100,7 +102,13 @@ def find_least_busy_region(image_path, region_width=300, region_height=200, scre
|
|||||||
if (min_var is None) or (var < min_var):
|
if (min_var is None) or (var < min_var):
|
||||||
min_var = var
|
min_var = var
|
||||||
min_coords = (x, y)
|
min_coords = (x, y)
|
||||||
return min_coords, min_var
|
if (max_var is None) or (var > max_var):
|
||||||
|
max_var = var
|
||||||
|
max_coords = (x, y)
|
||||||
|
if busiest:
|
||||||
|
return max_coords, max_var
|
||||||
|
else:
|
||||||
|
return min_coords, min_var
|
||||||
|
|
||||||
def find_largest_region(image_path, screen_width=None, screen_height=None, verbose=False, stride=2, screen_mode="fill", threshold=100.0, aspect_ratio=1.0, horizontal_padding=50, vertical_padding=50):
|
def find_largest_region(image_path, screen_width=None, screen_height=None, verbose=False, stride=2, screen_mode="fill", threshold=100.0, aspect_ratio=1.0, horizontal_padding=50, vertical_padding=50):
|
||||||
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
|
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
|
||||||
@@ -313,6 +321,7 @@ def main():
|
|||||||
parser.add_argument("--aspect-ratio", type=float, default=1.78, help="Aspect ratio (width/height) for largest region mode")
|
parser.add_argument("--aspect-ratio", type=float, default=1.78, help="Aspect ratio (width/height) for largest region mode")
|
||||||
parser.add_argument("--horizontal-padding", "-hp", type=int, default=50, help="Minimum horizontal distance from region to image edge")
|
parser.add_argument("--horizontal-padding", "-hp", type=int, default=50, help="Minimum horizontal distance from region to image edge")
|
||||||
parser.add_argument("--vertical-padding", "-vp", type=int, default=50, help="Minimum vertical distance from region to image edge")
|
parser.add_argument("--vertical-padding", "-vp", type=int, default=50, help="Minimum vertical distance from region to image edge")
|
||||||
|
parser.add_argument("--busiest", action="store_true", help="Find the busiest region instead of the least busy")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.largest_region:
|
if args.largest_region:
|
||||||
@@ -363,7 +372,8 @@ def main():
|
|||||||
stride=args.stride,
|
stride=args.stride,
|
||||||
screen_mode=args.screen_mode,
|
screen_mode=args.screen_mode,
|
||||||
horizontal_padding=args.horizontal_padding,
|
horizontal_padding=args.horizontal_padding,
|
||||||
vertical_padding=args.vertical_padding
|
vertical_padding=args.vertical_padding,
|
||||||
|
busiest=args.busiest
|
||||||
)
|
)
|
||||||
if args.visual_output:
|
if args.visual_output:
|
||||||
draw_region(args.image_path, coords, region_width=args.width, region_height=args.height, screen_width=args.screen_width, screen_height=args.screen_height, screen_mode=args.screen_mode)
|
draw_region(args.image_path, coords, region_width=args.width, region_height=args.height, screen_width=args.screen_width, screen_height=args.screen_height, screen_mode=args.screen_mode)
|
||||||
|
|||||||
Reference in New Issue
Block a user