Files

161 lines
7.8 KiB
QML

pragma Singleton
import QtQuick
import Quickshell
import qs.Common
import qs.Services
Singleton {
readonly property real sheetWidthDefault: sheetWidthFor(defaultColumns)
readonly property int defaultColumns: 8
readonly property int minimumColumns: 6
readonly property real sheetPadding: PopoutMetrics.contentPadding
readonly property real columnWidth: tileHeight
readonly property real gridStep: 0.5
property int columnPreview: 0
readonly property int gridColumns: columnPreview > 0 ? columnPreview : clampColumns(SettingsData.controlCenterColumns)
function clampColumns(value) {
const columns = Math.round(Number(value));
if (!Number.isFinite(columns) || columns <= 0)
return defaultColumns;
return Math.max(minimumColumns, columns);
}
function columnCapFor(availableWidth) {
return Math.max(1, Math.floor((availableWidth - sheetPadding * 2 + gridGap) / (columnWidth + gridGap)));
}
function rowCapFor(availableHeight, cellHeight = gridRowUnit) {
return Math.max(1, Math.floor((availableHeight + gridGap) / (cellHeight + gridGap)));
}
function sheetWidthFor(columns) {
return sheetPadding * 2 + columns * columnWidth + (columns - 1) * gridGap;
}
readonly property real maxHeightInset: 100
readonly property real minHeight: 300
readonly property real fallbackScreenHeight: 1080
readonly property real triggerWidth: 80
readonly property real tileHeight: 64
readonly property real gridRowUnit: tileHeight
readonly property real expandedTileMinWidth: columnWidth * 3 + gridGap * 2
readonly property real sliderRowHeight: Theme.minimumTouchTargetSize
readonly property real stripTrackHeight: 32
readonly property real stripHandleHeight: stripTrackHeight + Theme.sliderHandleGap * 2
readonly property real gridGap: Theme.spacingS
readonly property real iconScale: SettingsData.controlCenterIconScale
readonly property real tileIconSize: Theme.iconSizeLarge * iconScale
readonly property real iconBoxSize: Theme.minimumTouchTargetSize * iconScale
readonly property real tileActiveRadius: Theme.scaledRadius(24, tileHeight / 2)
readonly property real tallTileRadius: Theme.cornerRadiusXL
readonly property real iconBoxActiveRadius: Theme.cornerRadiusL
readonly property real iconBoxIconSize: Theme.iconSize * iconScale
readonly property real tallMeterThickness: 28
readonly property real pillMeterThickness: Math.round(18 * iconScale)
readonly property real tileTextGap: Theme.spacingM
readonly property real smallRowHeight: Math.min(iconBoxSize, tileHeight)
readonly property real trashSwallowScale: 0.6
// Joined to the sheet, whose own padding separates the buttons from the grid.
readonly property real editActionsHeight: Theme.iconButtonSize + sheetPadding
// Room around the popout surface for the edit chrome and action strip.
readonly property real editOverflow: Math.max(PopoutMetrics.editOverflow * 2, editActionsHeight)
// The island clips its faces, so its actions sit inside the sheet.
readonly property real islandEditRoom: editActionsHeight + Theme.spacingS
readonly property real runningAppsIconSize: Theme.iconSize * iconScale
// The resize corner counts a small tile as this many rows and snaps to the nearer of this and a full row.
readonly property real smallRowFraction: 0.5
readonly property real shapeButtonSize: Theme.iconSize
readonly property real detailDialogInset: Theme.spacingL
readonly property real detailDialogPadding: Theme.spacingS
readonly property real detailMinContentHeight: Theme.listItemTwoLineHeight * 3
readonly property real headerActionSize: Theme.buttonHeightXS
readonly property real headerActionIconSize: Theme.iconSizeMedium
readonly property real headerEdgeInset: rowPaddingH - (headerActionSize - headerActionIconSize) / 2
readonly property real pageHeaderHeight: Theme.fontSizeXXLarge + Theme.spacingM * 2
readonly property real pageTitleSize: Theme.fontSizeXXLarge
readonly property real detailHeightList: 350
readonly property real detailHeightBrightness: 400
readonly property real detailHeightDefault: 250
readonly property int transitionDuration: Theme.expressiveDurations.expressiveFastSpatial
readonly property int fadeDuration: Theme.expressiveDurations.expressiveEffects
readonly property real rowPaddingH: Theme.spacingL
readonly property real rowPaddingV: Theme.spacingM
readonly property real detailContentGap: Theme.spacingS
readonly property real sectionLabelTopGap: Theme.spacingS
readonly property real sectionLabelBottomGap: Theme.spacingXS
readonly property color rowColor: Theme.foregroundColor(Theme.cardSurface)
readonly property int maxPins: 3
readonly property real statusDotSize: 8
readonly property real spinnerStroke: 2
readonly property real emptyStateIconSize: Theme.iconSizeLarge
readonly property real emptyStateMinHeight: 100
readonly property real menuMinWidth: 180
readonly property real dialogWidth: 320
readonly property real libraryPanelWidth: 400
readonly property real libraryPanelHeight: 400
readonly property real widgetSheetHeightRatio: 0.85
readonly property real previewSize: 76
readonly property real configMenuWidth: 260
readonly property real vpnPopoutListHeight: 200
readonly property real headerDropdownWidth: 120
readonly property real rowDropdownWidth: 160
readonly property real headerPopupWidth: 200
readonly property real brightnessLowMax: 33
readonly property int wifiSignalBucket: 25
readonly property real diskWarnPercent: 75
readonly property real diskCriticalPercent: 90
readonly property int dndRefreshInterval: 1000
readonly property int wifiSignalStrong: 50
readonly property real brightnessMediumMax: 66
readonly property real brightnessExponentMin: 1.0
readonly property real brightnessExponentMax: 2.5
readonly property real brightnessExponentStep: 0.1
readonly property int overlayZ: 10000
readonly property real popupEnterScale: 0.92
readonly property color dialogColor: Theme.foregroundColor(Theme.hostSurface)
readonly property bool hideCoveredContent: BlurService.enabled && Theme.connectedSurfaceBlurEnabled && dialogColor.a < 1
readonly property color tileActiveColor: Theme.ccTileActiveBg
readonly property color tileActiveContent: Theme.ccTileActiveText
readonly property color tileInactiveColor: Theme.ccPillInactiveBg
readonly property color iconBoxInactiveColor: Theme.ccIconBoxInactiveBg
readonly property color tileInactiveContent: Theme.surfaceText
readonly property color tileInactiveSubtitle: Theme.surfaceVariantText
readonly property color tileInactiveIcon: Theme.primary
readonly property color bareActiveIcon: Theme.primary
readonly property real quickBarePadding: Theme.spacingL
readonly property real quickBareWidth: iconBoxIconSize + quickBarePadding
readonly property real quickTileGap: Theme.spacingXS
readonly property bool animationsEnabled: !SettingsData.reduceMotion && Theme.currentAnimationSpeed !== SettingsData.AnimationSpeed.None
function preferredDetailHeight(section, pluginHeight) {
if (!section)
return 0;
if (section.startsWith("plugin_"))
return pluginHeight > 0 ? pluginHeight : detailHeightDefault;
if (section.startsWith("brightnessSlider_"))
return detailHeightBrightness;
switch (section) {
case "wifi":
case "network":
case "bluetooth":
case "battery":
case "builtin_vpn":
case "builtin_tailscale":
case "audioOutput":
case "audioInput":
case "diskUsage":
case "runningApps":
return detailHeightList;
default:
return detailHeightDefault;
}
}
}