Merge pull request #1517 from caelestia-dots/unstable
Merge unstable into main
This commit is contained in:
commit
e65e918a9e
365 changed files with 16203 additions and 17799 deletions
2
.github/workflows/check-format.yml
vendored
2
.github/workflows/check-format.yml
vendored
|
|
@ -18,6 +18,7 @@ jobs:
|
||||||
- name: Check QML format
|
- name: Check QML format
|
||||||
shell: fish {0}
|
shell: fish {0}
|
||||||
run: |
|
run: |
|
||||||
|
/usr/lib/qt6/bin/qmlformat --version
|
||||||
for file in (string match -v 'build/*' **.qml)
|
for file in (string match -v 'build/*' **.qml)
|
||||||
/usr/lib/qt6/bin/qmlformat $file | diff -u $file - || exit 1
|
/usr/lib/qt6/bin/qmlformat $file | diff -u $file - || exit 1
|
||||||
end
|
end
|
||||||
|
|
@ -34,5 +35,6 @@ jobs:
|
||||||
- name: Check C++ format
|
- name: Check C++ format
|
||||||
shell: fish {0}
|
shell: fish {0}
|
||||||
run: |
|
run: |
|
||||||
|
clang-format --version
|
||||||
find plugin extras -name '*.cpp' -o -name '*.hpp' \
|
find plugin extras -name '*.cpp' -o -name '*.hpp' \
|
||||||
| xargs clang-format --dry-run --Werror
|
| xargs clang-format --dry-run --Werror
|
||||||
|
|
|
||||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
|
@ -25,6 +25,8 @@ jobs:
|
||||||
- name: Lint QML
|
- name: Lint QML
|
||||||
shell: fish {0}
|
shell: fish {0}
|
||||||
run: |
|
run: |
|
||||||
|
/usr/lib/qt6/bin/qmllint --version
|
||||||
|
|
||||||
# Generate tooling
|
# Generate tooling
|
||||||
touch .qmlls.ini
|
touch .qmlls.ini
|
||||||
QT_QPA_PLATFORM=offscreen QML2_IMPORT_PATH="$PWD/build/qml:$QML2_IMPORT_PATH" timeout 2 qs -p .
|
QT_QPA_PLATFORM=offscreen QML2_IMPORT_PATH="$PWD/build/qml:$QML2_IMPORT_PATH" timeout 2 qs -p .
|
||||||
|
|
|
||||||
8
.github/workflows/update-image.yml
vendored
8
.github/workflows/update-image.yml
vendored
|
|
@ -23,7 +23,13 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
cat > /tmp/Dockerfile <<EOF
|
cat > /tmp/Dockerfile <<EOF
|
||||||
FROM archlinux:latest
|
FROM archlinux:latest
|
||||||
RUN pacman -Syu --needed --noconfirm sudo base-devel cmake ninja fish git clazy qt6-declarative qt6-shadertools python libpipewire aubio libqalculate && \
|
# TEMPORARY (remove once the upstream qmlformat regression is fixed): pin to the
|
||||||
|
# 2026-05-13 Arch archive snapshot to hold qmlformat at qt6-declarative 6.11.0.
|
||||||
|
# qt6-declarative 6.11.1 silently crashes qmlformat (exit 1, empty output) on QML files
|
||||||
|
# that declare a property named 'id'. To unpin: delete the mirrorlist line below and
|
||||||
|
# change 'pacman -Syyuu' back to 'pacman -Syu'.
|
||||||
|
RUN echo 'Server = https://archive.archlinux.org/repos/2026/05/13/\$repo/os/\$arch' > /etc/pacman.d/mirrorlist && \
|
||||||
|
pacman -Syyuu --needed --noconfirm sudo base-devel cmake ninja fish git clazy qt6-declarative qt6-shadertools python libpipewire aubio libqalculate && \
|
||||||
useradd -m builder && \
|
useradd -m builder && \
|
||||||
echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
|
echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
|
||||||
sudo -u builder git clone https://aur.archlinux.org/yay-bin.git /home/builder/yay-bin && \
|
sudo -u builder git clone https://aur.archlinux.org/yay-bin.git /home/builder/yay-bin && \
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,20 @@ if("shell" IN_LIST ENABLE_MODULES)
|
||||||
|
|
||||||
install(FILES LICENSE DESTINATION "${INSTALL_QSCONFDIR}")
|
install(FILES LICENSE DESTINATION "${INSTALL_QSCONFDIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if("plugin" IN_LIST ENABLE_MODULES OR "shell" IN_LIST ENABLE_MODULES)
|
||||||
|
message(STATUS "Fetching M3Shapes module")
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
m3shapes_external
|
||||||
|
GIT_REPOSITORY https://github.com/soramanew/m3shapes.git
|
||||||
|
GIT_TAG main
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(m3shapes_external)
|
||||||
|
message(STATUS "Done fetching M3Shapes module")
|
||||||
|
|
||||||
|
# Fix m3shapes wrong rpath
|
||||||
|
if(TARGET m3shapesplugin)
|
||||||
|
set_target_properties(m3shapesplugin PROPERTIES INSTALL_RPATH "$ORIGIN")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
|
||||||
387
README.md
387
README.md
|
|
@ -240,12 +240,14 @@ For example, to disable the bar on DP-1:
|
||||||
> - `launcher` (`specialPrefix`, `actionPrefix`, `enableDangerousActions`, `vimKeybinds`,
|
> - `launcher` (`specialPrefix`, `actionPrefix`, `enableDangerousActions`, `vimKeybinds`,
|
||||||
> `favouriteApps`, `hiddenApps`, `actions`)
|
> `favouriteApps`, `hiddenApps`, `actions`)
|
||||||
> - `launcher.useFuzzy` (`apps`, `actions`, `schemes`, `variants`, `wallpapers`)
|
> - `launcher.useFuzzy` (`apps`, `actions`, `schemes`, `variants`, `wallpapers`)
|
||||||
> - `notifs` (`expire`, `fullscreen`, `defaultExpireTimeout`, `actionOnClick`)
|
> - `notifs` (`expire`, `fullscreen`, `defaultExpireTimeout`, `fullscreenExpireTimeout`, `actionOnClick`)
|
||||||
> - `lock` (`enableFprint`, `maxFprintTries`)
|
> - `lock` (`enableFprint`, `maxFprintTries`)
|
||||||
> - `utilities` (`toasts`, `vpn`)
|
> - `nexus` (`networkRescanInterval`)
|
||||||
|
> - `utilities.toasts` (all except `fullscreen`)
|
||||||
|
> - `utilities.vpn` (`enabled`, `provider`)
|
||||||
> - `services` (`weatherLocation`, `useFahrenheit`, `useFahrenheitPerformance`, `useTwelveHourClock`,
|
> - `services` (`weatherLocation`, `useFahrenheit`, `useFahrenheitPerformance`, `useTwelveHourClock`,
|
||||||
> `gpuType`, `visualiserBars`, `audioIncrement`, `brightnessIncrement`, `maxVolume`, `smartScheme`,
|
> `gpuType`, `visualiserBars`, `audioIncrement`, `brightnessIncrement`, `maxVolume`, `smartScheme`,
|
||||||
> `defaultPlayer`, `playerAliases`, `showLyrics`, `lyricsBackend`)
|
> `defaultPlayer`, `playerAliases`, `lyricsBackend`)
|
||||||
> - `paths` (`wallpaperDir`, `lyricsDir`)
|
> - `paths` (`wallpaperDir`, `lyricsDir`)
|
||||||
>
|
>
|
||||||
> </details>
|
> </details>
|
||||||
|
|
@ -265,31 +267,61 @@ For example, to disable the bar on DP-1:
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"deformScale": 1,
|
"deformScale": 1,
|
||||||
"anim": {
|
|
||||||
"durations": {
|
|
||||||
"scale": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"font": {
|
|
||||||
"family": {
|
|
||||||
"clock": "Rubik",
|
|
||||||
"material": "Material Symbols Rounded",
|
|
||||||
"mono": "CaskaydiaCove NF",
|
|
||||||
"sans": "Rubik"
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"scale": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"padding": {
|
|
||||||
"scale": 1
|
|
||||||
},
|
|
||||||
"rounding": {
|
"rounding": {
|
||||||
"scale": 1
|
"scale": 1
|
||||||
},
|
},
|
||||||
"spacing": {
|
"spacing": {
|
||||||
"scale": 1
|
"scale": 1
|
||||||
},
|
},
|
||||||
|
"padding": {
|
||||||
|
"scale": 1
|
||||||
|
},
|
||||||
|
"font": {
|
||||||
|
"scale": 1,
|
||||||
|
"clock": "Rubik",
|
||||||
|
"headline": {
|
||||||
|
"family": "GoogleSansFlex",
|
||||||
|
"large": { "size": 32, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"medium": { "size": 28, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"small": { "size": 24, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } }
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"family": "GoogleSansFlex",
|
||||||
|
"large": { "size": 22, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"medium": { "size": 16, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"small": { "size": 14, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } }
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"family": "GoogleSansFlex",
|
||||||
|
"large": { "size": 16, "weight": 400, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"medium": { "size": 14, "weight": 400, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"small": { "size": 12, "weight": 400, "italic": false, "vaxes": { "ROND": 25 } }
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"family": "GoogleSansFlex",
|
||||||
|
"large": { "size": 14, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"medium": { "size": 12, "weight": 500, "italic": false, "vaxes": { "ROND": 25 } },
|
||||||
|
"small": { "size": 11, "weight": 400, "italic": false, "vaxes": { "ROND": 25 } }
|
||||||
|
},
|
||||||
|
"mono": {
|
||||||
|
"family": "CaskaydiaCove NF",
|
||||||
|
"large": { "size": 16, "weight": 400, "italic": false, "vaxes": {} },
|
||||||
|
"medium": { "size": 14, "weight": 400, "italic": false, "vaxes": {} },
|
||||||
|
"small": { "size": 12, "weight": 400, "italic": false, "vaxes": {} }
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"family": "Material Symbols Rounded",
|
||||||
|
"extraLarge": { "size": 36, "weight": 400, "italic": false, "vaxes": {} },
|
||||||
|
"large": { "size": 24, "weight": 400, "italic": false, "vaxes": {} },
|
||||||
|
"medium": { "size": 18, "weight": 400, "italic": false, "vaxes": {} },
|
||||||
|
"small": { "size": 15, "weight": 400, "italic": false, "vaxes": {} }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"anim": {
|
||||||
|
"durations": {
|
||||||
|
"scale": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
"transparency": {
|
"transparency": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"base": 0.85,
|
"base": 0.85,
|
||||||
|
|
@ -297,7 +329,7 @@ For example, to disable the bar on DP-1:
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"logo": "caelestia",
|
"logo": "",
|
||||||
"showOverFullscreen": false,
|
"showOverFullscreen": false,
|
||||||
"mediaGifSpeedAdjustment": 300,
|
"mediaGifSpeedAdjustment": 300,
|
||||||
"sessionGifSpeed": 0.7,
|
"sessionGifSpeed": 0.7,
|
||||||
|
|
@ -307,6 +339,25 @@ For example, to disable the bar on DP-1:
|
||||||
"playback": ["mpv"],
|
"playback": ["mpv"],
|
||||||
"explorer": ["thunar"]
|
"explorer": ["thunar"]
|
||||||
},
|
},
|
||||||
|
"idle": {
|
||||||
|
"lockBeforeSleep": true,
|
||||||
|
"inhibitWhenAudio": true,
|
||||||
|
"timeouts": [
|
||||||
|
{
|
||||||
|
"timeout": 180,
|
||||||
|
"idleAction": "lock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timeout": 300,
|
||||||
|
"idleAction": "dpms off",
|
||||||
|
"returnAction": "dpms on"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timeout": 600,
|
||||||
|
"idleAction": ["systemctl", "suspend-then-hibernate"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
"warnLevels": [
|
"warnLevels": [
|
||||||
{
|
{
|
||||||
|
|
@ -330,65 +381,102 @@ For example, to disable the bar on DP-1:
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"criticalLevel": 3
|
"criticalLevel": 3
|
||||||
},
|
|
||||||
"idle": {
|
|
||||||
"lockBeforeSleep": true,
|
|
||||||
"inhibitWhenAudio": true,
|
|
||||||
"timeouts": [
|
|
||||||
{
|
|
||||||
"timeout": 180,
|
|
||||||
"idleAction": "lock"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"timeout": 300,
|
|
||||||
"idleAction": "dpms off",
|
|
||||||
"returnAction": "dpms on"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"timeout": 600,
|
|
||||||
"idleAction": ["systemctl", "suspend-then-hibernate"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"background": {
|
"background": {
|
||||||
|
"enabled": true,
|
||||||
|
"wallpaperEnabled": true,
|
||||||
"desktopClock": {
|
"desktopClock": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"scale": 1.0,
|
"scale": 1.0,
|
||||||
"position": "bottom-right",
|
"position": "bottom-right",
|
||||||
"shadow": {
|
"invertColors": false,
|
||||||
"enabled": true,
|
|
||||||
"opacity": 0.7,
|
|
||||||
"blur": 0.4
|
|
||||||
},
|
|
||||||
"background": {
|
"background": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"opacity": 0.7,
|
"opacity": 0.7,
|
||||||
"blur": true
|
"blur": true
|
||||||
},
|
},
|
||||||
"invertColors": false
|
"shadow": {
|
||||||
|
"enabled": true,
|
||||||
|
"opacity": 0.7,
|
||||||
|
"blur": 0.4
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"enabled": true,
|
|
||||||
"visualiser": {
|
"visualiser": {
|
||||||
"blur": false,
|
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"autoHide": true,
|
"autoHide": true,
|
||||||
|
"blur": false,
|
||||||
"rounding": 1,
|
"rounding": 1,
|
||||||
"spacing": 1
|
"spacing": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bar": {
|
"bar": {
|
||||||
|
"persistent": true,
|
||||||
|
"showOnHover": true,
|
||||||
|
"dragThreshold": 20,
|
||||||
|
"scrollActions": {
|
||||||
|
"workspaces": true,
|
||||||
|
"volume": true,
|
||||||
|
"brightness": true
|
||||||
|
},
|
||||||
|
"popouts": {
|
||||||
|
"activeWindow": true,
|
||||||
|
"tray": true,
|
||||||
|
"statusIcons": true
|
||||||
|
},
|
||||||
|
"workspaces": {
|
||||||
|
"shown": 5,
|
||||||
|
"activeIndicator": true,
|
||||||
|
"occupiedBg": false,
|
||||||
|
"showWindows": true,
|
||||||
|
"showWindowsOnSpecialWorkspaces": true,
|
||||||
|
"maxWindowIcons": 5,
|
||||||
|
"activeTrail": false,
|
||||||
|
"perMonitorWorkspaces": true,
|
||||||
|
"label": " ",
|
||||||
|
"occupiedLabel": "",
|
||||||
|
"activeLabel": "",
|
||||||
|
"capitalisation": "preserve",
|
||||||
|
"specialWorkspaceIcons": [
|
||||||
|
{
|
||||||
|
"name": "steam",
|
||||||
|
"icon": "sports_esports"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"windowIcons": [
|
||||||
|
{
|
||||||
|
"regex": "steam(_app_(default|[0-9]+))?",
|
||||||
|
"icon": "sports_esports"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"activeWindow": {
|
"activeWindow": {
|
||||||
"compact": false,
|
"compact": false,
|
||||||
"inverted": false,
|
"inverted": false,
|
||||||
"showOnHover": true
|
"showOnHover": true
|
||||||
},
|
},
|
||||||
|
"tray": {
|
||||||
|
"background": false,
|
||||||
|
"recolour": false,
|
||||||
|
"compact": false,
|
||||||
|
"iconSubs": [],
|
||||||
|
"hiddenIcons": []
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"showAudio": false,
|
||||||
|
"showMicrophone": false,
|
||||||
|
"showKbLayout": false,
|
||||||
|
"showNetwork": true,
|
||||||
|
"showWifi": true,
|
||||||
|
"showBluetooth": true,
|
||||||
|
"showBattery": true,
|
||||||
|
"showLockStatus": true
|
||||||
|
},
|
||||||
"clock": {
|
"clock": {
|
||||||
"background": false,
|
"background": false,
|
||||||
"showDate": false,
|
"showDate": false,
|
||||||
"showIcon": true
|
"showIcon": true
|
||||||
},
|
},
|
||||||
"dragThreshold": 20,
|
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"id": "logo",
|
"id": "logo",
|
||||||
|
|
@ -427,66 +515,12 @@ For example, to disable the bar on DP-1:
|
||||||
"enabled": true
|
"enabled": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"persistent": true,
|
"excludedScreens": []
|
||||||
"popouts": {
|
|
||||||
"activeWindow": true,
|
|
||||||
"statusIcons": true,
|
|
||||||
"tray": true
|
|
||||||
},
|
|
||||||
"scrollActions": {
|
|
||||||
"brightness": true,
|
|
||||||
"workspaces": true,
|
|
||||||
"volume": true
|
|
||||||
},
|
|
||||||
"showOnHover": true,
|
|
||||||
"status": {
|
|
||||||
"showAudio": false,
|
|
||||||
"showBattery": true,
|
|
||||||
"showBluetooth": true,
|
|
||||||
"showKbLayout": false,
|
|
||||||
"showMicrophone": false,
|
|
||||||
"showNetwork": true,
|
|
||||||
"showWifi": true,
|
|
||||||
"showLockStatus": true
|
|
||||||
},
|
|
||||||
"tray": {
|
|
||||||
"background": false,
|
|
||||||
"compact": false,
|
|
||||||
"iconSubs": [],
|
|
||||||
"recolour": false
|
|
||||||
},
|
|
||||||
"workspaces": {
|
|
||||||
"activeIndicator": true,
|
|
||||||
"activeLabel": "",
|
|
||||||
"activeTrail": false,
|
|
||||||
"label": " ",
|
|
||||||
"occupiedBg": false,
|
|
||||||
"occupiedLabel": "",
|
|
||||||
"perMonitorWorkspaces": true,
|
|
||||||
"showWindows": true,
|
|
||||||
"shown": 5,
|
|
||||||
"specialWorkspaceIcons": [
|
|
||||||
{
|
|
||||||
"name": "steam",
|
|
||||||
"icon": "sports_esports"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"windowIcons": [
|
|
||||||
{
|
|
||||||
"regex": "steam(_app_(default|[0-9]+))?",
|
|
||||||
"icon": "sports_esports"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"excludedScreens": [""],
|
|
||||||
"activeWindow": {
|
|
||||||
"inverted": false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"border": {
|
"border": {
|
||||||
|
"thickness": 10,
|
||||||
"rounding": 25,
|
"rounding": 25,
|
||||||
"smoothing": 32,
|
"smoothing": 20
|
||||||
"thickness": 10
|
|
||||||
},
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|
@ -495,11 +529,37 @@ For example, to disable the bar on DP-1:
|
||||||
"showMedia": true,
|
"showMedia": true,
|
||||||
"showPerformance": true,
|
"showPerformance": true,
|
||||||
"showWeather": true,
|
"showWeather": true,
|
||||||
|
"mediaUpdateInterval": 500,
|
||||||
|
"resourceUpdateInterval": 1000,
|
||||||
"dragThreshold": 50,
|
"dragThreshold": 50,
|
||||||
"mediaUpdateInterval": 500
|
"performance": {
|
||||||
|
"showBattery": true,
|
||||||
|
"showGpu": true,
|
||||||
|
"showCpu": true,
|
||||||
|
"showMemory": true,
|
||||||
|
"showStorage": true,
|
||||||
|
"showNetwork": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"launcher": {
|
"launcher": {
|
||||||
|
"enabled": true,
|
||||||
|
"showOnHover": false,
|
||||||
|
"maxShown": 7,
|
||||||
|
"maxWallpapers": 9,
|
||||||
|
"specialPrefix": "@",
|
||||||
"actionPrefix": ">",
|
"actionPrefix": ">",
|
||||||
|
"enableDangerousActions": false,
|
||||||
|
"dragThreshold": 50,
|
||||||
|
"vimKeybinds": false,
|
||||||
|
"favouriteApps": [],
|
||||||
|
"hiddenApps": [],
|
||||||
|
"useFuzzy": {
|
||||||
|
"apps": false,
|
||||||
|
"actions": false,
|
||||||
|
"schemes": false,
|
||||||
|
"variants": false,
|
||||||
|
"wallpapers": false
|
||||||
|
},
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"name": "Calculator",
|
"name": "Calculator",
|
||||||
|
|
@ -533,14 +593,6 @@ For example, to disable the bar on DP-1:
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"dangerous": false
|
"dangerous": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Transparency",
|
|
||||||
"icon": "opacity",
|
|
||||||
"description": "Change shell transparency",
|
|
||||||
"command": ["autocomplete", "transparency"],
|
|
||||||
"enabled": false,
|
|
||||||
"dangerous": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Random",
|
"name": "Random",
|
||||||
"icon": "casino",
|
"icon": "casino",
|
||||||
|
|
@ -609,71 +661,57 @@ For example, to disable the bar on DP-1:
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
"icon": "settings",
|
"icon": "settings",
|
||||||
"description": "Configure the shell",
|
"description": "Configure the shell",
|
||||||
"command": ["caelestia", "shell", "controlCenter", "open"],
|
"command": ["caelestia", "shell", "nexus", "open"],
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"dangerous": false
|
"dangerous": false
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"dragThreshold": 50,
|
|
||||||
"vimKeybinds": false,
|
|
||||||
"enableDangerousActions": false,
|
|
||||||
"maxShown": 7,
|
|
||||||
"maxWallpapers": 9,
|
|
||||||
"specialPrefix": "@",
|
|
||||||
"useFuzzy": {
|
|
||||||
"apps": false,
|
|
||||||
"actions": false,
|
|
||||||
"schemes": false,
|
|
||||||
"variants": false,
|
|
||||||
"wallpapers": false
|
|
||||||
},
|
|
||||||
"showOnHover": false,
|
|
||||||
"favouriteApps": [],
|
|
||||||
"hiddenApps": []
|
|
||||||
},
|
},
|
||||||
"lock": {
|
"lock": {
|
||||||
"recolourLogo": false,
|
"recolourLogo": true,
|
||||||
|
"enableFprint": true,
|
||||||
|
"maxFprintTries": 3,
|
||||||
"hideNotifs": false
|
"hideNotifs": false
|
||||||
},
|
},
|
||||||
|
"nexus": {
|
||||||
|
"wallpapersPerRow": 4,
|
||||||
|
"networkRescanInterval": 15000
|
||||||
|
},
|
||||||
"notifs": {
|
"notifs": {
|
||||||
"actionOnClick": false,
|
"expire": true,
|
||||||
"clearThreshold": 0.3,
|
"fullscreen": "on",
|
||||||
"defaultExpireTimeout": 5000,
|
"defaultExpireTimeout": 5000,
|
||||||
|
"fullscreenExpireTimeout": 2000,
|
||||||
|
"clearThreshold": 0.3,
|
||||||
"expandThreshold": 20,
|
"expandThreshold": 20,
|
||||||
"openExpanded": false,
|
"actionOnClick": false,
|
||||||
"expire": false
|
"groupPreviewNum": 3,
|
||||||
|
"openExpanded": false
|
||||||
},
|
},
|
||||||
"osd": {
|
"osd": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"hideDelay": 2000,
|
||||||
"enableBrightness": true,
|
"enableBrightness": true,
|
||||||
"enableMicrophone": false,
|
"enableMicrophone": false
|
||||||
"hideDelay": 2000
|
|
||||||
},
|
|
||||||
"paths": {
|
|
||||||
"mediaGif": "root:/assets/bongocat.gif",
|
|
||||||
"sessionGif": "root:/assets/kurukuru.gif",
|
|
||||||
"noNotifsPic": "root:/assets/dino.png",
|
|
||||||
"lockNoNotifsPic": "root:/assets/dino.png",
|
|
||||||
"wallpaperDir": "~/Pictures/Wallpapers",
|
|
||||||
"lyricsDir": "~/Music/lyrics"
|
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"audioIncrement": 0.1,
|
|
||||||
"brightnessIncrement": 0.1,
|
|
||||||
"maxVolume": 1.0,
|
|
||||||
"defaultPlayer": "Spotify",
|
|
||||||
"gpuType": "",
|
|
||||||
"playerAliases": [{ "from": "com.github.th_ch.youtube_music", "to": "YT Music" }],
|
|
||||||
"weatherLocation": "",
|
"weatherLocation": "",
|
||||||
"useFahrenheit": false,
|
"useFahrenheit": false,
|
||||||
"useFahrenheitPerformance": false,
|
"useFahrenheitPerformance": false,
|
||||||
"useTwelveHourClock": false,
|
"useTwelveHourClock": false,
|
||||||
|
"gpuType": "",
|
||||||
|
"visualiserBars": 60,
|
||||||
|
"audioIncrement": 0.1,
|
||||||
|
"brightnessIncrement": 0.1,
|
||||||
|
"maxVolume": 1.0,
|
||||||
"smartScheme": true,
|
"smartScheme": true,
|
||||||
"visualiserBars": 45
|
"defaultPlayer": "Spotify",
|
||||||
|
"playerAliases": [{ "from": "com.github.th_ch.youtube_music", "to": "YT Music" }],
|
||||||
|
"lyricsBackend": "Auto"
|
||||||
},
|
},
|
||||||
"session": {
|
"session": {
|
||||||
"dragThreshold": 30,
|
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"dragThreshold": 30,
|
||||||
"vimKeybinds": false,
|
"vimKeybinds": false,
|
||||||
"icons": {
|
"icons": {
|
||||||
"logout": "logout",
|
"logout": "logout",
|
||||||
|
|
@ -689,28 +727,29 @@ For example, to disable the bar on DP-1:
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"dragThreshold": 80,
|
"enabled": true,
|
||||||
"enabled": true
|
"dragThreshold": 80
|
||||||
},
|
},
|
||||||
"utilities": {
|
"utilities": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"maxToasts": 4,
|
"maxToasts": 4,
|
||||||
"toasts": {
|
"toasts": {
|
||||||
"audioInputChanged": true,
|
"fullscreen": "off",
|
||||||
"audioOutputChanged": true,
|
|
||||||
"capsLockChanged": true,
|
|
||||||
"chargingChanged": true,
|
|
||||||
"configLoaded": true,
|
"configLoaded": true,
|
||||||
"dndChanged": true,
|
"chargingChanged": true,
|
||||||
"gameModeChanged": true,
|
"gameModeChanged": true,
|
||||||
|
"dndChanged": true,
|
||||||
|
"audioOutputChanged": true,
|
||||||
|
"audioInputChanged": true,
|
||||||
|
"capsLockChanged": true,
|
||||||
|
"numLockChanged": true,
|
||||||
"kbLayoutChanged": true,
|
"kbLayoutChanged": true,
|
||||||
"kbLimit": true,
|
"kbLimit": true,
|
||||||
"numLockChanged": true,
|
|
||||||
"vpnChanged": true,
|
"vpnChanged": true,
|
||||||
"nowPlaying": false
|
"nowPlaying": false
|
||||||
},
|
},
|
||||||
"vpn": {
|
"vpn": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"provider": [
|
"provider": [
|
||||||
{
|
{
|
||||||
"name": "wireguard",
|
"name": "wireguard",
|
||||||
|
|
@ -734,8 +773,8 @@ For example, to disable the bar on DP-1:
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"enabled": true,
|
"id": "settings",
|
||||||
"id": "settings"
|
"enabled": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gameMode",
|
"id": "gameMode",
|
||||||
|
|
@ -747,9 +786,17 @@ For example, to disable the bar on DP-1:
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "vpn",
|
"id": "vpn",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"wallpaperDir": "~/Pictures/Wallpapers",
|
||||||
|
"lyricsDir": "~/Music/lyrics/",
|
||||||
|
"sessionGif": "root:/assets/kurukuru.gif",
|
||||||
|
"mediaGif": "root:/assets/bongocat.gif",
|
||||||
|
"noNotifsPic": "root:/assets/dino.png",
|
||||||
|
"lockNoNotifsPic": "root:/assets/dino.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Binary file not shown.
91
assets/google-sans-flex/LICENSE
Normal file
91
assets/google-sans-flex/LICENSE
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#version 440
|
|
||||||
|
|
||||||
layout(location = 0) in vec2 qt_TexCoord0;
|
|
||||||
layout(location = 0) out vec4 fragColor;
|
|
||||||
|
|
||||||
layout(std140, binding = 0) uniform buf {
|
|
||||||
mat4 qt_Matrix;
|
|
||||||
float qt_Opacity;
|
|
||||||
float fadeMargin;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(binding = 1) uniform sampler2D source;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 tex = texture(source, qt_TexCoord0);
|
|
||||||
float factor = 1.0;
|
|
||||||
float margin = 0.1;
|
|
||||||
|
|
||||||
if (qt_TexCoord0.y < margin) {
|
|
||||||
factor = qt_TexCoord0.y / margin;
|
|
||||||
} else if (qt_TexCoord0.y > (1.0 - margin)) {
|
|
||||||
factor = (1.0 - qt_TexCoord0.y) / margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
fragColor = tex * factor * qt_Opacity;
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
|
@ -1,19 +0,0 @@
|
||||||
#version 440
|
|
||||||
|
|
||||||
layout(location = 0) in vec2 qt_TexCoord0;
|
|
||||||
layout(location = 0) out vec4 fragColor;
|
|
||||||
|
|
||||||
layout(std140, binding = 0) uniform buf {
|
|
||||||
// qt_Matrix and qt_Opacity must always be both present
|
|
||||||
// if the built-in vertex shader is used.
|
|
||||||
mat4 qt_Matrix;
|
|
||||||
float qt_Opacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(binding = 1) uniform sampler2D source;
|
|
||||||
layout(binding = 2) uniform sampler2D maskSource;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
fragColor = texture(source, qt_TexCoord0.st) * (texture(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
|
|
||||||
}
|
|
||||||
Binary file not shown.
BIN
assets/wallpaper.webp
Normal file
BIN
assets/wallpaper.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 MiB |
|
|
@ -13,33 +13,48 @@ NumberAnimation {
|
||||||
EmphasizedExtraLarge,
|
EmphasizedExtraLarge,
|
||||||
FastSpatial,
|
FastSpatial,
|
||||||
DefaultSpatial,
|
DefaultSpatial,
|
||||||
SlowSpatial
|
SlowSpatial,
|
||||||
|
FastEffects,
|
||||||
|
DefaultEffects,
|
||||||
|
SlowEffects
|
||||||
}
|
}
|
||||||
|
|
||||||
property int type: Anim.Standard
|
property int type: Anim.DefaultSpatial
|
||||||
|
|
||||||
duration: {
|
duration: {
|
||||||
if (type < Anim.StandardSmall || type > Anim.SlowSpatial)
|
if (type < Anim.StandardSmall || type > Anim.SlowEffects)
|
||||||
return Tokens.anim.durations.normal;
|
return Tokens.anim.durations.normal;
|
||||||
|
|
||||||
if (type == Anim.FastSpatial)
|
if (type === Anim.FastSpatial)
|
||||||
return Tokens.anim.durations.expressiveFastSpatial;
|
return Tokens.anim.durations.expressiveFastSpatial;
|
||||||
if (type == Anim.DefaultSpatial)
|
if (type === Anim.DefaultSpatial)
|
||||||
return Tokens.anim.durations.expressiveDefaultSpatial;
|
return Tokens.anim.durations.expressiveDefaultSpatial;
|
||||||
if (type == Anim.SlowSpatial)
|
if (type === Anim.SlowSpatial)
|
||||||
return Tokens.anim.durations.expressiveSlowSpatial;
|
return Tokens.anim.durations.expressiveSlowSpatial;
|
||||||
|
if (type === Anim.FastEffects)
|
||||||
|
return Tokens.anim.durations.expressiveFastEffects;
|
||||||
|
if (type === Anim.DefaultEffects)
|
||||||
|
return Tokens.anim.durations.expressiveDefaultEffects;
|
||||||
|
if (type === Anim.SlowEffects)
|
||||||
|
return Tokens.anim.durations.expressiveSlowEffects;
|
||||||
|
|
||||||
const types = ["small", "normal", "large", "extraLarge"];
|
const types = ["small", "normal", "large", "extraLarge"];
|
||||||
const idx = type % 4; // 0-7 are the 4 standard types
|
const idx = type % 4; // 0-7 are the 4 standard types
|
||||||
return Tokens.anim.durations[types[idx]];
|
return Tokens.anim.durations[types[idx]];
|
||||||
}
|
}
|
||||||
easing: {
|
easing: {
|
||||||
if (type == Anim.FastSpatial)
|
if (type === Anim.FastSpatial)
|
||||||
return Tokens.anim.expressiveFastSpatial;
|
return Tokens.anim.expressiveFastSpatial;
|
||||||
if (type == Anim.DefaultSpatial)
|
if (type === Anim.DefaultSpatial)
|
||||||
return Tokens.anim.expressiveDefaultSpatial;
|
return Tokens.anim.expressiveDefaultSpatial;
|
||||||
if (type == Anim.SlowSpatial)
|
if (type === Anim.SlowSpatial)
|
||||||
return Tokens.anim.expressiveSlowSpatial;
|
return Tokens.anim.expressiveSlowSpatial;
|
||||||
|
if (type === Anim.FastEffects)
|
||||||
|
return Tokens.anim.expressiveFastEffects;
|
||||||
|
if (type === Anim.DefaultEffects)
|
||||||
|
return Tokens.anim.expressiveDefaultEffects;
|
||||||
|
if (type === Anim.SlowEffects)
|
||||||
|
return Tokens.anim.expressiveSlowEffects;
|
||||||
|
|
||||||
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
||||||
return Tokens.anim.emphasized;
|
return Tokens.anim.emphasized;
|
||||||
|
|
|
||||||
42
components/AnimLoader.qml
Normal file
42
components/AnimLoader.qml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property Component sourceComp
|
||||||
|
property bool isComplete
|
||||||
|
property int outAnimType: Anim.FastEffects
|
||||||
|
property int inAnimType: Anim.DefaultEffects
|
||||||
|
|
||||||
|
asynchronous: true
|
||||||
|
Component.onCompleted: {
|
||||||
|
isComplete = true;
|
||||||
|
sourceComponent = sourceComp;
|
||||||
|
}
|
||||||
|
onSourceCompChanged: {
|
||||||
|
if (isComplete)
|
||||||
|
anim.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: anim
|
||||||
|
|
||||||
|
running: false
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
target: root
|
||||||
|
property: "opacity"
|
||||||
|
to: 0
|
||||||
|
type: root.outAnimType
|
||||||
|
}
|
||||||
|
ScriptAction {
|
||||||
|
script: root.sourceComponent = root.sourceComp
|
||||||
|
}
|
||||||
|
Anim {
|
||||||
|
target: root
|
||||||
|
property: "opacity"
|
||||||
|
to: 1
|
||||||
|
type: root.inAnimType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,6 @@ import QtQuick
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
|
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: Tokens.anim.durations.normal
|
duration: Tokens.anim.durations.expressiveSlowEffects
|
||||||
easing: Tokens.anim.standard
|
easing: Tokens.anim.expressiveSlowEffects
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,20 @@ ColumnLayout {
|
||||||
required property string icon
|
required property string icon
|
||||||
required property string title
|
required property string title
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
animate: true
|
animate: true
|
||||||
text: root.icon
|
text: root.icon
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 3
|
fontStyle: Tokens.font.icon.builders.extraLarge.scale(3).weight(Font.Bold).build()
|
||||||
font.bold: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
animate: true
|
animate: true
|
||||||
text: root.title
|
text: root.title
|
||||||
font.pointSize: Tokens.font.size.large
|
font: Tokens.font.title.builders.medium.weight(Font.Bold).build()
|
||||||
font.bold: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ ColumnLayout {
|
||||||
|
|
||||||
required property var deviceDetails
|
required property var deviceDetails
|
||||||
|
|
||||||
spacing: Tokens.spacing.small / 2
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: qsTr("IP Address")
|
text: qsTr("IP Address")
|
||||||
|
|
@ -18,40 +18,40 @@ ColumnLayout {
|
||||||
StyledText {
|
StyledText {
|
||||||
text: root.deviceDetails?.ipAddress || qsTr("Not available")
|
text: root.deviceDetails?.ipAddress || qsTr("Not available")
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.normal
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
text: qsTr("Subnet Mask")
|
text: qsTr("Subnet Mask")
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: root.deviceDetails?.subnet || qsTr("Not available")
|
text: root.deviceDetails?.subnet || qsTr("Not available")
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.normal
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
text: qsTr("Gateway")
|
text: qsTr("Gateway")
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: root.deviceDetails?.gateway || qsTr("Not available")
|
text: root.deviceDetails?.gateway || qsTr("Not available")
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.normal
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
text: qsTr("DNS Servers")
|
text: qsTr("DNS Servers")
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: (root.deviceDetails && root.deviceDetails.dns && root.deviceDetails.dns.length > 0) ? root.deviceDetails.dns.join(", ") : qsTr("Not available")
|
text: (root.deviceDetails && root.deviceDetails.dns && root.deviceDetails.dns.length > 0) ? root.deviceDetails.dns.join(", ") : qsTr("Not available")
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
Layout.maximumWidth: parent.width
|
Layout.maximumWidth: parent.width
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
|
import QtQuick
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
property real fill
|
property real fill
|
||||||
property int grade: Colours.light ? 0 : -25
|
property int grade: Colours.light ? 0 : -25
|
||||||
|
property font fontStyle: Tokens.font.icon.small
|
||||||
|
|
||||||
font.family: Tokens.font.family.material
|
font: Tokens.font.icon.size(fontStyle.pointSize).weight(fontStyle.weight).vaxes(fontStyle.variableAxes).fill(fill.toFixed(1)).grade(grade).build()
|
||||||
font.pointSize: Tokens.font.size.larger
|
|
||||||
font.variableAxes: ({
|
|
||||||
FILL: fill.toFixed(1),
|
|
||||||
GRAD: grade,
|
|
||||||
opsz: fontInfo.pixelSize,
|
|
||||||
wght: fontInfo.weight
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,16 @@ ColumnLayout {
|
||||||
required property string value
|
required property string value
|
||||||
property bool showTopMargin: false
|
property bool showTopMargin: false
|
||||||
|
|
||||||
spacing: Tokens.spacing.small / 2
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: root.showTopMargin ? Tokens.spacing.normal : 0
|
Layout.topMargin: root.showTopMargin ? Tokens.spacing.medium : 0
|
||||||
text: root.label
|
text: root.label
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: root.value
|
text: root.value
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ StyledRect {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
default property alias content: contentColumn.data
|
default property alias content: contentColumn.data
|
||||||
property real contentSpacing: Tokens.spacing.larger
|
property real contentSpacing: Tokens.spacing.large
|
||||||
property bool alignTop: false
|
property bool alignTop: false
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: contentColumn.implicitHeight + Tokens.padding.large * 2
|
implicitHeight: contentColumn.implicitHeight + Tokens.padding.extraLargeIncreased
|
||||||
|
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Colours.transparency.enabled ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : Colours.palette.m3surfaceContainerHigh
|
color: Colours.transparency.enabled ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : Colours.palette.m3surfaceContainerHigh
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,9 @@ ColumnLayout {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.large
|
Layout.topMargin: Tokens.spacing.largeIncreased
|
||||||
text: root.title
|
text: root.title
|
||||||
font.pointSize: Tokens.font.size.larger
|
font: Tokens.font.title.builders.medium.weight(Font.Medium).build()
|
||||||
font.weight: 500
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
|
import Caelestia
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
|
|
@ -8,10 +9,11 @@ MouseArea {
|
||||||
|
|
||||||
property bool disabled
|
property bool disabled
|
||||||
property bool showHoverBackground: true
|
property bool showHoverBackground: true
|
||||||
|
property bool manualPressOverride
|
||||||
readonly property alias rect: base
|
readonly property alias rect: base
|
||||||
|
|
||||||
property bool shapeMorph
|
property bool shapeMorph
|
||||||
property real stateOpacity: pressed ? 0.1 : containsMouse ? 0.08 : 0
|
property real stateOpacity: containsMouse ? 0.08 : 0
|
||||||
|
|
||||||
property real pressX: width / 2
|
property real pressX: width / 2
|
||||||
property real pressY: height / 2
|
property real pressY: height / 2
|
||||||
|
|
@ -29,7 +31,7 @@ MouseArea {
|
||||||
const d2 = distSq(width, 0);
|
const d2 = distSq(width, 0);
|
||||||
const d3 = distSq(0, height);
|
const d3 = distSq(0, height);
|
||||||
const d4 = distSq(width, height);
|
const d4 = distSq(width, height);
|
||||||
return Math.sqrt(Math.max(d1, d2, d3, d4)) * (shapeMorph ? 1.16 : 1);
|
return (Math.sqrt(Math.max(d1, d2, d3, d4)) + (shapeMorph ? 24 : 0)) * 1.3;
|
||||||
}
|
}
|
||||||
property real endRadiusAtPress
|
property real endRadiusAtPress
|
||||||
|
|
||||||
|
|
@ -59,12 +61,17 @@ MouseArea {
|
||||||
onPressed: e => press(e.x, e.y)
|
onPressed: e => press(e.x, e.y)
|
||||||
|
|
||||||
onPressedChanged: {
|
onPressedChanged: {
|
||||||
if (!pressed && !rippleAnim.running && circle.opacity > 0)
|
if (!(pressed || manualPressOverride) && !rippleAnim.running && circle.opacity > 0)
|
||||||
|
fadeAnim.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
onManualPressOverrideChanged: {
|
||||||
|
if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running)
|
||||||
fadeAnim.start();
|
fadeAnim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
onCircleRadiusChanged: {
|
onCircleRadiusChanged: {
|
||||||
if (!pressed && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running)
|
if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running)
|
||||||
fadeAnim.start();
|
fadeAnim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +82,7 @@ MouseArea {
|
||||||
target: root
|
target: root
|
||||||
property: "circleRadius"
|
property: "circleRadius"
|
||||||
to: root.endRadius
|
to: root.endRadius
|
||||||
easing: Tokens.anim.expressiveSlowEffects
|
easing: Tokens.anim.standard
|
||||||
duration: Tokens.anim.durations.expressiveSlowEffects * 2
|
duration: Tokens.anim.durations.expressiveSlowEffects * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,8 +92,7 @@ MouseArea {
|
||||||
target: circle
|
target: circle
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 0
|
to: 0
|
||||||
easing: Tokens.anim.expressiveSlowEffects
|
type: Anim.SlowEffects
|
||||||
duration: Tokens.anim.durations.expressiveSlowEffects
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
|
|
@ -95,8 +101,14 @@ MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
opacity: root.stateOpacity
|
opacity: root.stateOpacity
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
// Pick up radius from parent if it has one (parent can be anything with a radius property)
|
// Pick up radius from parent if it has one (parent can be anything with radius props)
|
||||||
radius: root.parent?.radius ?? 0 // qmllint disable missing-property
|
// qmllint disable missing-property
|
||||||
|
radius: root.parent?.radius ?? 0
|
||||||
|
topLeftRadius: root.parent?.topLeftRadius ?? radius ?? 0
|
||||||
|
topRightRadius: root.parent?.topRightRadius ?? radius ?? 0
|
||||||
|
bottomLeftRadius: root.parent?.bottomLeftRadius ?? radius ?? 0
|
||||||
|
bottomRightRadius: root.parent?.bottomRightRadius ?? radius ?? 0
|
||||||
|
// qmllint enable missing-property
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
|
|
@ -122,12 +134,12 @@ MouseArea {
|
||||||
color: Qt.alpha(base.color, 1)
|
color: Qt.alpha(base.color, 1)
|
||||||
}
|
}
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 0.99
|
position: CUtils.clamp(1 - 0.2 * root.endRadius / root.circleRadius, 0.01, 0.99)
|
||||||
color: Qt.alpha(base.color, 1)
|
color: Qt.alpha(base.color, 1)
|
||||||
}
|
}
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 1
|
position: 1
|
||||||
color: Qt.alpha(base.color, 0)
|
color: Qt.alpha(base.color, CUtils.clamp((root.circleRadius / root.endRadius - 0.9) / 0.1, 0, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,14 +147,14 @@ MouseArea {
|
||||||
startY: 0
|
startY: 0
|
||||||
|
|
||||||
PathLine {
|
PathLine {
|
||||||
x: root.width - root.clamp(base.topLeftRadius)
|
x: root.width - root.clamp(base.topRightRadius)
|
||||||
y: 0
|
y: 0
|
||||||
}
|
}
|
||||||
PathArc {
|
PathArc {
|
||||||
relativeX: root.clamp(base.topLeftRadius)
|
relativeX: root.clamp(base.topRightRadius)
|
||||||
relativeY: root.clamp(base.topLeftRadius)
|
relativeY: root.clamp(base.topRightRadius)
|
||||||
radiusX: root.clamp(base.topLeftRadius)
|
radiusX: root.clamp(base.topRightRadius)
|
||||||
radiusY: root.clamp(base.topLeftRadius)
|
radiusY: root.clamp(base.topRightRadius)
|
||||||
}
|
}
|
||||||
PathLine {
|
PathLine {
|
||||||
x: root.width
|
x: root.width
|
||||||
|
|
@ -179,8 +191,7 @@ MouseArea {
|
||||||
|
|
||||||
Behavior on stateOpacity {
|
Behavior on stateOpacity {
|
||||||
Anim {
|
Anim {
|
||||||
easing: Tokens.anim.expressiveDefaultEffects
|
type: Anim.DefaultEffects
|
||||||
duration: Tokens.anim.durations.expressiveDefaultEffects
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,11 @@ Text {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool animate: false
|
property bool animate: false
|
||||||
property string animateProp: "scale"
|
|
||||||
property real animateFrom: 0
|
|
||||||
property real animateTo: 1
|
|
||||||
property int animateDuration: Tokens.anim.durations.normal
|
|
||||||
|
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
textFormat: Text.PlainText
|
textFormat: Text.PlainText
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
font.family: Tokens.font.family.sans
|
font: Tokens.font.body.small
|
||||||
font.pointSize: Tokens.font.size.smaller
|
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
CAnim {}
|
CAnim {}
|
||||||
|
|
@ -28,20 +23,18 @@ Text {
|
||||||
|
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
to: root.animateFrom
|
target: root
|
||||||
easing: Tokens.anim.standardAccel
|
property: "opacity"
|
||||||
|
to: 0
|
||||||
|
type: Anim.FastEffects
|
||||||
}
|
}
|
||||||
PropertyAction {}
|
PropertyAction {}
|
||||||
Anim {
|
Anim {
|
||||||
to: root.animateTo
|
target: root
|
||||||
easing: Tokens.anim.standardDecel
|
property: "opacity"
|
||||||
|
to: 1
|
||||||
|
type: Anim.DefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component Anim: NumberAnimation {
|
|
||||||
target: root
|
|
||||||
property: root.animateProp
|
|
||||||
duration: root.animateDuration / 2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,28 @@ import qs.components
|
||||||
Flickable {
|
Flickable {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool doneFakeFlick
|
||||||
|
|
||||||
maximumFlickVelocity: 3000
|
maximumFlickVelocity: 3000
|
||||||
|
|
||||||
rebound: Transition {
|
rebound: Transition {
|
||||||
|
onRunningChanged: {
|
||||||
|
if (!running && !root.doneFakeFlick) {
|
||||||
|
root.doneFakeFlick = true;
|
||||||
|
root.flick(1, 1);
|
||||||
|
root.flick(-1, -1);
|
||||||
|
Qt.callLater(() => root.cancelFlick());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
properties: "x,y"
|
properties: "x,y"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: root.doneFakeFlick
|
||||||
|
interval: 10
|
||||||
|
onTriggered: root.doneFakeFlick = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,28 @@ import qs.components
|
||||||
ListView {
|
ListView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool doneFakeFlick
|
||||||
|
|
||||||
maximumFlickVelocity: 3000
|
maximumFlickVelocity: 3000
|
||||||
|
|
||||||
rebound: Transition {
|
rebound: Transition {
|
||||||
|
onRunningChanged: {
|
||||||
|
if (!running && !root.doneFakeFlick) {
|
||||||
|
root.doneFakeFlick = true;
|
||||||
|
root.flick(1, 1);
|
||||||
|
root.flick(-1, -1);
|
||||||
|
Qt.callLater(() => root.cancelFlick());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
properties: "x,y"
|
properties: "x,y"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: root.doneFakeFlick
|
||||||
|
interval: 10
|
||||||
|
onTriggered: root.doneFakeFlick = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
components/containers/VerticalFadeFlickable.qml
Normal file
72
components/containers/VerticalFadeFlickable.qml
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import qs.components
|
||||||
|
import qs.components.effects
|
||||||
|
|
||||||
|
StyledFlickable {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real fadeAmount: 0.2
|
||||||
|
|
||||||
|
property real topFadeOpacity: fadeShouldBeActive(true) ? 0 : 1
|
||||||
|
property real bottomFadeOpacity: fadeShouldBeActive(false) ? 0 : 1
|
||||||
|
|
||||||
|
function fadeShouldBeActive(isStart: bool): bool {
|
||||||
|
// When content is smaller than flickable size, hide fade when rebound starts
|
||||||
|
if (contentHeight + topMargin + bottomMargin < height && rebound.running && ((isStart ? verticalOvershoot > 0 : verticalOvershoot < 0)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (isStart)
|
||||||
|
return visibleArea.yPosition > 0;
|
||||||
|
return visibleArea.yPosition + visibleArea.heightRatio < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
flickableDirection: Flickable.VerticalFlick
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: Mask {
|
||||||
|
maskSource: mask
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: mask
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
layer.enabled: true
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
orientation: Gradient.Vertical
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: Qt.rgba(0, 0, 0, root.topFadeOpacity)
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: root.fadeAmount
|
||||||
|
color: Qt.rgba(0, 0, 0, 1)
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1 - root.fadeAmount
|
||||||
|
color: Qt.rgba(0, 0, 0, 1)
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: Qt.rgba(0, 0, 0, root.bottomFadeOpacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on topFadeOpacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.SlowEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on bottomFadeOpacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.SlowEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
95
components/controls/ButtonBase.qml
Normal file
95
components/controls/ButtonBase.qml
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
import QtQuick
|
||||||
|
import Caelestia.Config
|
||||||
|
import qs.components
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
enum ButtonType {
|
||||||
|
Filled,
|
||||||
|
Tonal,
|
||||||
|
Text
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool checked
|
||||||
|
property alias disabled: stateLayer.disabled
|
||||||
|
property bool isToggle
|
||||||
|
property bool isRound
|
||||||
|
|
||||||
|
property bool radiusMorph: true
|
||||||
|
property alias shapeMorph: stateLayer.shapeMorph
|
||||||
|
property bool fillWidth // For ButtonRow
|
||||||
|
|
||||||
|
property font font
|
||||||
|
property int type: ButtonBase.Filled
|
||||||
|
|
||||||
|
property real padding
|
||||||
|
property real horizontalPadding: padding
|
||||||
|
property real verticalPadding: padding
|
||||||
|
|
||||||
|
readonly property alias pressed: stateLayer.pressed
|
||||||
|
readonly property alias hovered: stateLayer.containsMouse
|
||||||
|
readonly property alias stateLayer: stateLayer
|
||||||
|
readonly property alias radiusAnim: radiusAnim
|
||||||
|
|
||||||
|
property color activeColour
|
||||||
|
property color inactiveColour
|
||||||
|
property color activeOnColour
|
||||||
|
property color inactiveOnColour
|
||||||
|
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
|
||||||
|
property color disabledOnColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
|
||||||
|
|
||||||
|
property bool internalChecked
|
||||||
|
property real shapeMorphExpansion: shapeMorph && pressed ? 24 : 0 // Apparently it's always 24px no matter the width of the button
|
||||||
|
readonly property color onColour: disabled ? disabledOnColour : internalChecked ? activeOnColour : inactiveOnColour
|
||||||
|
|
||||||
|
property real pressedRadius: Tokens.rounding.small
|
||||||
|
property real checkedRadius: Tokens.rounding.medium
|
||||||
|
property real defaultRadius: Tokens.rounding.large
|
||||||
|
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
onCheckedChanged: internalChecked = checked
|
||||||
|
|
||||||
|
radius: {
|
||||||
|
if (radiusMorph && pressed)
|
||||||
|
return pressedRadius;
|
||||||
|
if (internalChecked)
|
||||||
|
return checkedRadius;
|
||||||
|
if (isRound)
|
||||||
|
return (height || implicitHeight) / 2 * Math.min(1, Tokens.rounding.scale);
|
||||||
|
return defaultRadius;
|
||||||
|
}
|
||||||
|
color: type === ButtonBase.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour
|
||||||
|
|
||||||
|
// Make size required so we don't forget to set it
|
||||||
|
required implicitWidth
|
||||||
|
required implicitHeight
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
id: stateLayer
|
||||||
|
|
||||||
|
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
||||||
|
disabled: root.disabled
|
||||||
|
onClicked: {
|
||||||
|
if (root.isToggle)
|
||||||
|
root.internalChecked = !root.internalChecked;
|
||||||
|
root.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on radius {
|
||||||
|
Anim {
|
||||||
|
id: radiusAnim
|
||||||
|
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on shapeMorphExpansion {
|
||||||
|
Anim {
|
||||||
|
type: Anim.FastSpatial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,8 +19,8 @@ BusyIndicator {
|
||||||
Completing
|
Completing
|
||||||
}
|
}
|
||||||
|
|
||||||
property real implicitSize: Tokens.font.size.normal * 3
|
property real implicitSize: Tokens.font.body.medium.pointSize * 3
|
||||||
property real strokeWidth: Tokens.padding.small * 0.8
|
property real strokeWidth: Tokens.padding.extraSmall
|
||||||
property color fgColour: Colours.palette.m3primary
|
property color fgColour: Colours.palette.m3primary
|
||||||
property color bgColour: Colours.palette.m3secondaryContainer
|
property color bgColour: Colours.palette.m3secondaryContainer
|
||||||
|
|
||||||
|
|
@ -63,6 +63,7 @@ BusyIndicator {
|
||||||
|
|
||||||
transitions: Transition {
|
transitions: Transition {
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
properties: "opacity,internalStrokeWidth"
|
properties: "opacity,internalStrokeWidth"
|
||||||
duration: manager.completeEndDuration * Tokens.anim.durations.scale
|
duration: manager.completeEndDuration * Tokens.anim.durations.scale
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +78,7 @@ BusyIndicator {
|
||||||
rotation: manager.rotation
|
rotation: manager.rotation
|
||||||
startAngle: manager.startFraction * 360
|
startAngle: manager.startFraction * 360
|
||||||
value: manager.endFraction - manager.startFraction
|
value: manager.endFraction - manager.startFraction
|
||||||
|
hasEndIndicator: false
|
||||||
}
|
}
|
||||||
|
|
||||||
CircularIndicatorManager {
|
CircularIndicatorManager {
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,122 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
|
import Caelestia.Components
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
Shape {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property real value
|
property real value
|
||||||
property int startAngle: -90
|
property int startAngle: -90
|
||||||
property int strokeWidth: Tokens.padding.smaller
|
property int sweepAngle: 360
|
||||||
|
property int strokeWidth: Tokens.padding.small
|
||||||
property int padding: 0
|
property int padding: 0
|
||||||
property int spacing: Tokens.spacing.small
|
property int spacing: Tokens.spacing.small
|
||||||
property color fgColour: Colours.palette.m3primary
|
property color fgColour: Colours.palette.m3primary
|
||||||
property color bgColour: Colours.palette.m3secondaryContainer
|
property color bgColour: Colours.palette.m3secondaryContainer
|
||||||
|
property alias hasEndIndicator: dot.active
|
||||||
|
|
||||||
|
property bool wavy: false
|
||||||
|
property alias waveFrequency: wave.frequency
|
||||||
|
property alias waveAmplitude: wave.amplitudeMultiplier
|
||||||
|
property bool wavePaused
|
||||||
|
property alias waveDuration: waveProgAnim.duration
|
||||||
|
|
||||||
readonly property real size: Math.min(width, height)
|
readonly property real size: Math.min(width, height)
|
||||||
readonly property real arcRadius: (size - padding - strokeWidth) / 2
|
readonly property real arcRadius: (size - padding - strokeWidth * (1 + waveAmplitude * 2)) / 2
|
||||||
readonly property real vValue: value || 1 / 360
|
property real clampedVal: Math.max(1 / 360, Math.min(1, isNaN(value) ? 0 : value)) // Not readonly for animations
|
||||||
readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI)
|
readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI)
|
||||||
|
readonly property real dotAngleRad: (startAngle + sweepAngle - gapAngle * (sweepAngle < 360 ? 0 : 1)) * Math.PI / 180
|
||||||
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2 // For consumers
|
||||||
asynchronous: true
|
property real implicitSize
|
||||||
|
|
||||||
ShapePath {
|
implicitWidth: implicitSize
|
||||||
fillColor: "transparent"
|
implicitHeight: implicitSize
|
||||||
strokeColor: root.bgColour
|
|
||||||
strokeWidth: root.strokeWidth
|
|
||||||
capStyle: root.Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
|
||||||
|
|
||||||
PathAngleArc {
|
Shape {
|
||||||
startAngle: root.startAngle + 360 * root.vValue + root.gapAngle
|
preferredRendererType: Shape.CurveRenderer
|
||||||
sweepAngle: Math.max(-root.gapAngle, 360 * (1 - root.vValue) - root.gapAngle * 2)
|
asynchronous: true
|
||||||
radiusX: root.arcRadius
|
opacity: Math.min(1, remainingArc.sweepAngle)
|
||||||
radiusY: root.arcRadius
|
|
||||||
centerX: root.size / 2
|
|
||||||
centerY: root.size / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on strokeColor {
|
ShapePath {
|
||||||
CAnim {
|
fillColor: "transparent"
|
||||||
duration: Tokens.anim.durations.large
|
strokeColor: root.bgColour
|
||||||
|
strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth
|
||||||
|
capStyle: ShapePath.RoundCap
|
||||||
|
|
||||||
|
PathAngleArc {
|
||||||
|
id: remainingArc
|
||||||
|
|
||||||
|
radiusX: root.arcRadius
|
||||||
|
radiusY: root.arcRadius
|
||||||
|
centerX: root.size / 2
|
||||||
|
centerY: root.size / 2
|
||||||
|
startAngle: root.startAngle + root.clampedVal * root.sweepAngle + root.gapAngle
|
||||||
|
sweepAngle: Math.max(1 / 360, root.sweepAngle * (1 - root.clampedVal) - root.gapAngle * (root.sweepAngle < 360 ? 1 : 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on strokeColor {
|
||||||
|
CAnim {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapePath {
|
WavyLine {
|
||||||
fillColor: "transparent"
|
id: wave
|
||||||
strokeColor: root.fgColour
|
|
||||||
strokeWidth: root.strokeWidth
|
|
||||||
capStyle: root.Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
|
||||||
|
|
||||||
PathAngleArc {
|
anchors.fill: parent
|
||||||
startAngle: root.startAngle
|
anchors.margins: -lineWidth * amplitudeMultiplier
|
||||||
sweepAngle: 360 * root.vValue
|
|
||||||
radiusX: root.arcRadius
|
lineWidth: root.strokeWidth
|
||||||
radiusY: root.arcRadius
|
color: root.fgColour
|
||||||
centerX: root.size / 2
|
pathType: WavyLine.Arc
|
||||||
centerY: root.size / 2
|
radius: root.arcRadius
|
||||||
|
startAngle: root.startAngle
|
||||||
|
fullAngle: root.sweepAngle
|
||||||
|
value: root.clampedVal
|
||||||
|
frequency: 8
|
||||||
|
amplitudeMultiplier: root.wavy ? 0.5 : 0
|
||||||
|
|
||||||
|
Anim on waveProgress {
|
||||||
|
id: waveProgAnim
|
||||||
|
|
||||||
|
running: true
|
||||||
|
paused: root.wavePaused || wave.amplitudeMultiplier === 0
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
duration: 2000
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
loops: Animation.Infinite
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on strokeColor {
|
Behavior on color {
|
||||||
CAnim {
|
CAnim {}
|
||||||
duration: Tokens.anim.durations.large
|
}
|
||||||
|
|
||||||
|
Behavior on amplitudeMultiplier {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: dot
|
||||||
|
|
||||||
|
x: root.size / 2 + root.arcRadius * Math.cos(root.dotAngleRad) - width / 2
|
||||||
|
y: root.size / 2 + root.arcRadius * Math.sin(root.dotAngleRad) - height / 2
|
||||||
|
|
||||||
|
sourceComponent: StyledRect {
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
color: root.fgColour
|
||||||
|
opacity: Math.min(1, remainingArc.sweepAngle)
|
||||||
|
implicitWidth: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth)
|
||||||
|
implicitHeight: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ ColumnLayout {
|
||||||
id: sectionHeaderItem
|
id: sectionHeaderItem
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Math.max(titleRow.implicitHeight + Tokens.padding.normal * 2, 48)
|
Layout.preferredHeight: Math.max(titleRow.implicitHeight + Tokens.padding.medium * 2, 48)
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: titleRow
|
id: titleRow
|
||||||
|
|
@ -32,14 +32,13 @@ ColumnLayout {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: Tokens.padding.normal
|
anchors.leftMargin: Tokens.padding.medium
|
||||||
anchors.rightMargin: Tokens.padding.normal
|
anchors.rightMargin: Tokens.padding.medium
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: root.title
|
text: root.title
|
||||||
font.pointSize: Tokens.font.size.larger
|
font: Tokens.font.title.builders.medium.weight(Font.Medium).build()
|
||||||
font.weight: 500
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -50,7 +49,7 @@ ColumnLayout {
|
||||||
text: "expand_more"
|
text: "expand_more"
|
||||||
rotation: root.expanded ? 180 : 0
|
rotation: root.expanded ? 180 : 0
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.normal
|
fontStyle: Tokens.font.icon.medium
|
||||||
|
|
||||||
Behavior on rotation {
|
Behavior on rotation {
|
||||||
Anim {
|
Anim {
|
||||||
|
|
@ -63,7 +62,7 @@ ColumnLayout {
|
||||||
StateLayer {
|
StateLayer {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
showHoverBackground: false
|
showHoverBackground: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.toggleRequested();
|
root.toggleRequested();
|
||||||
|
|
@ -76,7 +75,7 @@ ColumnLayout {
|
||||||
id: contentWrapper
|
id: contentWrapper
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: root.expanded ? (contentColumn.implicitHeight + Tokens.spacing.small * 2) : 0
|
Layout.preferredHeight: root.expanded ? (contentColumn.implicitHeight + Tokens.spacing.large) : 0
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Behavior on Layout.preferredHeight {
|
Behavior on Layout.preferredHeight {
|
||||||
|
|
@ -87,13 +86,15 @@ ColumnLayout {
|
||||||
id: backgroundRect
|
id: backgroundRect
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Colours.transparency.enabled ? Colours.layer(Colours.palette.m3surfaceContainer, root.nested ? 3 : 2) : (root.nested ? Colours.palette.m3surfaceContainerHigh : Colours.palette.m3surfaceContainer)
|
color: Colours.transparency.enabled ? Colours.layer(Colours.palette.m3surfaceContainer, root.nested ? 3 : 2) : (root.nested ? Colours.palette.m3surfaceContainerHigh : Colours.palette.m3surfaceContainer)
|
||||||
opacity: root.showBackground && root.expanded ? 1.0 : 0.0
|
opacity: root.showBackground && root.expanded ? 1.0 : 0.0
|
||||||
visible: root.showBackground
|
visible: root.showBackground
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,26 +104,28 @@ ColumnLayout {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
y: Tokens.spacing.small
|
y: Tokens.spacing.small
|
||||||
anchors.leftMargin: Tokens.padding.normal
|
anchors.leftMargin: Tokens.padding.medium
|
||||||
anchors.rightMargin: Tokens.padding.normal
|
anchors.rightMargin: Tokens.padding.medium
|
||||||
anchors.bottomMargin: Tokens.spacing.small
|
anchors.bottomMargin: Tokens.spacing.small
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
opacity: root.expanded ? 1.0 : 0.0
|
opacity: root.expanded ? 1.0 : 0.0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: descriptionText
|
id: descriptionText
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: root.description !== "" ? Tokens.spacing.smaller : 0
|
Layout.topMargin: root.description !== "" ? Tokens.spacing.medium : 0
|
||||||
Layout.bottomMargin: root.description !== "" ? Tokens.spacing.small : 0
|
Layout.bottomMargin: root.description !== "" ? Tokens.spacing.small : 0
|
||||||
visible: root.description !== ""
|
visible: root.description !== ""
|
||||||
text: root.description
|
text: root.description
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,23 +73,23 @@ RowLayout {
|
||||||
root.isEditing = false;
|
root.isEditing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
padding: Tokens.padding.small
|
padding: Tokens.padding.extraSmall
|
||||||
leftPadding: Tokens.padding.normal
|
leftPadding: Tokens.padding.medium
|
||||||
rightPadding: Tokens.padding.normal
|
rightPadding: Tokens.padding.medium
|
||||||
|
|
||||||
background: StyledRect {
|
background: StyledRect {
|
||||||
implicitWidth: 100
|
implicitWidth: 100
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
color: Colours.tPalette.m3surfaceContainerHigh
|
color: Colours.tPalette.m3surfaceContainerHigh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
color: Colours.palette.m3primary
|
color: Colours.palette.m3primary
|
||||||
|
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: upIcon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: upIcon.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
id: upState
|
id: upState
|
||||||
|
|
@ -120,11 +120,11 @@ RowLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
color: Colours.palette.m3primary
|
color: Colours.palette.m3primary
|
||||||
|
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: downIcon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: downIcon.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
id: downState
|
id: downState
|
||||||
|
|
|
||||||
|
|
@ -67,47 +67,29 @@ Slider {
|
||||||
|
|
||||||
property bool moving
|
property bool moving
|
||||||
|
|
||||||
function update(): void {
|
|
||||||
animate = !moving;
|
|
||||||
binding.when = moving;
|
|
||||||
font.pointSize = moving ? Tokens.font.size.small : Tokens.font.size.larger;
|
|
||||||
font.family = moving ? Tokens.font.family.sans : Tokens.font.family.material;
|
|
||||||
}
|
|
||||||
|
|
||||||
text: root.icon
|
|
||||||
color: Colours.palette.m3inverseOnSurface
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
anchors.verticalCenterOffset: 1
|
||||||
|
text: moving ? Math.round(root.value * 100) : root.icon
|
||||||
|
color: Colours.palette.m3inverseOnSurface
|
||||||
|
font: moving ? Tokens.font.body.small : Tokens.font.icon.medium
|
||||||
|
|
||||||
onMovingChanged: anim.restart()
|
Behavior on moving {
|
||||||
|
SequentialAnimation {
|
||||||
Binding {
|
Anim {
|
||||||
id: binding
|
target: icon
|
||||||
|
property: "scale"
|
||||||
target: icon
|
to: 0.3
|
||||||
property: "text"
|
duration: Tokens.anim.durations.small / 2
|
||||||
value: Math.round(root.value * 100)
|
easing: Tokens.anim.standardAccel
|
||||||
when: false
|
}
|
||||||
}
|
PropertyAction {}
|
||||||
|
Anim {
|
||||||
SequentialAnimation {
|
target: icon
|
||||||
id: anim
|
property: "scale"
|
||||||
|
to: 1
|
||||||
Anim {
|
duration: Tokens.anim.durations.normal / 2
|
||||||
target: icon
|
easing: Tokens.anim.standardDecel
|
||||||
property: "scale"
|
}
|
||||||
to: 0
|
|
||||||
duration: Tokens.anim.durations.normal / 2
|
|
||||||
easing: Tokens.anim.standardAccel
|
|
||||||
}
|
|
||||||
ScriptAction {
|
|
||||||
script: icon.update()
|
|
||||||
}
|
|
||||||
Anim {
|
|
||||||
target: icon
|
|
||||||
property: "scale"
|
|
||||||
to: 1
|
|
||||||
duration: Tokens.anim.durations.normal / 2
|
|
||||||
easing: Tokens.anim.standardDecel
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,80 +3,50 @@ import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledRect {
|
ButtonBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Filled,
|
|
||||||
Tonal,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias icon: label.text
|
property alias icon: label.text
|
||||||
property bool checked
|
readonly property alias label: label
|
||||||
property bool toggle
|
|
||||||
property real padding: type === IconButton.Text ? Tokens.padding.small / 2 : Tokens.padding.smaller
|
|
||||||
property alias font: label.font
|
|
||||||
property int type: IconButton.Filled
|
|
||||||
property bool disabled
|
|
||||||
|
|
||||||
property alias stateLayer: stateLayer
|
font: Tokens.font.icon.medium
|
||||||
property alias label: label
|
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small
|
||||||
property alias radiusAnim: radiusAnim
|
|
||||||
|
|
||||||
property bool internalChecked
|
activeColour: type === IconButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
||||||
property color activeColour: type === IconButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
inactiveColour: {
|
||||||
property color inactiveColour: {
|
if (!isToggle && type === IconButton.Filled)
|
||||||
if (!toggle && type === IconButton.Filled)
|
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === IconButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
return type === IconButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
||||||
}
|
}
|
||||||
property color activeOnColour: type === IconButton.Filled ? Colours.palette.m3onPrimary : type === IconButton.Tonal ? Colours.palette.m3onSecondary : Colours.palette.m3primary
|
activeOnColour: type === IconButton.Filled ? Colours.palette.m3onPrimary : type === IconButton.Tonal ? Colours.palette.m3onSecondary : Colours.palette.m3primary
|
||||||
property color inactiveOnColour: {
|
inactiveOnColour: {
|
||||||
if (!toggle && type === IconButton.Filled)
|
if (!isToggle && type === IconButton.Filled)
|
||||||
return Colours.palette.m3onPrimary;
|
return Colours.palette.m3onPrimary;
|
||||||
return type === IconButton.Tonal ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurfaceVariant;
|
return type === IconButton.Tonal ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurfaceVariant;
|
||||||
}
|
}
|
||||||
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
|
|
||||||
property color disabledOnColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
|
|
||||||
|
|
||||||
signal clicked
|
|
||||||
|
|
||||||
onCheckedChanged: internalChecked = checked
|
|
||||||
|
|
||||||
radius: internalChecked ? Tokens.rounding.small : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
|
||||||
color: type === IconButton.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour
|
|
||||||
|
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: label.implicitHeight + padding * 2
|
implicitHeight: {
|
||||||
|
// Ensure even size so icon is centered properly
|
||||||
StateLayer {
|
const h = label.implicitHeight + padding * 2;
|
||||||
id: stateLayer
|
if (h % 2 !== 0)
|
||||||
|
return h + 1;
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
return h;
|
||||||
disabled: root.disabled
|
|
||||||
onClicked: {
|
|
||||||
if (root.toggle)
|
|
||||||
root.internalChecked = !root.internalChecked;
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: root.disabled ? root.disabledOnColour : root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
anchors.verticalCenterOffset: 1 // AHHHHHHH material symbols whyyyy
|
||||||
fill: !root.toggle || root.internalChecked ? 1 : 0
|
color: root.onColour
|
||||||
|
fontStyle: root.font
|
||||||
|
fill: !root.isToggle || root.internalChecked ? 1 : 0
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
Anim {}
|
Anim {
|
||||||
}
|
type: Anim.DefaultEffects
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {
|
|
||||||
id: radiusAnim
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,55 +4,40 @@ import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledRect {
|
ButtonBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Filled,
|
|
||||||
Tonal,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias icon: iconLabel.text
|
property alias icon: iconLabel.text
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property bool checked
|
|
||||||
property bool toggle
|
|
||||||
property real horizontalPadding: Tokens.padding.normal
|
|
||||||
property real verticalPadding: Tokens.padding.smaller
|
|
||||||
property alias font: label.font
|
|
||||||
property int type: IconTextButton.Filled
|
|
||||||
|
|
||||||
property alias stateLayer: stateLayer
|
readonly property alias iconLabel: iconLabel
|
||||||
property alias iconLabel: iconLabel
|
readonly property alias label: label
|
||||||
property alias label: label
|
|
||||||
|
|
||||||
property bool internalChecked
|
horizontalPadding: Tokens.padding.medium
|
||||||
property color activeColour: type === IconTextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
verticalPadding: Tokens.padding.small
|
||||||
property color inactiveColour: type === IconTextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer
|
|
||||||
property color activeOnColour: type === IconTextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary
|
|
||||||
property color inactiveOnColour: type === IconTextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
|
||||||
|
|
||||||
signal clicked
|
activeColour: type === TextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
||||||
|
inactiveColour: {
|
||||||
onCheckedChanged: internalChecked = checked
|
if (!isToggle && type === TextButton.Filled)
|
||||||
|
return Colours.palette.m3primary;
|
||||||
radius: internalChecked ? Tokens.rounding.small : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
return type === TextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
||||||
color: type === IconTextButton.Text ? "transparent" : internalChecked ? activeColour : inactiveColour
|
}
|
||||||
|
activeOnColour: {
|
||||||
|
if (type === TextButton.Text)
|
||||||
|
return Colours.palette.m3primary;
|
||||||
|
return type === TextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary;
|
||||||
|
}
|
||||||
|
inactiveOnColour: {
|
||||||
|
if (!isToggle && type === TextButton.Filled)
|
||||||
|
return Colours.palette.m3onPrimary;
|
||||||
|
if (type === TextButton.Text)
|
||||||
|
return Colours.palette.m3primary;
|
||||||
|
return type === TextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer;
|
||||||
|
}
|
||||||
|
|
||||||
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
||||||
implicitHeight: row.implicitHeight + verticalPadding * 2
|
implicitHeight: row.implicitHeight + verticalPadding * 2
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
|
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
|
||||||
onClicked: {
|
|
||||||
if (root.toggle)
|
|
||||||
root.internalChecked = !root.internalChecked;
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: row
|
id: row
|
||||||
|
|
||||||
|
|
@ -64,11 +49,18 @@ StyledRect {
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.topMargin: Math.round(fontInfo.pointSize * 0.0575)
|
Layout.topMargin: Math.round(fontInfo.pointSize * 0.0575)
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
fill: root.internalChecked ? 1 : 0
|
fill: root.internalChecked ? 1 : 0
|
||||||
|
fontStyle: {
|
||||||
|
const f = Qt.font(root.font);
|
||||||
|
f.pointSize = Math.round(root.font.pointSize * 1.1);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,11 +69,8 @@ StyledRect {
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.topMargin: -Math.round(iconLabel.fontInfo.pointSize * 0.0575)
|
Layout.topMargin: -Math.round(iconLabel.fontInfo.pointSize * 0.0575)
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
|
font: root.font
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
116
components/controls/LoadingIndicator.qml
Normal file
116
components/controls/LoadingIndicator.qml
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import M3Shapes
|
||||||
|
import qs.components
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
MaterialShape {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property list<int> shapes: {
|
||||||
|
if (containsIcon)
|
||||||
|
return [MaterialShape.SoftBurst, MaterialShape.Cookie9Sided, MaterialShape.Pill, MaterialShape.Sunny, MaterialShape.Cookie4Sided, MaterialShape.Oval];
|
||||||
|
return [MaterialShape.SoftBurst, MaterialShape.Cookie9Sided, MaterialShape.Pentagon, MaterialShape.Pill, MaterialShape.Sunny, MaterialShape.Cookie4Sided, MaterialShape.Oval];
|
||||||
|
}
|
||||||
|
property int shapeIndex
|
||||||
|
property real cRotation
|
||||||
|
property real lRotation
|
||||||
|
property real thisLRotation
|
||||||
|
property bool containsIcon
|
||||||
|
|
||||||
|
property bool animated: true
|
||||||
|
property int morphAnimRotation: 60
|
||||||
|
property real morphScale: 0.14
|
||||||
|
property alias rotateAnimDuration: rotateAnim.duration
|
||||||
|
|
||||||
|
property real stiffness: 180
|
||||||
|
property real dampingRatio: 0.6
|
||||||
|
property real visibilityThreshold: 0.075
|
||||||
|
|
||||||
|
readonly property real springDuration: {
|
||||||
|
const wn = Math.sqrt(stiffness);
|
||||||
|
const r = -dampingRatio * wn;
|
||||||
|
const c = 1 / Math.sqrt(1 - dampingRatio * dampingRatio);
|
||||||
|
return Math.log(visibilityThreshold / c) / r;
|
||||||
|
}
|
||||||
|
readonly property real springMaxVelocity: {
|
||||||
|
const wn = Math.sqrt(stiffness);
|
||||||
|
const factor = Math.exp(-z * Math.acos(z) / Math.sqrt(1 - z * z));
|
||||||
|
return wn * factor;
|
||||||
|
}
|
||||||
|
property bool springSettled: true
|
||||||
|
|
||||||
|
function spring(t: real): var {
|
||||||
|
const wn = Math.sqrt(stiffness);
|
||||||
|
const za = dampingRatio * wn;
|
||||||
|
|
||||||
|
const wd = wn * Math.sqrt(1 - dampingRatio * dampingRatio);
|
||||||
|
const r = za / wd;
|
||||||
|
const pos = 1 - Math.exp(-za * t) * (Math.cos(wd * t) + r * Math.sin(wd * t));
|
||||||
|
const vel = Math.exp(-za * t) * (wn * wn / wd) * Math.sin(wd * t);
|
||||||
|
|
||||||
|
return [pos, vel];
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitSize: 38
|
||||||
|
color: Colours.palette.m3primary
|
||||||
|
toShape: shapes[0]
|
||||||
|
|
||||||
|
ElapsedTimer {
|
||||||
|
id: timer
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameAnimation {
|
||||||
|
running: root.animated && !root.springSettled
|
||||||
|
onTriggered: {
|
||||||
|
const t = timer.elapsed();
|
||||||
|
|
||||||
|
if (t >= root.springDuration) {
|
||||||
|
root.springSettled = true;
|
||||||
|
} else {
|
||||||
|
const [pos, vel] = root.spring(t);
|
||||||
|
root.morphProgress = Math.min(1, pos); // Overshooting the morph looks weird
|
||||||
|
root.thisLRotation = pos * root.morphAnimRotation;
|
||||||
|
root.scale = 1 + vel * root.morphScale / root.springMaxVelocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 650
|
||||||
|
repeat: true
|
||||||
|
triggeredOnStart: true
|
||||||
|
running: root.animated
|
||||||
|
onTriggered: {
|
||||||
|
root.beginBatchUpdate();
|
||||||
|
root.fromShape = root.toShape;
|
||||||
|
root.shapeIndex = (root.shapeIndex + 1) % root.shapes.length;
|
||||||
|
root.toShape = root.shapes[root.shapeIndex];
|
||||||
|
root.morphProgress = 0;
|
||||||
|
|
||||||
|
root.rotation = root.rotation;
|
||||||
|
root.lRotation = (root.lRotation + root.thisLRotation) % 360;
|
||||||
|
root.thisLRotation = 0;
|
||||||
|
root.rotation = Qt.binding(() => root.cRotation + root.lRotation + root.thisLRotation);
|
||||||
|
|
||||||
|
root.springSettled = false;
|
||||||
|
timer.restart();
|
||||||
|
root.endBatchUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RotationAnimation on cRotation {
|
||||||
|
id: rotateAnim
|
||||||
|
|
||||||
|
running: root.animated
|
||||||
|
from: 0
|
||||||
|
to: 360
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
loops: Animation.Infinite
|
||||||
|
duration: 4666
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ MouseArea {
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.small
|
type: Anim.DefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ MouseArea {
|
||||||
return item.mapToItem(root.parent, 0, off).y + root.marginY;
|
return item.mapToItem(root.parent, 0, off).y + root.marginY;
|
||||||
}
|
}
|
||||||
|
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
level: 2
|
level: 2
|
||||||
|
|
||||||
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
|
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
|
||||||
|
|
@ -90,9 +90,7 @@ MouseArea {
|
||||||
origin.y: root.thisSideY === Menu.Bottom ? menu.height : 0
|
origin.y: root.thisSideY === Menu.Bottom ? menu.height : 0
|
||||||
|
|
||||||
Behavior on yScale {
|
Behavior on yScale {
|
||||||
Anim {
|
Anim {}
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +103,7 @@ MouseArea {
|
||||||
id: column
|
id: column
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.extraSmall
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -118,17 +116,17 @@ MouseArea {
|
||||||
|
|
||||||
required property int index
|
required property int index
|
||||||
required property MenuItem modelData
|
required property MenuItem modelData
|
||||||
readonly property bool active: modelData === root.active
|
readonly property bool active: modelData === root?.active
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
radius: active ? 12 : Tokens.rounding.extraSmall // This should use a token, but tokens are currently extremely scuffed
|
radius: active ? Tokens.rounding.medium : Tokens.rounding.extraSmall
|
||||||
topLeftRadius: index === 0 ? Tokens.rounding.small : radius
|
topLeftRadius: index === 0 ? Tokens.rounding.medium : radius
|
||||||
topRightRadius: index === 0 ? Tokens.rounding.small : radius
|
topRightRadius: index === 0 ? Tokens.rounding.medium : radius
|
||||||
bottomLeftRadius: index === repeater.count - 1 ? Tokens.rounding.small : radius
|
bottomLeftRadius: index === repeater?.count - 1 ? Tokens.rounding.medium : radius
|
||||||
bottomRightRadius: index === repeater.count - 1 ? Tokens.rounding.small : radius
|
bottomRightRadius: index === repeater?.count - 1 ? Tokens.rounding.medium : radius
|
||||||
|
|
||||||
color: Qt.alpha(Colours.palette.m3tertiaryContainer, active ? 1 : 0)
|
color: Qt.alpha(Colours.palette.m3tertiaryContainer, active ? 1 : 0)
|
||||||
|
|
||||||
|
|
@ -156,26 +154,26 @@ MouseArea {
|
||||||
id: menuOptionRow
|
id: menuOptionRow
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
text: item.modelData.icon
|
text: item.modelData?.icon ?? ""
|
||||||
color: item.active ? Colours.palette.m3onTertiaryContainer : Colours.palette.m3onSurfaceVariant
|
color: item.active ? Colours.palette.m3onTertiaryContainer : Colours.palette.m3onSurfaceVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: item.modelData.text
|
text: item.modelData?.text ?? ""
|
||||||
color: item.active ? Colours.palette.m3onTertiaryContainer : Colours.palette.m3onSurface
|
color: item.active ? Colours.palette.m3onTertiaryContainer : Colours.palette.m3onSurface
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
active: item.modelData.trailingIcon.length > 0
|
active: item.modelData?.trailingIcon.length > 0
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
sourceComponent: MaterialIcon {
|
sourceComponent: MaterialIcon {
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ StyledRect {
|
||||||
property var onValueModified: function (value) {}
|
property var onValueModified: function (value) {}
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: row.implicitHeight + Tokens.padding.large * 2
|
implicitHeight: row.implicitHeight + Tokens.padding.extraLargeIncreased
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
|
|
@ -30,7 +30,7 @@ StyledRect {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.margins: Tokens.padding.large
|
anchors.margins: Tokens.padding.large
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -12,43 +12,46 @@ Row {
|
||||||
Tonal
|
Tonal
|
||||||
}
|
}
|
||||||
|
|
||||||
property real horizontalPadding: Tokens.padding.normal
|
property real horizontalPadding: Tokens.padding.medium
|
||||||
property real verticalPadding: Tokens.padding.smaller
|
property real verticalPadding: Tokens.padding.small
|
||||||
property int type: SplitButton.Filled
|
property int type: SplitButton.Filled
|
||||||
property bool disabled
|
property bool disabled
|
||||||
property bool menuOnTop
|
property bool menuOnTop
|
||||||
property string fallbackIcon
|
property string fallbackIcon
|
||||||
property string fallbackText
|
property string fallbackText
|
||||||
|
property real minLeftWidth
|
||||||
|
|
||||||
property alias menuItems: menu.items
|
property alias menuItems: menu.items
|
||||||
property alias active: menu.active
|
property alias active: menu.active
|
||||||
property alias expanded: menu.expanded
|
property alias expanded: menu.expanded
|
||||||
property alias menu: menu
|
readonly property alias menu: menu
|
||||||
property alias iconLabel: iconLabel
|
readonly property alias iconLabel: iconLabel
|
||||||
property alias label: label
|
readonly property alias label: label
|
||||||
property alias stateLayer: stateLayer
|
readonly property alias stateLayer: stateLayer
|
||||||
|
readonly property alias textRow: textRow
|
||||||
|
readonly property alias expandBtn: expandBtn
|
||||||
|
|
||||||
property color colour: type == SplitButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondaryContainer
|
property color colour: type == SplitButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondaryContainer
|
||||||
property color textColour: type == SplitButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondaryContainer
|
property color textColour: type == SplitButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondaryContainer
|
||||||
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
|
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
|
||||||
property color disabledTextColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
|
property color disabledTextColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
|
||||||
|
|
||||||
spacing: Math.floor(Tokens.spacing.small / 2)
|
spacing: Math.floor(Tokens.spacing.extraSmall)
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
||||||
topRightRadius: Tokens.rounding.small / 2
|
topRightRadius: Tokens.rounding.medium / 2
|
||||||
bottomRightRadius: Tokens.rounding.small / 2
|
bottomRightRadius: Tokens.rounding.medium / 2
|
||||||
color: root.disabled ? root.disabledColour : root.colour
|
color: root.disabled ? root.disabledColour : root.colour
|
||||||
|
|
||||||
implicitWidth: textRow.implicitWidth + root.horizontalPadding * 2
|
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
|
||||||
implicitHeight: expandBtn.implicitHeight
|
implicitHeight: expandBtn.implicitHeight
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
id: stateLayer
|
id: stateLayer
|
||||||
|
|
||||||
rect.topRightRadius: parent.topRightRadius
|
topRightRadius: parent.topRightRadius
|
||||||
rect.bottomRightRadius: parent.bottomRightRadius
|
bottomRightRadius: parent.bottomRightRadius
|
||||||
color: root.textColour
|
color: root.textColour
|
||||||
disabled: root.disabled
|
disabled: root.disabled
|
||||||
onClicked: root.active?.clicked()
|
onClicked: root.active?.clicked()
|
||||||
|
|
@ -93,7 +96,7 @@ Row {
|
||||||
StyledRect {
|
StyledRect {
|
||||||
id: expandBtn
|
id: expandBtn
|
||||||
|
|
||||||
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.small / 2
|
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.medium / 2
|
||||||
|
|
||||||
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
||||||
topLeftRadius: rad
|
topLeftRadius: rad
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ StyledRect {
|
||||||
signal selected(item: MenuItem)
|
signal selected(item: MenuItem)
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: row.implicitHeight + Tokens.padding.large * 2
|
implicitHeight: row.implicitHeight + Tokens.padding.extraLargeIncreased
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
||||||
|
|
||||||
clip: false
|
clip: false
|
||||||
|
|
@ -33,7 +33,7 @@ StyledRect {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.large
|
anchors.margins: Tokens.padding.large
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,14 @@ Item {
|
||||||
signal editingFinished
|
signal editingFinished
|
||||||
|
|
||||||
implicitWidth: 70
|
implicitWidth: 70
|
||||||
implicitHeight: inputField.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: inputField.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
id: container
|
id: container
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: inputHover.containsMouse || inputField.activeFocus ? Colours.layer(Colours.palette.m3surfaceContainer, 3) : Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
color: inputHover.containsMouse || inputField.activeFocus ? Colours.layer(Colours.palette.m3surfaceContainer, 3) : Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: inputField.activeFocus ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3outline, 0.3)
|
border.color: inputField.activeFocus ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3outline, 0.3)
|
||||||
opacity: root.enabled ? 1 : 0.5
|
opacity: root.enabled ? 1 : 0.5
|
||||||
|
|
@ -54,7 +54,7 @@ Item {
|
||||||
id: inputField
|
id: inputField
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width - Tokens.padding.normal
|
width: parent.width - Tokens.padding.medium
|
||||||
horizontalAlignment: root.horizontalAlignment
|
horizontalAlignment: root.horizontalAlignment
|
||||||
validator: root.validator
|
validator: root.validator
|
||||||
readOnly: root.readOnly
|
readOnly: root.readOnly
|
||||||
|
|
|
||||||
247
components/controls/StyledProgressBar.qml
Normal file
247
components/controls/StyledProgressBar.qml
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Templates
|
||||||
|
import Caelestia
|
||||||
|
import Caelestia.Components
|
||||||
|
import Caelestia.Config
|
||||||
|
import Caelestia.Internal
|
||||||
|
import qs.components
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
ProgressBar {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
enum IndeterminateAnimState {
|
||||||
|
Running,
|
||||||
|
Completing,
|
||||||
|
Stopped
|
||||||
|
}
|
||||||
|
|
||||||
|
property color fgColour: Colours.palette.m3primary
|
||||||
|
property color bgColour: Colours.palette.m3secondaryContainer
|
||||||
|
|
||||||
|
property bool wavy
|
||||||
|
property bool wavePaused
|
||||||
|
property int waveFrequency: 6
|
||||||
|
property real waveAmplitude: 0.5
|
||||||
|
property int waveDuration: 1000
|
||||||
|
|
||||||
|
property int indeterminateAnimState: StyledProgressBar.Stopped
|
||||||
|
|
||||||
|
function toBounds(startFrac: real, endFrac: real, gapSize: real): point {
|
||||||
|
startFrac = CUtils.clamp(startFrac, 0, 1);
|
||||||
|
endFrac = CUtils.clamp(endFrac, 0, 1);
|
||||||
|
|
||||||
|
// Ramp down gap size
|
||||||
|
const GAP_RAMP_DOWN_THRESHOLD = 0.01;
|
||||||
|
gapSize += height / 2;
|
||||||
|
const startGapSize = (gapSize * CUtils.clamp(startFrac, 0, GAP_RAMP_DOWN_THRESHOLD) / GAP_RAMP_DOWN_THRESHOLD);
|
||||||
|
const endGapSize = (gapSize * (1 - CUtils.clamp(endFrac, 1 - GAP_RAMP_DOWN_THRESHOLD, 1)) / GAP_RAMP_DOWN_THRESHOLD);
|
||||||
|
const start = width * startFrac + startGapSize;
|
||||||
|
const end = width * endFrac - endGapSize;
|
||||||
|
|
||||||
|
return start >= end ? Qt.point(0, 0) : Qt.point(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIAnimState(): void {
|
||||||
|
if (indeterminate) {
|
||||||
|
manager.completeEndProgress = 0;
|
||||||
|
indeterminateAnimState = StyledProgressBar.Running;
|
||||||
|
} else if (indeterminateAnimState === StyledProgressBar.Running) {
|
||||||
|
indeterminateAnimState = StyledProgressBar.Completing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onIndeterminateChanged: updateIAnimState()
|
||||||
|
Component.onCompleted: updateIAnimState()
|
||||||
|
|
||||||
|
implicitWidth: 200
|
||||||
|
implicitHeight: 4
|
||||||
|
|
||||||
|
contentItem: Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: true
|
||||||
|
sourceComponent: root.indeterminate || root.indeterminateAnimState !== StyledProgressBar.Stopped ? indeterminateComp : determinateComp
|
||||||
|
}
|
||||||
|
|
||||||
|
LinearIndicatorManager {
|
||||||
|
id: manager
|
||||||
|
|
||||||
|
gap: root.Tokens.spacing.extraSmall
|
||||||
|
|
||||||
|
Anim on progress {
|
||||||
|
running: root.indeterminateAnimState !== StyledProgressBar.Stopped
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
duration: manager.duration
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
loops: Animation.Infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim on completeEndProgress {
|
||||||
|
running: root.indeterminateAnimState === StyledProgressBar.Completing
|
||||||
|
to: 1
|
||||||
|
duration: manager.completeEndDuration
|
||||||
|
onFinished: {
|
||||||
|
if (root.indeterminateAnimState === StyledProgressBar.Completing)
|
||||||
|
root.indeterminateAnimState = StyledProgressBar.Stopped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: determinateComp
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Line {
|
||||||
|
id: remaining
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
implicitWidth: parent.width - wave.implicitWidth - Tokens.spacing.extraSmall
|
||||||
|
}
|
||||||
|
|
||||||
|
Line {
|
||||||
|
property real implicitSize
|
||||||
|
|
||||||
|
Component.onCompleted: implicitSize = Qt.binding(() => parent.width - wave.implicitWidth < parent.height ? parent.height : 4)
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.rightMargin: (parent.height - implicitHeight) / 2
|
||||||
|
|
||||||
|
implicitWidth: implicitSize
|
||||||
|
implicitHeight: implicitSize
|
||||||
|
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
color: root.fgColour
|
||||||
|
|
||||||
|
Behavior on implicitSize {
|
||||||
|
Anim {
|
||||||
|
type: Anim.FastSpatial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Wave {
|
||||||
|
id: wave
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
Component.onCompleted: implicitWidth = Qt.binding(() => parent.width * root.visualPosition)
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: indeterminateComp
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
Line {
|
||||||
|
bounds: {
|
||||||
|
const i = manager.activeIndicators[0]; // qmllint disable unresolved-type
|
||||||
|
return i ? root.toBounds(0, i.startFraction, i.gapSize / 2) : Qt.point(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Line {
|
||||||
|
bounds: {
|
||||||
|
const i = manager.activeIndicators[manager.activeIndicators.length - 1]; // qmllint disable unresolved-type
|
||||||
|
return i ? root.toBounds(i.endFraction, 1, i.gapSize / 2) : Qt.point(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Instantiator {
|
||||||
|
model: Math.max(manager.activeIndicators.length, 1) - 1 // qmllint disable unresolved-type
|
||||||
|
|
||||||
|
delegate: Line {
|
||||||
|
required property int index
|
||||||
|
readonly property LinearIndicatorSegment cur: manager.activeIndicators[index] // qmllint disable unresolved-type
|
||||||
|
readonly property LinearIndicatorSegment next: manager.activeIndicators[index + 1 % manager.activeIndicators.length] // qmllint disable unresolved-type
|
||||||
|
|
||||||
|
bounds: root.toBounds(cur.endFraction, next.startFraction, cur.gapSize / 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
onObjectAdded: (_, obj) => content.data.push(obj)
|
||||||
|
onObjectRemoved: (_, obj) => {
|
||||||
|
const idx = content.data.indexOf(obj);
|
||||||
|
if (idx !== -1)
|
||||||
|
content.data.splice(idx, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Instantiator {
|
||||||
|
model: manager.activeIndicators // qmllint disable unresolved-type
|
||||||
|
|
||||||
|
delegate: Wave {
|
||||||
|
required property LinearIndicatorSegment modelData
|
||||||
|
readonly property point bounds: root.toBounds(modelData.startFraction, modelData.endFraction, modelData.gapSize / 2)
|
||||||
|
|
||||||
|
x: bounds.x
|
||||||
|
implicitWidth: bounds.y - bounds.x
|
||||||
|
|
||||||
|
color: root.fgColour
|
||||||
|
}
|
||||||
|
|
||||||
|
onObjectAdded: (_, obj) => content.data.push(obj)
|
||||||
|
onObjectRemoved: (_, obj) => {
|
||||||
|
const idx = content.data.indexOf(obj);
|
||||||
|
if (idx !== -1)
|
||||||
|
content.data.splice(idx, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Line: StyledRect {
|
||||||
|
property point bounds
|
||||||
|
|
||||||
|
x: bounds.x
|
||||||
|
implicitWidth: bounds.y - bounds.x
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
implicitHeight: parent.height
|
||||||
|
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
color: root.bgColour
|
||||||
|
}
|
||||||
|
|
||||||
|
component Wave: WavyLine {
|
||||||
|
id: wave
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth
|
||||||
|
|
||||||
|
lineWidth: parent.height
|
||||||
|
amplitudeMultiplier: root.wavy ? root.waveAmplitude : 0
|
||||||
|
frequency: root.waveFrequency
|
||||||
|
startX: x
|
||||||
|
fullLength: parent.width
|
||||||
|
color: root.fgColour
|
||||||
|
|
||||||
|
Anim on waveProgress {
|
||||||
|
running: true
|
||||||
|
paused: wave.amplitudeMultiplier === 0 || root.wavePaused
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
duration: root.waveDuration
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
loops: Animation.Infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on amplitudeMultiplier {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ import qs.services
|
||||||
RadioButton {
|
RadioButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
font.pointSize: Tokens.font.size.smaller
|
font: Tokens.font.body.small
|
||||||
|
|
||||||
implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin
|
implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin
|
||||||
implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight)
|
implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight)
|
||||||
|
|
@ -24,7 +24,7 @@ RadioButton {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
anchors.margins: -Tokens.padding.smaller
|
anchors.margins: -Tokens.padding.small
|
||||||
color: root.checked ? Colours.palette.m3onSurface : Colours.palette.m3primary
|
color: root.checked ? Colours.palette.m3onSurface : Colours.palette.m3primary
|
||||||
z: -1
|
z: -1
|
||||||
onClicked: root.click()
|
onClicked: root.click()
|
||||||
|
|
@ -46,9 +46,9 @@ RadioButton {
|
||||||
|
|
||||||
contentItem: StyledText {
|
contentItem: StyledText {
|
||||||
text: root.text
|
text: root.text
|
||||||
font.pointSize: root.font.pointSize
|
font: root.font
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: outerCircle.right
|
anchors.left: outerCircle.right
|
||||||
anchors.leftMargin: Tokens.spacing.smaller
|
anchors.leftMargin: Tokens.spacing.medium
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ ScrollBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
implicitWidth: Tokens.padding.small
|
implicitWidth: Tokens.padding.extraSmall
|
||||||
|
|
||||||
contentItem: StyledRect {
|
contentItem: StyledRect {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -74,7 +74,9 @@ ScrollBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Templates
|
import QtQuick.Templates
|
||||||
|
import Caelestia
|
||||||
|
import Caelestia.Components
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
@ -7,51 +11,178 @@ import qs.services
|
||||||
Slider {
|
Slider {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
background: Item {
|
property bool wavy
|
||||||
|
property bool animateWave
|
||||||
|
property real waveFrequency: 6
|
||||||
|
property int waveDuration: 1000
|
||||||
|
property int radius: Tokens.rounding.medium
|
||||||
|
|
||||||
|
property color fgColour: enabled ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3onSurface, 0.38)
|
||||||
|
property color bgColour: enabled ? Colours.palette.m3secondaryContainer : Qt.alpha(Colours.palette.m3onSurface, 0.1)
|
||||||
|
|
||||||
|
property real pos: visualPosition
|
||||||
|
property real filledWidth
|
||||||
|
|
||||||
|
signal interaction(v: real)
|
||||||
|
|
||||||
|
Component.onCompleted: filledWidth = Qt.binding(() => (width - handle.implicitWidth - handle.anchors.leftMargin) * pos)
|
||||||
|
|
||||||
|
implicitWidth: 200
|
||||||
|
implicitHeight: 12
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
anchors.top: parent.top
|
id: remaining
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.topMargin: root.implicitHeight / 3
|
|
||||||
anchors.bottomMargin: root.implicitHeight / 3
|
|
||||||
|
|
||||||
implicitWidth: root.handle.x - root.implicitHeight / 6
|
anchors.left: handle.right
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
color: Colours.palette.m3primary
|
implicitHeight: parent.height * (parent.height <= 12 ? opacity : Math.min(opacity * 2, 1))
|
||||||
radius: Tokens.rounding.full
|
opacity: Math.min(width, 12) / 12
|
||||||
topRightRadius: root.implicitHeight / 15
|
|
||||||
bottomRightRadius: root.implicitHeight / 15
|
radius: root.radius
|
||||||
|
topLeftRadius: Tokens.rounding.extraSmall / 2
|
||||||
|
bottomLeftRadius: Tokens.rounding.extraSmall / 2
|
||||||
|
color: root.bgColour
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: root.implicitHeight / 3
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.bottomMargin: root.implicitHeight / 3
|
anchors.rightMargin: 4 * remaining.opacity
|
||||||
|
|
||||||
implicitWidth: parent.width - root.handle.x - root.handle.implicitWidth - root.implicitHeight / 6
|
implicitWidth: implicitHeight
|
||||||
|
implicitHeight: 4 * remaining.opacity
|
||||||
|
opacity: remaining.opacity
|
||||||
|
|
||||||
color: Colours.palette.m3surfaceContainerHighest
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
topLeftRadius: root.implicitHeight / 15
|
color: root.fgColour
|
||||||
bottomLeftRadius: root.implicitHeight / 15
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
id: handle
|
||||||
|
|
||||||
|
anchors.left: filled.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
|
implicitWidth: 4
|
||||||
|
implicitHeight: {
|
||||||
|
const t = CUtils.clamp((parent.height - 12) / 16, 0, 1);
|
||||||
|
const lerp = (a, b) => a + (b - a) * t;
|
||||||
|
return parent.height * (mouse.pressed ? lerp(3.5, 1.5) : lerp(3, 1.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
color: root.fgColour
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
type: Anim.FastSpatial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: filled
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
sourceComponent: root.wavy ? waveComp : lineComp
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: lineComp
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
implicitWidth: root.filledWidth
|
||||||
|
implicitHeight: root.height
|
||||||
|
|
||||||
|
radius: root.radius
|
||||||
|
topRightRadius: Tokens.rounding.extraSmall / 2
|
||||||
|
bottomRightRadius: Tokens.rounding.extraSmall / 2
|
||||||
|
color: root.fgColour
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: waveComp
|
||||||
|
|
||||||
|
WavyLine {
|
||||||
|
lineWidth: root.height * 0.7
|
||||||
|
frequency: root.waveFrequency
|
||||||
|
startX: x
|
||||||
|
fullLength: root.width - handle.implicitWidth - handle.anchors.leftMargin
|
||||||
|
color: root.fgColour
|
||||||
|
|
||||||
|
implicitWidth: root.filledWidth
|
||||||
|
implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth
|
||||||
|
|
||||||
|
Anim on waveProgress {
|
||||||
|
running: true
|
||||||
|
paused: !root.animateWave
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
duration: root.waveDuration
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
loops: Animation.Infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle: StyledRect {
|
Binding {
|
||||||
x: root.visualPosition * root.availableWidth - implicitWidth / 2
|
id: posBinding
|
||||||
|
|
||||||
implicitWidth: root.implicitHeight / 4.5
|
target: root
|
||||||
implicitHeight: root.implicitHeight
|
property: "pos"
|
||||||
|
value: CUtils.clamp(mouse.pressStartPos + mouse.dragMovement, 0, 1)
|
||||||
|
when: mouse.pressed
|
||||||
|
}
|
||||||
|
|
||||||
color: Colours.palette.m3primary
|
MouseArea {
|
||||||
radius: Tokens.rounding.full
|
id: mouse
|
||||||
|
|
||||||
MouseArea {
|
property real pressStartX
|
||||||
anchors.fill: parent
|
property real pressStartPos
|
||||||
acceptedButtons: Qt.NoButton
|
property real dragMovement
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
preventStealing: true
|
||||||
|
implicitHeight: handle.implicitHeight
|
||||||
|
|
||||||
|
onPressed: e => {
|
||||||
|
widthBehavior.enabled = false;
|
||||||
|
pressStartX = e.x;
|
||||||
|
pressStartPos = root.visualPosition;
|
||||||
}
|
}
|
||||||
|
onPositionChanged: e => {
|
||||||
|
dragMovement = (e.x - pressStartX) / width;
|
||||||
|
root.interaction(posBinding.value);
|
||||||
|
}
|
||||||
|
onReleased: e => {
|
||||||
|
root.interaction(posBinding.value);
|
||||||
|
widthBehavior.enabled = true;
|
||||||
|
dragMovement = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on filledWidth {
|
||||||
|
id: widthBehavior
|
||||||
|
|
||||||
|
Anim {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,17 @@ Switch {
|
||||||
color: root.checked ? Colours.palette.m3primary : Colours.layer(Colours.palette.m3surfaceContainerHighest, root.cLayer)
|
color: root.checked ? Colours.palette.m3primary : Colours.layer(Colours.palette.m3surfaceContainerHighest, root.cLayer)
|
||||||
|
|
||||||
implicitWidth: implicitHeight * 1.7
|
implicitWidth: implicitHeight * 1.7
|
||||||
implicitHeight: Tokens.font.size.normal + Tokens.padding.smaller * 2
|
implicitHeight: Tokens.font.body.medium.pointSize + Tokens.padding.small * 2
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.3 : implicitHeight
|
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: root.checked ? Colours.palette.m3onPrimary : Colours.layer(Colours.palette.m3outline, root.cLayer + 1)
|
color: root.checked ? Colours.palette.m3onPrimary : Colours.layer(Colours.palette.m3outline, root.cLayer + 1)
|
||||||
|
|
||||||
x: root.checked ? parent.implicitWidth - nonAnimWidth - Tokens.padding.small / 2 : Tokens.padding.small / 2
|
x: root.checked ? parent.implicitWidth - nonAnimWidth - Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall / 2
|
||||||
implicitWidth: nonAnimWidth
|
implicitWidth: nonAnimWidth
|
||||||
implicitHeight: parent.implicitHeight - Tokens.padding.small
|
implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
|
|
@ -39,7 +39,9 @@ Switch {
|
||||||
opacity: root.pressed ? 0.1 : root.hovered ? 0.08 : 0
|
opacity: root.pressed ? 0.1 : root.hovered ? 0.08 : 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,12 +85,12 @@ Switch {
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: height
|
width: height
|
||||||
height: parent.implicitHeight - Tokens.padding.small * 2
|
height: parent.implicitHeight - Tokens.padding.medium
|
||||||
preferredRendererType: Shape.CurveRenderer
|
preferredRendererType: Shape.CurveRenderer
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
ShapePath {
|
ShapePath {
|
||||||
strokeWidth: root.Tokens.font.size.larger * 0.15
|
strokeWidth: root.Tokens.font.body.large.pointSize * 0.15
|
||||||
strokeColor: root.checked ? Colours.palette.m3primary : Colours.palette.m3surfaceContainerHighest
|
strokeColor: root.checked ? Colours.palette.m3primary : Colours.palette.m3surfaceContainerHighest
|
||||||
fillColor: "transparent"
|
fillColor: "transparent"
|
||||||
capStyle: root.Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
capStyle: root.Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
||||||
|
|
@ -129,11 +131,15 @@ Switch {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on x {
|
Behavior on x {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.FastSpatial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
Behavior on implicitWidth {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.FastSpatial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +151,7 @@ Switch {
|
||||||
}
|
}
|
||||||
|
|
||||||
component PropAnim: PropertyAnimation {
|
component PropAnim: PropertyAnimation {
|
||||||
duration: Tokens.anim.durations.normal
|
duration: Tokens.anim.durations.expressiveFastSpatial
|
||||||
easing: Tokens.anim.standard
|
easing: Tokens.anim.expressiveFastSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ TextField {
|
||||||
|
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
placeholderTextColor: Colours.palette.m3outline
|
placeholderTextColor: Colours.palette.m3outline
|
||||||
font.family: Tokens.font.family.sans
|
font: Tokens.font.body.small
|
||||||
font.pointSize: Tokens.font.size.smaller
|
|
||||||
renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering
|
renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering
|
||||||
cursorVisible: !readOnly
|
cursorVisible: !readOnly
|
||||||
|
|
||||||
|
|
@ -25,7 +24,7 @@ TextField {
|
||||||
|
|
||||||
implicitWidth: 2
|
implicitWidth: 2
|
||||||
color: Colours.palette.m3primary
|
color: Colours.palette.m3primary
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onCursorPositionChanged(): void {
|
function onCursorPositionChanged(): void {
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ StyledRect {
|
||||||
signal toggled(checked: bool)
|
signal toggled(checked: bool)
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: row.implicitHeight + Tokens.padding.large * 2
|
implicitHeight: row.implicitHeight + Tokens.padding.extraLargeIncreased
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
|
|
@ -28,7 +28,7 @@ StyledRect {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.margins: Tokens.padding.large
|
anchors.margins: Tokens.padding.large
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -3,75 +3,41 @@ import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledRect {
|
ButtonBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Filled,
|
|
||||||
Tonal,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property bool checked
|
readonly property alias label: label
|
||||||
property bool toggle
|
|
||||||
property real horizontalPadding: Tokens.padding.normal
|
|
||||||
property real verticalPadding: Tokens.padding.smaller
|
|
||||||
property alias font: label.font
|
|
||||||
property int type: TextButton.Filled
|
|
||||||
|
|
||||||
property alias stateLayer: stateLayer
|
horizontalPadding: Tokens.padding.medium
|
||||||
property alias label: label
|
verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
property bool internalChecked
|
activeColour: type === TextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
||||||
property color activeColour: type === TextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
inactiveColour: {
|
||||||
property color inactiveColour: {
|
if (!isToggle && type === TextButton.Filled)
|
||||||
if (!toggle && type === TextButton.Filled)
|
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
return type === TextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
||||||
}
|
}
|
||||||
property color activeOnColour: {
|
activeOnColour: {
|
||||||
if (type === TextButton.Text)
|
if (type === TextButton.Text)
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary;
|
return type === TextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary;
|
||||||
}
|
}
|
||||||
property color inactiveOnColour: {
|
inactiveOnColour: {
|
||||||
if (!toggle && type === TextButton.Filled)
|
if (!isToggle && type === TextButton.Filled)
|
||||||
return Colours.palette.m3onPrimary;
|
return Colours.palette.m3onPrimary;
|
||||||
if (type === TextButton.Text)
|
if (type === TextButton.Text)
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer;
|
return type === TextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
signal clicked
|
|
||||||
|
|
||||||
onCheckedChanged: internalChecked = checked
|
|
||||||
|
|
||||||
radius: internalChecked ? Tokens.rounding.small : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
|
||||||
color: type === TextButton.Text ? "transparent" : internalChecked ? activeColour : inactiveColour
|
|
||||||
|
|
||||||
implicitWidth: label.implicitWidth + horizontalPadding * 2
|
implicitWidth: label.implicitWidth + horizontalPadding * 2
|
||||||
implicitHeight: label.implicitHeight + verticalPadding * 2
|
implicitHeight: label.implicitHeight + verticalPadding * 2
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
|
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
|
||||||
onClicked: {
|
|
||||||
if (root.toggle)
|
|
||||||
root.internalChecked = !root.internalChecked;
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ StyledRect {
|
||||||
property string icon
|
property string icon
|
||||||
property string label
|
property string label
|
||||||
property string accent: "Secondary"
|
property string accent: "Secondary"
|
||||||
property real iconSize: Tokens.font.size.large
|
property real iconSize: Tokens.font.icon.large.pointSize
|
||||||
property real horizontalPadding: Tokens.padding.large
|
property real horizontalPadding: Tokens.padding.large
|
||||||
property real verticalPadding: Tokens.padding.normal
|
property real verticalPadding: Tokens.padding.medium
|
||||||
property string tooltip: ""
|
property string tooltip: ""
|
||||||
property bool hovered: false
|
property bool hovered: false
|
||||||
|
|
||||||
|
|
@ -24,10 +24,10 @@ StyledRect {
|
||||||
|
|
||||||
Component.onCompleted: hovered = toggleStateLayer.containsMouse
|
Component.onCompleted: hovered = toggleStateLayer.containsMouse
|
||||||
|
|
||||||
Layout.preferredWidth: implicitWidth + (toggleStateLayer.pressed ? Tokens.padding.normal * 2 : toggled ? Tokens.padding.small * 2 : 0)
|
Layout.preferredWidth: implicitWidth + (toggleStateLayer.pressed ? Tokens.padding.medium * 2 : toggled ? Tokens.padding.small : 0)
|
||||||
implicitWidth: toggleBtnInner.implicitWidth + horizontalPadding * 2
|
implicitWidth: toggleBtnInner.implicitWidth + horizontalPadding * 2
|
||||||
implicitHeight: toggleBtnIcon.implicitHeight + verticalPadding * 2
|
implicitHeight: toggleBtnIcon.implicitHeight + verticalPadding * 2
|
||||||
radius: toggled || toggleStateLayer.pressed ? Tokens.rounding.small : Math.min(width, height) / 2 * Math.min(1, Tokens.rounding.scale)
|
radius: toggled || toggleStateLayer.pressed ? Tokens.rounding.medium : Math.min(width, height) / 2 * Math.min(1, Tokens.rounding.scale)
|
||||||
color: toggled ? Colours.palette[`m3${accent.toLowerCase()}`] : Colours.palette[`m3${accent.toLowerCase()}Container`]
|
color: toggled ? Colours.palette[`m3${accent.toLowerCase()}`] : Colours.palette[`m3${accent.toLowerCase()}Container`]
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
@ -52,7 +52,7 @@ StyledRect {
|
||||||
id: toggleBtnInner
|
id: toggleBtnInner
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: toggleBtnIcon
|
id: toggleBtnIcon
|
||||||
|
|
@ -61,10 +61,12 @@ StyledRect {
|
||||||
fill: root.toggled ? 1 : 0
|
fill: root.toggled ? 1 : 0
|
||||||
text: root.icon
|
text: root.icon
|
||||||
color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`]
|
color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`]
|
||||||
font.pointSize: root.iconSize
|
fontStyle: Tokens.font.icon.size(root.iconSize).build()
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ RowLayout {
|
||||||
property alias toggle: toggle
|
property alias toggle: toggle
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ Popup {
|
||||||
let newY = targetPos.y - tooltipHeight - Tokens.spacing.small;
|
let newY = targetPos.y - tooltipHeight - Tokens.spacing.small;
|
||||||
|
|
||||||
// Keep within bounds
|
// Keep within bounds
|
||||||
const padding = Tokens.padding.normal;
|
const padding = Tokens.padding.medium;
|
||||||
if (newX < padding) {
|
if (newX < padding) {
|
||||||
newX = padding;
|
newX = padding;
|
||||||
} else if (newX + tooltipWidth > (parent.width - padding)) {
|
} else if (newX + tooltipWidth > (parent.width - padding)) {
|
||||||
|
|
@ -116,11 +116,11 @@ Popup {
|
||||||
contentItem: StyledRect {
|
contentItem: StyledRect {
|
||||||
id: tooltipRect
|
id: tooltipRect
|
||||||
|
|
||||||
implicitWidth: tooltipText.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: tooltipText.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: tooltipText.implicitHeight + Tokens.padding.smaller * 2
|
implicitHeight: tooltipText.implicitHeight + Tokens.padding.large
|
||||||
|
|
||||||
color: Colours.palette.m3surfaceContainerHighest
|
color: Colours.palette.m3surfaceContainerHighest
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
|
|
||||||
// Add elevation for depth
|
// Add elevation for depth
|
||||||
|
|
@ -138,7 +138,7 @@ Popup {
|
||||||
|
|
||||||
text: root.text
|
text: root.text
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ RectangularShadow {
|
||||||
offset.y: dp / 2
|
offset.y: dp / 2
|
||||||
|
|
||||||
Behavior on dp {
|
Behavior on dp {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.SlowEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ StyledRect {
|
||||||
id: maskInner
|
id: maskInner
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
components/effects/Mask.qml
Normal file
7
components/effects/Mask.qml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
maskEnabled: true
|
||||||
|
maskSpreadAtMin: 1
|
||||||
|
maskThresholdMin: 0.5
|
||||||
|
}
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
|
|
||||||
ShaderEffect {
|
|
||||||
required property Item source
|
|
||||||
required property Item maskSource
|
|
||||||
|
|
||||||
fragmentShader: Quickshell.shellPath("assets/shaders/opacitymask.frag.qsb")
|
|
||||||
}
|
|
||||||
|
|
@ -9,8 +9,8 @@ Item {
|
||||||
|
|
||||||
required property var currentItem
|
required property var currentItem
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth + Tokens.padding.larger + content.anchors.rightMargin
|
implicitWidth: content.implicitWidth + Tokens.padding.medium + content.anchors.rightMargin
|
||||||
implicitHeight: currentItem ? content.implicitHeight + Tokens.padding.normal + content.anchors.bottomMargin : 0
|
implicitHeight: currentItem ? content.implicitHeight + Tokens.padding.medium + content.anchors.bottomMargin : 0
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
preferredRendererType: Shape.CurveRenderer
|
preferredRendererType: Shape.CurveRenderer
|
||||||
|
|
@ -18,7 +18,7 @@ Item {
|
||||||
ShapePath {
|
ShapePath {
|
||||||
id: path
|
id: path
|
||||||
|
|
||||||
readonly property real rounding: Tokens.rounding.small
|
readonly property real rounding: root.Tokens.rounding.medium
|
||||||
readonly property bool flatten: root.implicitHeight < rounding * 2
|
readonly property bool flatten: root.implicitHeight < rounding * 2
|
||||||
readonly property real roundingY: flatten ? root.implicitHeight / 2 : rounding
|
readonly property real roundingY: flatten ? root.implicitHeight / 2 : rounding
|
||||||
|
|
||||||
|
|
@ -76,8 +76,8 @@ Item {
|
||||||
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.rightMargin: Tokens.padding.larger - Tokens.padding.small
|
anchors.rightMargin: Tokens.padding.medium - Tokens.padding.extraSmall
|
||||||
anchors.bottomMargin: Tokens.padding.normal - Tokens.padding.small
|
anchors.bottomMargin: Tokens.padding.medium - Tokens.padding.extraSmall
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onCurrentItemChanged(): void {
|
function onCurrentItemChanged(): void {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ StyledRect {
|
||||||
required property var dialog
|
required property var dialog
|
||||||
required property FolderContents folder
|
required property FolderContents folder
|
||||||
|
|
||||||
implicitHeight: inner.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: inner.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ StyledRect {
|
||||||
id: inner
|
id: inner
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
|
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
|
|
@ -28,14 +28,14 @@ StyledRect {
|
||||||
StyledRect {
|
StyledRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.rightMargin: Tokens.spacing.normal
|
Layout.rightMargin: Tokens.spacing.medium
|
||||||
|
|
||||||
color: Colours.tPalette.m3surfaceContainerHigh
|
color: Colours.tPalette.m3surfaceContainerHigh
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
|
|
||||||
text: `${root.dialog.filterLabel} (${root.dialog.filters.map(f => `*.${f}`).join(", ")})`
|
text: `${root.dialog.filterLabel} (${root.dialog.filters.map(f => `*.${f}`).join(", ")})`
|
||||||
}
|
}
|
||||||
|
|
@ -43,10 +43,10 @@ StyledRect {
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
color: Colours.tPalette.m3surfaceContainerHigh
|
color: Colours.tPalette.m3surfaceContainerHigh
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
implicitWidth: cancelText.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: cancelText.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: cancelText.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: cancelText.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
disabled: !root.dialog.selectionValid
|
disabled: !root.dialog.selectionValid
|
||||||
|
|
@ -57,7 +57,7 @@ StyledRect {
|
||||||
id: selectText
|
id: selectText
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
|
|
||||||
text: qsTr("Select")
|
text: qsTr("Select")
|
||||||
color: root.dialog.selectionValid ? Colours.palette.m3onSurface : Colours.palette.m3outline
|
color: root.dialog.selectionValid ? Colours.palette.m3onSurface : Colours.palette.m3outline
|
||||||
|
|
@ -66,10 +66,10 @@ StyledRect {
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
color: Colours.tPalette.m3surfaceContainerHigh
|
color: Colours.tPalette.m3surfaceContainerHigh
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
implicitWidth: cancelText.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: cancelText.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: cancelText.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: cancelText.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|
@ -81,7 +81,7 @@ StyledRect {
|
||||||
id: cancelText
|
id: cancelText
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
|
|
||||||
text: qsTr("Cancel")
|
text: qsTr("Cancel")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,10 @@ LazyLoader {
|
||||||
|
|
||||||
implicitWidth: 1000
|
implicitWidth: 1000
|
||||||
implicitHeight: 600
|
implicitHeight: 600
|
||||||
|
minimumSize.width: 400
|
||||||
|
minimumSize.height: 300
|
||||||
color: Colours.tPalette.m3surface
|
color: Colours.tPalette.m3surface
|
||||||
|
surfaceFormat.opaque: false
|
||||||
title: loader.title
|
title: loader.title
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Effects
|
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import Caelestia.Models
|
import Caelestia.Models
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
|
import qs.components.effects
|
||||||
import qs.components.filedialog
|
import qs.components.filedialog
|
||||||
import qs.components.images
|
import qs.components.images
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
@ -24,12 +24,9 @@ Item {
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: MultiEffect {
|
layer.effect: Mask {
|
||||||
maskSource: mask
|
maskSource: mask
|
||||||
maskEnabled: true
|
|
||||||
maskInverted: true
|
maskInverted: true
|
||||||
maskThresholdMin: 0.5
|
|
||||||
maskSpreadAtMin: 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,8 +39,8 @@ Item {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.extraSmall
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,20 +56,20 @@ Item {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: "scan_delete"
|
text: "scan_delete"
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 2
|
fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).weight(Font.Medium).build()
|
||||||
font.weight: 500
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: qsTr("This folder is empty")
|
text: qsTr("This folder is empty")
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.large
|
font: Tokens.font.body.builders.large.weight(Font.Medium).build()
|
||||||
font.weight: 500
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,10 +77,10 @@ Item {
|
||||||
id: view
|
id: view
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small + Tokens.padding.normal
|
anchors.margins: Tokens.padding.extraSmall + Tokens.padding.medium
|
||||||
|
|
||||||
cellWidth: Sizes.itemWidth + Tokens.spacing.small
|
cellWidth: Sizes.itemWidth + Tokens.spacing.small
|
||||||
cellHeight: Sizes.itemWidth + Tokens.spacing.small * 2 + Tokens.padding.normal * 2 + 1
|
cellHeight: Sizes.itemWidth + Tokens.spacing.large + Tokens.padding.medium * 2 + 1
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
focus: true
|
focus: true
|
||||||
|
|
@ -120,12 +117,12 @@ Item {
|
||||||
properties: "opacity,scale"
|
properties: "opacity,scale"
|
||||||
from: 0
|
from: 0
|
||||||
to: 1
|
to: 1
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remove: Transition {
|
remove: Transition {
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 0
|
to: 0
|
||||||
}
|
}
|
||||||
|
|
@ -137,13 +134,13 @@ Item {
|
||||||
|
|
||||||
displaced: Transition {
|
displaced: Transition {
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
properties: "opacity,scale"
|
properties: "opacity,scale"
|
||||||
to: 1
|
to: 1
|
||||||
easing: Tokens.anim.standardDecel
|
easing: Tokens.anim.standardDecel
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
properties: "x,y"
|
properties: "x,y"
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +148,7 @@ Item {
|
||||||
CurrentItem {
|
CurrentItem {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.extraSmall
|
||||||
|
|
||||||
currentItem: view.currentItem
|
currentItem: view.currentItem
|
||||||
}
|
}
|
||||||
|
|
@ -162,12 +159,12 @@ Item {
|
||||||
required property int index
|
required property int index
|
||||||
required property FileSystemEntry modelData
|
required property FileSystemEntry modelData
|
||||||
|
|
||||||
readonly property real nonAnimHeight: icon.implicitHeight + name.anchors.topMargin + name.implicitHeight + Tokens.padding.normal * 2
|
readonly property real nonAnimHeight: icon.implicitHeight + name.anchors.topMargin + name.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
implicitWidth: Sizes.itemWidth
|
implicitWidth: Sizes.itemWidth
|
||||||
implicitHeight: nonAnimHeight
|
implicitHeight: nonAnimHeight
|
||||||
|
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Qt.alpha(Colours.tPalette.m3surfaceContainerHighest, GridView.isCurrentItem ? Colours.tPalette.m3surfaceContainerHighest.a : 0)
|
color: Qt.alpha(Colours.tPalette.m3surfaceContainerHighest, GridView.isCurrentItem ? Colours.tPalette.m3surfaceContainerHighest.a : 0)
|
||||||
z: GridView.isCurrentItem || implicitHeight !== nonAnimHeight ? 1 : 0
|
z: GridView.isCurrentItem || implicitHeight !== nonAnimHeight ? 1 : 0
|
||||||
clip: true
|
clip: true
|
||||||
|
|
@ -187,9 +184,9 @@ Item {
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: Tokens.padding.normal
|
anchors.topMargin: Tokens.padding.medium
|
||||||
|
|
||||||
implicitSize: Sizes.itemWidth - Tokens.padding.normal * 2
|
implicitSize: Sizes.itemWidth - Tokens.padding.medium * 2
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
const file = item.modelData;
|
const file = item.modelData;
|
||||||
|
|
@ -211,7 +208,7 @@ Item {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: icon.bottom
|
anchors.top: icon.bottom
|
||||||
anchors.topMargin: Tokens.spacing.small
|
anchors.topMargin: Tokens.spacing.small
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
elide: item.GridView.isCurrentItem ? Text.ElideNone : Text.ElideRight
|
elide: item.GridView.isCurrentItem ? Text.ElideNone : Text.ElideRight
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ StyledRect {
|
||||||
|
|
||||||
required property var dialog
|
required property var dialog
|
||||||
|
|
||||||
implicitWidth: inner.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: inner.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: inner.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: inner.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
|
||||||
|
|
@ -20,15 +20,15 @@ StyledRect {
|
||||||
id: inner
|
id: inner
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: upIcon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: upIcon.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
disabled: root.dialog.cwd.length === 1
|
disabled: root.dialog.cwd.length === 1
|
||||||
onClicked: root.dialog.cwd.pop()
|
onClicked: root.dialog.cwd.pop()
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ StyledRect {
|
||||||
StyledRect {
|
StyledRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
color: Colours.tPalette.m3surfaceContainerHigh
|
color: Colours.tPalette.m3surfaceContainerHigh
|
||||||
|
|
||||||
implicitHeight: pathComponents.implicitHeight + pathComponents.anchors.margins * 2
|
implicitHeight: pathComponents.implicitHeight + pathComponents.anchors.margins * 2
|
||||||
|
|
@ -55,7 +55,7 @@ StyledRect {
|
||||||
id: pathComponents
|
id: pathComponents
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small / 2
|
anchors.margins: Tokens.padding.extraSmall / 2
|
||||||
anchors.leftMargin: 0
|
anchors.leftMargin: 0
|
||||||
|
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
@ -78,13 +78,13 @@ StyledRect {
|
||||||
sourceComponent: StyledText {
|
sourceComponent: StyledText {
|
||||||
text: "/"
|
text: "/"
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.bold: true
|
font: Tokens.font.body.builders.small.weight(Font.Bold).build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
implicitWidth: homeIcon.implicitWidth + (homeIcon.active ? Tokens.padding.small : 0) + folderName.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: homeIcon.implicitWidth + (homeIcon.active ? Tokens.padding.extraSmall : 0) + folderName.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: folderName.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: folderName.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
@ -95,7 +95,7 @@ StyledRect {
|
||||||
root.dialog.cwd = root.dialog.cwd.slice(0, folder.index + 1);
|
root.dialog.cwd = root.dialog.cwd.slice(0, folder.index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +106,7 @@ StyledRect {
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: Tokens.padding.normal
|
anchors.leftMargin: Tokens.padding.medium
|
||||||
|
|
||||||
active: folder.index === 0 && folder.modelData === "Home"
|
active: folder.index === 0 && folder.modelData === "Home"
|
||||||
sourceComponent: MaterialIcon {
|
sourceComponent: MaterialIcon {
|
||||||
|
|
@ -121,11 +121,11 @@ StyledRect {
|
||||||
|
|
||||||
anchors.left: homeIcon.right
|
anchors.left: homeIcon.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: homeIcon.active ? Tokens.padding.small : 0
|
anchors.leftMargin: homeIcon.active ? Tokens.padding.extraSmall : 0
|
||||||
|
|
||||||
text: folder.modelData
|
text: folder.modelData
|
||||||
color: folder.index < root.dialog.cwd.length - 1 ? Colours.palette.m3onSurfaceVariant : Colours.palette.m3onSurface
|
color: folder.index < root.dialog.cwd.length - 1 ? Colours.palette.m3onSurfaceVariant : Colours.palette.m3onSurface
|
||||||
font.bold: true
|
font: Tokens.font.body.builders.small.weight(Font.Bold).build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ StyledRect {
|
||||||
required property var dialog
|
required property var dialog
|
||||||
|
|
||||||
implicitWidth: Sizes.sidebarWidth
|
implicitWidth: Sizes.sidebarWidth
|
||||||
implicitHeight: inner.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: inner.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
|
||||||
|
|
@ -23,17 +23,16 @@ StyledRect {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
spacing: Tokens.spacing.small / 2
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.topMargin: Tokens.padding.small / 2
|
Layout.topMargin: Tokens.padding.extraSmall / 2
|
||||||
Layout.bottomMargin: Tokens.spacing.normal
|
Layout.bottomMargin: Tokens.spacing.medium
|
||||||
text: qsTr("Files")
|
text: qsTr("Files")
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
font.pointSize: Tokens.font.size.larger
|
font: Tokens.font.body.builders.large.weight(Font.Bold).build()
|
||||||
font.bold: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -46,7 +45,7 @@ StyledRect {
|
||||||
readonly property bool selected: modelData === root.dialog.cwd[root.dialog.cwd.length - 1]
|
readonly property bool selected: modelData === root.dialog.cwd[root.dialog.cwd.length - 1]
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: placeInner.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: placeInner.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Qt.alpha(Colours.palette.m3secondaryContainer, selected ? 1 : 0)
|
color: Qt.alpha(Colours.palette.m3secondaryContainer, selected ? 1 : 0)
|
||||||
|
|
@ -65,11 +64,11 @@ StyledRect {
|
||||||
id: placeInner
|
id: placeInner
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
anchors.leftMargin: Tokens.padding.large
|
anchors.leftMargin: Tokens.padding.large
|
||||||
anchors.rightMargin: Tokens.padding.large
|
anchors.rightMargin: Tokens.padding.large
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
text: {
|
text: {
|
||||||
|
|
@ -91,11 +90,13 @@ StyledRect {
|
||||||
return "folder";
|
return "folder";
|
||||||
}
|
}
|
||||||
color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
|
color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
|
||||||
font.pointSize: Tokens.font.size.large
|
fontStyle: Tokens.font.icon.medium
|
||||||
fill: place.selected ? 1 : 0
|
fill: place.selected ? 1 : 0
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +104,7 @@ StyledRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: place.modelData
|
text: place.modelData
|
||||||
color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
|
color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
|
||||||
font.pointSize: Tokens.font.size.normal
|
font: Tokens.font.body.small
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,5 @@ import Quickshell
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
property int itemWidth: 103
|
property int itemWidth: 103
|
||||||
property int sidebarWidth: 200
|
property int sidebarWidth: 230
|
||||||
}
|
}
|
||||||
|
|
|
||||||
75
components/images/FadeImage.qml
Normal file
75
components/images/FadeImage.qml
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.components
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool hadPrevious
|
||||||
|
property bool fadingOut
|
||||||
|
property bool preventInit
|
||||||
|
property int fadeOutAnim: Anim.FastEffects
|
||||||
|
property int fadeInAnim: Anim.DefaultEffects
|
||||||
|
property int fadeInLargeAnim: Anim.StandardLarge
|
||||||
|
|
||||||
|
function maybeStartInAnim(): void {
|
||||||
|
if (!preventInit && !opacityInAnim.running && status === Image.Ready) {
|
||||||
|
opacityInAnim.type = hadPrevious ? fadeInAnim : fadeInLargeAnim;
|
||||||
|
opacityInAnim.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asynchronous: true
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
sourceSize: {
|
||||||
|
const dpr = (QsWindow.window as QsWindow)?.devicePixelRatio ?? 1;
|
||||||
|
return Qt.size(width * dpr, height * dpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
retainWhileLoading: true
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
onStatusChanged: maybeStartInAnim()
|
||||||
|
onPreventInitChanged: maybeStartInAnim()
|
||||||
|
|
||||||
|
Anim on opacity {
|
||||||
|
id: opacityInAnim
|
||||||
|
|
||||||
|
running: false
|
||||||
|
to: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on source {
|
||||||
|
SequentialAnimation {
|
||||||
|
ScriptAction {
|
||||||
|
script: opacityInAnim.stop()
|
||||||
|
}
|
||||||
|
PropertyAction {
|
||||||
|
target: root
|
||||||
|
property: "fadingOut"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
Anim {
|
||||||
|
target: root
|
||||||
|
property: "opacity"
|
||||||
|
to: 0
|
||||||
|
type: root.fadeOutAnim
|
||||||
|
}
|
||||||
|
PropertyAction {
|
||||||
|
target: root
|
||||||
|
property: "fadingOut"
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
PropertyAction {
|
||||||
|
target: root
|
||||||
|
property: "hadPrevious"
|
||||||
|
value: root.source
|
||||||
|
}
|
||||||
|
PropertyAction {}
|
||||||
|
ScriptAction {
|
||||||
|
script: root.maybeStartInAnim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
107
components/widgets/CoverArt.qml
Normal file
107
components/widgets/CoverArt.qml
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
import M3Shapes
|
||||||
|
import Caelestia.Config
|
||||||
|
import qs.components
|
||||||
|
import qs.components.controls
|
||||||
|
import qs.components.effects
|
||||||
|
import qs.components.images
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property alias shape: shape
|
||||||
|
|
||||||
|
property bool hadPrevious
|
||||||
|
property color fallbackColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2)
|
||||||
|
|
||||||
|
// Slight glow to separate from bg
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
shadowEnabled: true
|
||||||
|
blurMax: 1
|
||||||
|
shadowColor: Colours.palette.m3outline
|
||||||
|
shadowOpacity: 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on fallbackColour {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: shapeWrapper
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
opacity: root.fallbackColour.a
|
||||||
|
|
||||||
|
MaterialShape {
|
||||||
|
id: shape
|
||||||
|
|
||||||
|
implicitSize: root.width
|
||||||
|
shape: MaterialShape.Cookie12Sided
|
||||||
|
color: Qt.alpha(root.fallbackColour, 1)
|
||||||
|
|
||||||
|
Anim on rotation {
|
||||||
|
running: true
|
||||||
|
paused: !Players.active?.isPlaying
|
||||||
|
from: 360
|
||||||
|
to: 0
|
||||||
|
duration: 23500
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
loops: Animation.Infinite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
grade: 200
|
||||||
|
text: image.status === Image.Error ? "broken_image" : "art_track"
|
||||||
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
|
fontStyle: Tokens.font.icon.size((parent.width * 0.35) || 1).build()
|
||||||
|
opacity: image.status === Image.Null || image.status === Image.Error ? 1 : 0
|
||||||
|
animate: true
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
asynchronous: true
|
||||||
|
active: opacity > 0
|
||||||
|
opacity: image.status === Image.Loading ? 1 : 0
|
||||||
|
|
||||||
|
sourceComponent: LoadingIndicator {
|
||||||
|
implicitSize: root.width * 0.3
|
||||||
|
color: Colours.palette.m3primaryContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FadeImage {
|
||||||
|
id: image
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
source: Players.getArtUrl(Players.active)
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: Mask {
|
||||||
|
maskSource: shapeWrapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,13 +8,13 @@ StyledRect {
|
||||||
required property int extra
|
required property int extra
|
||||||
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.medium
|
||||||
|
|
||||||
color: Colours.palette.m3tertiary
|
color: Colours.palette.m3tertiary
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
implicitWidth: count.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: count.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: count.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: count.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
opacity: extra > 0 ? 1 : 0
|
opacity: extra > 0 ? 1 : 0
|
||||||
scale: extra > 0 ? 1 : 0.5
|
scale: extra > 0 ? 1 : 0.5
|
||||||
|
|
@ -38,6 +38,7 @@ StyledRect {
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
duration: Tokens.anim.durations.expressiveFastSpatial
|
duration: Tokens.anim.durations.expressiveFastSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
components/widgets/WavyTopRect.qml
Normal file
47
components/widgets/WavyTopRect.qml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Shapes
|
||||||
|
import qs.components
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
Shape {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property color color: Colours.palette.m3surfaceContainer
|
||||||
|
property int waves: 4
|
||||||
|
property real amplitude: 3
|
||||||
|
|
||||||
|
readonly property real waveHeight: amplitude * 2
|
||||||
|
|
||||||
|
preferredRendererType: Shape.CurveRenderer
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
strokeWidth: 0
|
||||||
|
strokeColor: "transparent"
|
||||||
|
fillColor: root.color
|
||||||
|
|
||||||
|
PathSvg {
|
||||||
|
path: {
|
||||||
|
const w = root.width;
|
||||||
|
const h = root.height;
|
||||||
|
const a = root.amplitude;
|
||||||
|
const n = Math.max(1, root.waves);
|
||||||
|
const wl = w / n;
|
||||||
|
const half = wl / 2;
|
||||||
|
|
||||||
|
let d = `M 0,${a} `;
|
||||||
|
for (let i = 0; i < n; ++i) {
|
||||||
|
const x = i * wl;
|
||||||
|
d += `Q ${x + half / 2},${-a} ${x + half},${a} `;
|
||||||
|
d += `Q ${x + half + half / 2},${3 * a} ${x + wl},${a} `;
|
||||||
|
}
|
||||||
|
d += `L ${w},${h} L 0,${h} Z`;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on fillColor {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
modules/GSFLoader.qml
Normal file
6
modules/GSFLoader.qml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
FontLoader {
|
||||||
|
source: Quickshell.shellPath("assets/google-sans-flex/GoogleSansFlex-VariableFont_GRAD,ROND,opsz,slnt,wdth,wght.ttf")
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ import Quickshell.Io
|
||||||
import Caelestia
|
import Caelestia
|
||||||
import qs.components.misc
|
import qs.components.misc
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.controlcenter
|
import qs.modules.nexus
|
||||||
|
|
||||||
Scope {
|
Scope {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -15,8 +15,8 @@ Scope {
|
||||||
// qmllint disable unresolved-type
|
// qmllint disable unresolved-type
|
||||||
CustomShortcut {
|
CustomShortcut {
|
||||||
// qmllint enable unresolved-type
|
// qmllint enable unresolved-type
|
||||||
name: "controlCenter"
|
name: "nexus"
|
||||||
description: "Open control center"
|
description: "Open nexus"
|
||||||
onPressed: WindowFactory.create()
|
onPressed: WindowFactory.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,7 +133,7 @@ Scope {
|
||||||
WindowFactory.create();
|
WindowFactory.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
target: "controlCenter"
|
target: "nexus"
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Effects
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Caelestia
|
import Caelestia
|
||||||
import qs.components
|
import qs.components
|
||||||
|
import qs.components.effects
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -168,17 +168,17 @@ MouseArea {
|
||||||
to: 0
|
to: 0
|
||||||
type: Anim.StandardLarge
|
type: Anim.StandardLarge
|
||||||
}
|
}
|
||||||
ExAnim {
|
Anim {
|
||||||
target: root
|
target: root
|
||||||
properties: "rsx,rsy"
|
properties: "rsx,rsy"
|
||||||
to: 0
|
to: 0
|
||||||
}
|
}
|
||||||
ExAnim {
|
Anim {
|
||||||
target: root
|
target: root
|
||||||
property: "sw"
|
property: "sw"
|
||||||
to: root.screen.width
|
to: root.screen.width
|
||||||
}
|
}
|
||||||
ExAnim {
|
Anim {
|
||||||
target: root
|
target: root
|
||||||
property: "sh"
|
property: "sh"
|
||||||
to: root.screen.height
|
to: root.screen.height
|
||||||
|
|
@ -230,12 +230,9 @@ MouseArea {
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: MultiEffect {
|
layer.effect: Mask {
|
||||||
maskSource: selectionWrapper
|
maskSource: selectionWrapper
|
||||||
maskEnabled: true
|
|
||||||
maskInverted: true
|
maskInverted: true
|
||||||
maskSpreadAtMin: 1
|
|
||||||
maskThresholdMin: 0.5
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -284,28 +281,24 @@ MouseArea {
|
||||||
Behavior on rsx {
|
Behavior on rsx {
|
||||||
enabled: !root.pressed
|
enabled: !root.pressed
|
||||||
|
|
||||||
ExAnim {}
|
Anim {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on rsy {
|
Behavior on rsy {
|
||||||
enabled: !root.pressed
|
enabled: !root.pressed
|
||||||
|
|
||||||
ExAnim {}
|
Anim {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on sw {
|
Behavior on sw {
|
||||||
enabled: !root.pressed
|
enabled: !root.pressed
|
||||||
|
|
||||||
ExAnim {}
|
Anim {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on sh {
|
Behavior on sh {
|
||||||
enabled: !root.pressed
|
enabled: !root.pressed
|
||||||
|
|
||||||
ExAnim {}
|
Anim {}
|
||||||
}
|
|
||||||
|
|
||||||
component ExAnim: Anim {
|
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@ Variants {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
active: Config.background.desktopClock.enabled
|
active: Config.background.desktopClock.enabled
|
||||||
|
|
||||||
anchors.margins: Tokens.padding.large * 2
|
anchors.margins: Tokens.padding.extraLargeIncreased
|
||||||
anchors.leftMargin: Tokens.padding.large * 2 + Tokens.sizes.bar.innerWidth + Math.max(Tokens.padding.smaller, Config.border.thickness)
|
anchors.leftMargin: Tokens.padding.extraLargeIncreased + Tokens.sizes.bar.innerWidth + Math.max(Tokens.padding.small, Config.border.thickness)
|
||||||
|
|
||||||
state: Config.background.desktopClock.position
|
state: Config.background.desktopClock.position
|
||||||
states: [
|
states: [
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ Item {
|
||||||
readonly property color safeTertiary: useLightSet ? Colours.palette.m3tertiaryContainer : Colours.palette.m3tertiary
|
readonly property color safeTertiary: useLightSet ? Colours.palette.m3tertiaryContainer : Colours.palette.m3tertiary
|
||||||
|
|
||||||
implicitWidth: layout.implicitWidth + (Tokens.padding.large * 4 * root.clockScale)
|
implicitWidth: layout.implicitWidth + (Tokens.padding.large * 4 * root.clockScale)
|
||||||
implicitHeight: layout.implicitHeight + (Tokens.padding.large * 2 * root.clockScale)
|
implicitHeight: layout.implicitHeight + (Tokens.padding.extraLargeIncreased * root.clockScale)
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: clockContainer
|
id: clockContainer
|
||||||
|
|
@ -63,7 +63,7 @@ Item {
|
||||||
|
|
||||||
visible: root.bgEnabled
|
visible: root.bgEnabled
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Tokens.rounding.large * root.clockScale
|
radius: Tokens.rounding.extraLarge * root.clockScale
|
||||||
opacity: Config.background.desktopClock.background.opacity
|
opacity: Config.background.desktopClock.background.opacity
|
||||||
color: Colours.palette.m3surface
|
color: Colours.palette.m3surface
|
||||||
|
|
||||||
|
|
@ -74,21 +74,20 @@ Item {
|
||||||
id: layout
|
id: layout
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Tokens.spacing.larger * root.clockScale
|
spacing: Tokens.spacing.large * root.clockScale
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Time.hourStr
|
text: Time.hourStr
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 3 * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.headline.medium.pointSize * 3 * root.clockScale).weight(Font.Bold).build()
|
||||||
font.weight: Font.Bold
|
|
||||||
color: root.safePrimary
|
color: root.safePrimary
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: ":"
|
text: ":"
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 3 * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.headline.medium.pointSize * 3 * root.clockScale).build()
|
||||||
color: root.safeTertiary
|
color: root.safeTertiary
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
Layout.topMargin: -Tokens.padding.large * 1.5 * root.clockScale
|
Layout.topMargin: -Tokens.padding.large * 1.5 * root.clockScale
|
||||||
|
|
@ -96,8 +95,7 @@ Item {
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Time.minuteStr
|
text: Time.minuteStr
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 3 * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.headline.medium.pointSize * 3 * root.clockScale).weight(Font.Bold).build()
|
||||||
font.weight: Font.Bold
|
|
||||||
color: root.safeSecondary
|
color: root.safeSecondary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +109,7 @@ Item {
|
||||||
|
|
||||||
sourceComponent: StyledText {
|
sourceComponent: StyledText {
|
||||||
text: Time.amPmStr
|
text: Time.amPmStr
|
||||||
font.pointSize: Tokens.font.size.large * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.title.medium.pointSize * root.clockScale).build()
|
||||||
color: root.safeSecondary
|
color: root.safeSecondary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,8 +118,8 @@ Item {
|
||||||
StyledRect {
|
StyledRect {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: 4 * root.clockScale
|
Layout.preferredWidth: 4 * root.clockScale
|
||||||
Layout.topMargin: Tokens.spacing.larger * root.clockScale
|
Layout.topMargin: Tokens.spacing.large * root.clockScale
|
||||||
Layout.bottomMargin: Tokens.spacing.larger * root.clockScale
|
Layout.bottomMargin: Tokens.spacing.large * root.clockScale
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: root.safePrimary
|
color: root.safePrimary
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
|
|
@ -132,24 +130,19 @@ Item {
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Time.format("MMMM").toUpperCase()
|
text: Time.format("MMMM").toUpperCase()
|
||||||
font.pointSize: Tokens.font.size.large * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.title.medium.pointSize * root.clockScale).letterSpacing(4).weight(Font.Bold).build()
|
||||||
font.letterSpacing: 4
|
|
||||||
font.weight: Font.Bold
|
|
||||||
color: root.safeSecondary
|
color: root.safeSecondary
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Time.format("dd")
|
text: Time.format("dd")
|
||||||
font.pointSize: Tokens.font.size.extraLarge * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.headline.medium.pointSize * root.clockScale).letterSpacing(2).weight(Font.Medium).build()
|
||||||
font.letterSpacing: 2
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: root.safePrimary
|
color: root.safePrimary
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Time.format("dddd")
|
text: Time.format("dddd")
|
||||||
font.pointSize: Tokens.font.size.larger * root.clockScale
|
font: Tokens.font.clock.size(Tokens.font.body.large.pointSize * root.clockScale).letterSpacing(2).build()
|
||||||
font.letterSpacing: 2
|
|
||||||
color: root.safeSecondary
|
color: root.safeSecondary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,9 +150,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on clockScale {
|
Behavior on clockScale {
|
||||||
Anim {
|
Anim {}
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
Behavior on implicitWidth {
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ Item {
|
||||||
values: Audio.cava.values
|
values: Audio.cava.values
|
||||||
primaryColor: Qt.alpha(Colours.palette.m3primary, 0.7)
|
primaryColor: Qt.alpha(Colours.palette.m3primary, 0.7)
|
||||||
secondaryColor: Qt.alpha(Colours.palette.m3inversePrimary, 0.7)
|
secondaryColor: Qt.alpha(Colours.palette.m3inversePrimary, 0.7)
|
||||||
rounding: Tokens.rounding.small * Config.background.visualiser.rounding
|
rounding: Tokens.rounding.medium * Config.background.visualiser.rounding
|
||||||
spacing: Tokens.spacing.small * Config.background.visualiser.spacing
|
spacing: Tokens.spacing.extraSmall * Config.background.visualiser.spacing
|
||||||
animationDuration: Tokens.anim.durations.normal
|
animationDuration: Tokens.anim.durations.normal
|
||||||
|
|
||||||
Behavior on anchors.leftMargin {
|
Behavior on anchors.leftMargin {
|
||||||
|
|
@ -87,6 +87,8 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,22 +12,24 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string source: Wallpapers.current
|
property string source: Wallpapers.current
|
||||||
property Image current: one
|
property CachingImage current
|
||||||
property bool completed
|
property bool completed
|
||||||
|
|
||||||
onSourceChanged: {
|
onSourceChanged: {
|
||||||
if (!source)
|
if (!source)
|
||||||
current = null;
|
current = null;
|
||||||
else if (current === one)
|
|
||||||
two.update();
|
|
||||||
else
|
else
|
||||||
one.update();
|
current = imgComp.createObject(this, {
|
||||||
|
path: source
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (source)
|
if (source)
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
one.update();
|
current = imgComp.createObject(this, {
|
||||||
|
path: source
|
||||||
|
});
|
||||||
completed = true;
|
completed = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -43,12 +45,12 @@ Item {
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
text: "sentiment_stressed"
|
text: "sentiment_stressed"
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 5
|
fontStyle: Tokens.font.icon.builders.extraLarge.scale(5).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|
@ -58,13 +60,12 @@ Item {
|
||||||
StyledText {
|
StyledText {
|
||||||
text: qsTr("Wallpaper missing?")
|
text: qsTr("Wallpaper missing?")
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 2
|
font: Tokens.font.body.builders.large.size(28 * 2).weight(Font.Bold).build()
|
||||||
font.bold: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
implicitWidth: selectWallText.implicitWidth + Tokens.padding.large * 2
|
implicitWidth: selectWallText.implicitWidth + Tokens.padding.extraLargeIncreased
|
||||||
implicitHeight: selectWallText.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: selectWallText.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Colours.palette.m3primary
|
color: Colours.palette.m3primary
|
||||||
|
|
@ -91,7 +92,7 @@ Item {
|
||||||
|
|
||||||
text: qsTr("Set it now!")
|
text: qsTr("Set it now!")
|
||||||
color: Colours.palette.m3onPrimary
|
color: Colours.palette.m3onPrimary
|
||||||
font.pointSize: Tokens.font.size.large
|
font: Tokens.font.body.large
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,48 +100,34 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Img {
|
Component {
|
||||||
id: one
|
id: imgComp
|
||||||
}
|
|
||||||
|
|
||||||
Img {
|
CachingImage {
|
||||||
id: two
|
id: img
|
||||||
}
|
|
||||||
|
|
||||||
component Img: CachingImage {
|
anchors.fill: parent
|
||||||
id: img
|
|
||||||
|
|
||||||
function update(): void {
|
opacity: 0
|
||||||
if (path === root.source)
|
|
||||||
root.current = this;
|
|
||||||
else
|
|
||||||
path = root.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.fill: parent
|
onStatusChanged: {
|
||||||
|
if (status === Image.Ready)
|
||||||
opacity: 0
|
anim.start();
|
||||||
scale: Wallpapers.showPreview ? 1 : 0.8
|
|
||||||
|
|
||||||
onStatusChanged: {
|
|
||||||
if (status === Image.Ready)
|
|
||||||
root.current = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
states: State {
|
|
||||||
name: "visible"
|
|
||||||
when: root.current === img
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
img.opacity: 1
|
|
||||||
img.scale: 1
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
transitions: Transition {
|
Anim on opacity {
|
||||||
Anim {
|
id: anim
|
||||||
target: img
|
|
||||||
properties: "opacity,scale"
|
type: Anim.SlowEffects
|
||||||
|
running: false
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: root.current !== img && root.current?.status === Image.Ready
|
||||||
|
interval: anim.duration
|
||||||
|
onTriggered: img.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Item {
|
||||||
readonly property bool disabled: Strings.testRegexList(Config.bar.excludedScreens, screen.name)
|
readonly property bool disabled: Strings.testRegexList(Config.bar.excludedScreens, screen.name)
|
||||||
|
|
||||||
readonly property int clampedWidth: Math.max(Config.border.minThickness, implicitWidth)
|
readonly property int clampedWidth: Math.max(Config.border.minThickness, implicitWidth)
|
||||||
readonly property int padding: Math.max(Tokens.padding.smaller, Config.border.thickness)
|
readonly property int padding: Math.max(Tokens.padding.small, Config.border.thickness)
|
||||||
readonly property int contentWidth: Tokens.sizes.bar.innerWidth + padding * 2
|
readonly property int contentWidth: Tokens.sizes.bar.innerWidth + padding * 2
|
||||||
readonly property int exclusiveZone: !disabled && (Config.bar.persistent || visibilities.bar) ? contentWidth : Config.border.thickness
|
readonly property int exclusiveZone: !disabled && (Config.bar.persistent || visibilities.bar) ? contentWidth : Config.border.thickness
|
||||||
readonly property bool shouldBeVisible: !fullscreen && !disabled && (Config.bar.persistent || visibilities.bar || isHovered)
|
readonly property bool shouldBeVisible: !fullscreen && !disabled && (Config.bar.persistent || visibilities.bar || isHovered)
|
||||||
|
|
@ -37,7 +37,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
visible: width > 0
|
visible: width > Config.border.thickness
|
||||||
implicitWidth: fullscreen ? 0 : Config.border.thickness
|
implicitWidth: fullscreen ? 0 : Config.border.thickness
|
||||||
|
|
||||||
states: State {
|
states: State {
|
||||||
|
|
@ -57,7 +57,6 @@ Item {
|
||||||
Anim {
|
Anim {
|
||||||
target: root
|
target: root
|
||||||
property: "implicitWidth"
|
property: "implicitWidth"
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Transition {
|
Transition {
|
||||||
|
|
@ -79,7 +78,7 @@ Item {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
active: root.shouldBeVisible || root.visible
|
active: root.shouldBeVisible
|
||||||
|
|
||||||
sourceComponent: Bar {
|
sourceComponent: Bar {
|
||||||
width: root.contentWidth
|
width: root.contentWidth
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,7 @@ Item {
|
||||||
id: metrics
|
id: metrics
|
||||||
|
|
||||||
text: root.windowTitle
|
text: root.windowTitle
|
||||||
font.pointSize: root.Tokens.font.size.smaller
|
font: root.Tokens.font.body.builders.small.letterSpacing(1.4).build()
|
||||||
font.family: root.Tokens.font.family.mono
|
|
||||||
elide: Qt.ElideRight
|
elide: Qt.ElideRight
|
||||||
elideWidth: root.maxHeight - icon.height
|
elideWidth: root.maxHeight - icon.height
|
||||||
|
|
||||||
|
|
@ -100,9 +99,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
Anim {
|
Anim {}
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component Title: StyledText {
|
component Title: StyledText {
|
||||||
|
|
@ -112,8 +109,7 @@ Item {
|
||||||
anchors.top: icon.bottom
|
anchors.top: icon.bottom
|
||||||
anchors.topMargin: Tokens.spacing.small
|
anchors.topMargin: Tokens.spacing.small
|
||||||
|
|
||||||
font.pointSize: metrics.font.pointSize
|
font: metrics.font
|
||||||
font.family: metrics.font.family
|
|
||||||
color: root.colour
|
color: root.colour
|
||||||
opacity: root.current === this ? 1 : 0
|
opacity: root.current === this ? 1 : 0
|
||||||
|
|
||||||
|
|
@ -132,7 +128,9 @@ Item {
|
||||||
height: implicitWidth
|
height: implicitWidth
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
@ -9,7 +10,8 @@ StyledRect {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property color colour: Colours.palette.m3tertiary
|
readonly property color colour: Colours.palette.m3tertiary
|
||||||
readonly property int padding: Config.bar.clock.background ? Tokens.padding.normal : Tokens.padding.small
|
readonly property int padding: Config.bar.clock.background ? Tokens.padding.medium : Tokens.padding.extraSmall
|
||||||
|
readonly property var font: Tokens.font.body.builders.small.scale(1.1)
|
||||||
|
|
||||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||||
implicitHeight: layout.implicitHeight + root.padding * 2
|
implicitHeight: layout.implicitHeight + root.padding * 2
|
||||||
|
|
@ -17,16 +19,15 @@ StyledRect {
|
||||||
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, Config.bar.clock.background ? Colours.tPalette.m3surfaceContainer.a : 0)
|
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, Config.bar.clock.background ? Colours.tPalette.m3surfaceContainer.a : 0)
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
Column {
|
ColumnLayout {
|
||||||
id: layout
|
id: layout
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
active: Config.bar.clock.showIcon
|
active: Config.bar.clock.showIcon
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
|
|
@ -37,35 +38,69 @@ StyledRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
visible: Config.bar.clock.showDate
|
visible: Config.bar.clock.showDate
|
||||||
|
|
||||||
horizontalAlignment: StyledText.AlignHCenter
|
horizontalAlignment: StyledText.AlignHCenter
|
||||||
text: Time.format("ddd\nd")
|
text: Time.format("ddd\nd")
|
||||||
font.pointSize: Tokens.font.size.smaller
|
font: Tokens.font.body.small
|
||||||
font.family: Tokens.font.family.sans
|
|
||||||
color: root.colour
|
color: root.colour
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.fillWidth: true
|
||||||
visible: Config.bar.clock.showDate
|
visible: Config.bar.clock.showDate
|
||||||
height: visible ? 1 : 0
|
implicitHeight: 1
|
||||||
|
color: Colours.palette.m3outlineVariant
|
||||||
width: parent.width * 0.8
|
|
||||||
color: root.colour
|
|
||||||
opacity: 0.2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: Time.hourStr
|
||||||
horizontalAlignment: StyledText.AlignHCenter
|
font: {
|
||||||
text: Time.format(GlobalConfig.services.useTwelveHourClock ? "hh\nmm\nA" : "hh\nmm")
|
const scale = text === "11" ? 1.15 : Math.min(1.05, Math.max(hourMetrics.width, minMetrics.width) / hourMetrics.width);
|
||||||
font.pointSize: Tokens.font.size.smaller
|
return root.font.width(scale * 100).letterSpacing(scale).build();
|
||||||
font.family: Tokens.font.family.mono
|
}
|
||||||
color: root.colour
|
color: root.colour
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: hourMetrics
|
||||||
|
|
||||||
|
font: root.font.build()
|
||||||
|
text: Time.hourStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.topMargin: -parent.spacing - 4
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: Time.minuteStr
|
||||||
|
font: {
|
||||||
|
const scale = text === "11" ? 1.15 : Math.min(1.05, Math.max(hourMetrics.width, minMetrics.width) / minMetrics.width);
|
||||||
|
return root.font.width(scale * 100).letterSpacing(scale).build();
|
||||||
|
}
|
||||||
|
color: root.colour
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: minMetrics
|
||||||
|
|
||||||
|
font: root.font.build()
|
||||||
|
text: Time.minuteStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
Layout.topMargin: -parent.spacing - 4
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
asynchronous: true
|
||||||
|
active: GlobalConfig.services.useTwelveHourClock
|
||||||
|
visible: active
|
||||||
|
|
||||||
|
sourceComponent: StyledText {
|
||||||
|
text: Time.amPmStr.toLowerCase()
|
||||||
|
font: Tokens.font.body.builders.small.scale(0.9).build()
|
||||||
|
color: root.colour
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import qs.utils
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
implicitWidth: Math.round(Tokens.font.size.large * 1.2)
|
implicitWidth: Math.round(Tokens.font.body.large.pointSize * 1.2)
|
||||||
implicitHeight: Math.round(Tokens.font.size.large * 1.2)
|
implicitHeight: Math.round(Tokens.font.body.large.pointSize * 1.2)
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -30,8 +30,8 @@ Item {
|
||||||
id: caelestiaLogo
|
id: caelestiaLogo
|
||||||
|
|
||||||
Logo {
|
Logo {
|
||||||
implicitWidth: Math.round(Tokens.font.size.large * 1.6)
|
implicitWidth: Math.round(Tokens.font.body.large.pointSize * 1.6)
|
||||||
implicitHeight: Math.round(Tokens.font.size.large * 1.6)
|
implicitHeight: Math.round(Tokens.font.body.large.pointSize * 1.6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ Item {
|
||||||
|
|
||||||
ColouredIcon {
|
ColouredIcon {
|
||||||
source: SysInfo.osLogo
|
source: SysInfo.osLogo
|
||||||
implicitSize: Math.round(Tokens.font.size.large * 1.2)
|
implicitSize: Math.round(Tokens.font.body.large.pointSize * 1.2)
|
||||||
colour: Colours.palette.m3tertiary
|
colour: Colours.palette.m3tertiary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Item {
|
||||||
|
|
||||||
required property DrawerVisibilities visibilities
|
required property DrawerVisibilities visibilities
|
||||||
|
|
||||||
implicitWidth: icon.implicitHeight + Tokens.padding.small * 2
|
implicitWidth: icon.implicitHeight + Tokens.padding.small
|
||||||
implicitHeight: icon.implicitHeight
|
implicitHeight: icon.implicitHeight
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
|
|
@ -16,7 +16,7 @@ Item {
|
||||||
anchors.fill: undefined
|
anchors.fill: undefined
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: icon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: icon.implicitHeight + Tokens.padding.small
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
onClicked: root.visibilities.session = !root.visibilities.session
|
onClicked: root.visibilities.session = !root.visibilities.session
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +29,6 @@ Item {
|
||||||
|
|
||||||
text: "power_settings_new"
|
text: "power_settings_new"
|
||||||
color: Colours.palette.m3error
|
color: Colours.palette.m3error
|
||||||
font.bold: true
|
fontStyle: Tokens.font.icon.builders.small.weight(Font.Bold).build()
|
||||||
font.pointSize: Tokens.font.size.normal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ StyledRect {
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||||
implicitHeight: iconColumn.implicitHeight + Tokens.padding.normal * 2 - (Config.bar.status.showLockStatus && !Hypr.capsLock && !Hypr.numLock ? iconColumn.spacing : 0)
|
implicitHeight: iconColumn.implicitHeight + Tokens.padding.medium * 2 - (Config.bar.status.showLockStatus && !Hypr.capsLock && !Hypr.numLock ? iconColumn.spacing : 0)
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: iconColumn
|
id: iconColumn
|
||||||
|
|
@ -29,9 +29,9 @@ StyledRect {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: Tokens.padding.normal
|
anchors.bottomMargin: Tokens.padding.medium
|
||||||
|
|
||||||
spacing: Tokens.spacing.smaller / 2
|
spacing: Tokens.spacing.medium / 2
|
||||||
|
|
||||||
// Lock keys status
|
// Lock keys status
|
||||||
WrappedLoader {
|
WrappedLoader {
|
||||||
|
|
@ -57,7 +57,9 @@ StyledRect {
|
||||||
color: root.colour
|
color: root.colour
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -88,7 +90,9 @@ StyledRect {
|
||||||
color: root.colour
|
color: root.colour
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -136,7 +140,7 @@ StyledRect {
|
||||||
animate: true
|
animate: true
|
||||||
text: Hypr.kbLayout
|
text: Hypr.kbLayout
|
||||||
color: root.colour
|
color: root.colour
|
||||||
font.family: Tokens.font.family.mono
|
font: Tokens.font.mono.medium
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +176,7 @@ StyledRect {
|
||||||
active: Config.bar.status.showBluetooth
|
active: Config.bar.status.showBluetooth
|
||||||
|
|
||||||
sourceComponent: ColumnLayout {
|
sourceComponent: ColumnLayout {
|
||||||
spacing: Tokens.spacing.smaller / 2
|
spacing: Tokens.spacing.medium / 2
|
||||||
|
|
||||||
// Bluetooth icon
|
// Bluetooth icon
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
|
|
@ -245,15 +249,7 @@ StyledRect {
|
||||||
return "rocket_launch";
|
return "rocket_launch";
|
||||||
return "balance";
|
return "balance";
|
||||||
}
|
}
|
||||||
|
return Icons.getBatteryIcon(UPower.displayDevice.percentage, [UPowerDeviceState.Charging, UPowerDeviceState.FullyCharged, UPowerDeviceState.PendingCharge].includes(UPower.displayDevice.state));
|
||||||
const perc = UPower.displayDevice.percentage;
|
|
||||||
const charging = [UPowerDeviceState.Charging, UPowerDeviceState.FullyCharged, UPowerDeviceState.PendingCharge].includes(UPower.displayDevice.state);
|
|
||||||
if (perc === 1)
|
|
||||||
return charging ? "battery_charging_full" : "battery_full";
|
|
||||||
let level = Math.floor(perc * 7);
|
|
||||||
if (charging && (level === 4 || level === 1))
|
|
||||||
level--;
|
|
||||||
return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`;
|
|
||||||
}
|
}
|
||||||
color: !UPower.onBattery || UPower.displayDevice.percentage > 0.2 ? root.colour : Colours.palette.m3error
|
color: !UPower.onBattery || UPower.displayDevice.percentage > 0.2 ? root.colour : Colours.palette.m3error
|
||||||
fill: 1
|
fill: 1
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ StyledRect {
|
||||||
readonly property alias items: items
|
readonly property alias items: items
|
||||||
readonly property alias expandIcon: expandIcon
|
readonly property alias expandIcon: expandIcon
|
||||||
|
|
||||||
readonly property int padding: Config.bar.tray.background ? Tokens.padding.normal : Tokens.padding.small
|
readonly property int padding: Config.bar.tray.background ? Tokens.padding.medium : Tokens.padding.extraSmall
|
||||||
readonly property int spacing: Config.bar.tray.background ? Tokens.spacing.small : 0
|
readonly property int spacing: Config.bar.tray.background ? Tokens.spacing.small : 0
|
||||||
|
|
||||||
property bool expanded
|
property bool expanded
|
||||||
|
|
@ -75,7 +75,9 @@ StyledRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,16 +93,16 @@ StyledRect {
|
||||||
|
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
implicitWidth: expandIconInner.implicitWidth
|
implicitWidth: expandIconInner.implicitWidth
|
||||||
implicitHeight: expandIconInner.implicitHeight - Tokens.padding.small * 2
|
implicitHeight: expandIconInner.implicitHeight - Tokens.padding.small
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: expandIconInner
|
id: expandIconInner
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: Config.bar.tray.background ? Tokens.padding.small : -Tokens.padding.small
|
anchors.bottomMargin: Config.bar.tray.background ? Tokens.padding.extraSmall : -Tokens.padding.extraSmall
|
||||||
text: "expand_less"
|
text: "expand_less"
|
||||||
font.pointSize: Tokens.font.size.large
|
fontStyle: Tokens.font.icon.large
|
||||||
rotation: root.expanded ? 180 : 0
|
rotation: root.expanded ? 180 : 0
|
||||||
|
|
||||||
Behavior on rotation {
|
Behavior on rotation {
|
||||||
|
|
@ -115,8 +117,6 @@ StyledRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
Anim {
|
Anim {}
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ MouseArea {
|
||||||
required property SystemTrayItem modelData
|
required property SystemTrayItem modelData
|
||||||
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
implicitWidth: Tokens.font.size.small * 2
|
implicitWidth: Tokens.font.body.small.pointSize * 2
|
||||||
implicitHeight: Tokens.font.size.small * 2
|
implicitHeight: Tokens.font.body.small.pointSize * 2
|
||||||
|
|
||||||
onClicked: event => {
|
onClicked: event => {
|
||||||
if (event.button === Qt.LeftButton)
|
if (event.button === Qt.LeftButton)
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ StyledRect {
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
y: offset + mask.y
|
y: offset + mask.y
|
||||||
implicitWidth: Tokens.sizes.bar.innerWidth - Tokens.padding.small * 2
|
implicitWidth: Tokens.sizes.bar.innerWidth - Tokens.padding.small
|
||||||
implicitHeight: size
|
implicitHeight: size
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Colours.palette.m3primary
|
color: Colours.palette.m3primary
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ Item {
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
anchors.horizontalCenter: root.horizontalCenter
|
||||||
|
|
||||||
y: (start?.y ?? 0) - 1
|
y: (start?.y ?? 0) - 1
|
||||||
implicitWidth: Tokens.sizes.bar.innerWidth - Tokens.padding.small * 2 + 2
|
implicitWidth: Tokens.sizes.bar.innerWidth - Tokens.padding.small + 2
|
||||||
implicitHeight: start && end ? end.y + end.size - start.y + 2 : 0
|
implicitHeight: start && end ? end.y + end.size - start.y + 2 : 0
|
||||||
|
|
||||||
color: Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
|
color: Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Item {
|
||||||
readonly property string activeSpecial: (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? monitor : Hypr.focusedMonitor)?.lastIpcObject.specialWorkspace?.name ?? ""
|
readonly property string activeSpecial: (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? monitor : Hypr.focusedMonitor)?.lastIpcObject.specialWorkspace?.name ?? ""
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: OpacityMask {
|
layer.effect: Mask {
|
||||||
maskSource: mask
|
maskSource: mask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +65,9 @@ Item {
|
||||||
opacity: view.contentY > 0 ? 0 : 1
|
opacity: view.contentY > 0 ? 0 : 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,10 +78,12 @@ Item {
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
implicitHeight: parent.height / 2
|
implicitHeight: parent.height / 2
|
||||||
opacity: view.contentY < view.contentHeight - parent.height + Tokens.padding.small ? 0 : 1
|
opacity: view.contentY < view.contentHeight - parent.height + Tokens.padding.extraSmall ? 0 : 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +92,7 @@ Item {
|
||||||
id: view
|
id: view
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
currentIndex: model.values.findIndex(w => w.name === root.activeSpecial)
|
currentIndex: model.values.findIndex(w => w.name === root.activeSpecial)
|
||||||
|
|
@ -213,7 +217,7 @@ Item {
|
||||||
drag.target: view.contentItem
|
drag.target: view.contentItem
|
||||||
drag.axis: Drag.YAxis
|
drag.axis: Drag.YAxis
|
||||||
drag.maximumY: 0
|
drag.maximumY: 0
|
||||||
drag.minimumY: Math.min(0, view.height - view.contentHeight - Tokens.padding.small)
|
drag.minimumY: Math.min(0, view.height - view.contentHeight - Tokens.padding.extraSmall)
|
||||||
|
|
||||||
onPressed: event => startY = event.y
|
onPressed: event => startY = event.y
|
||||||
|
|
||||||
|
|
@ -233,7 +237,7 @@ Item {
|
||||||
id: ws
|
id: ws
|
||||||
|
|
||||||
required property HyprlandWorkspace modelData
|
required property HyprlandWorkspace modelData
|
||||||
readonly property int size: label.Layout.preferredHeight + (hasWindows ? windows.implicitHeight + Tokens.padding.small : 0)
|
readonly property int size: label.Layout.preferredHeight + (hasWindows ? windows.implicitHeight + Tokens.padding.extraSmall : 0)
|
||||||
property int wsId
|
property int wsId
|
||||||
property string icon
|
property string icon
|
||||||
property bool hasWindows
|
property bool hasWindows
|
||||||
|
|
@ -284,7 +288,7 @@ Item {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||||
Layout.preferredHeight: Tokens.sizes.bar.innerWidth - Tokens.padding.small * 2
|
Layout.preferredHeight: Tokens.sizes.bar.innerWidth - Tokens.padding.small
|
||||||
|
|
||||||
sourceComponent: ws.icon.length === 1 ? letterComp : iconComp
|
sourceComponent: ws.icon.length === 1 ? letterComp : iconComp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ ColumnLayout {
|
||||||
|
|
||||||
readonly property bool isWorkspace: true // Flag for finding workspace children
|
readonly property bool isWorkspace: true // Flag for finding workspace children
|
||||||
// Unanimated prop for others to use as reference
|
// Unanimated prop for others to use as reference
|
||||||
readonly property int size: implicitHeight + (hasWindows ? Tokens.padding.small : 0)
|
readonly property int size: implicitHeight + (hasWindows ? Tokens.padding.extraSmall : 0)
|
||||||
|
|
||||||
readonly property int ws: groupOffset + index + 1
|
readonly property int ws: groupOffset + index + 1
|
||||||
readonly property bool isOccupied: occupied[ws] ?? false
|
readonly property bool isOccupied: occupied[ws] ?? false
|
||||||
|
|
@ -33,7 +33,7 @@ ColumnLayout {
|
||||||
id: indicator
|
id: indicator
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||||
Layout.preferredHeight: Tokens.sizes.bar.innerWidth - Tokens.padding.small * 2
|
Layout.preferredHeight: Tokens.sizes.bar.innerWidth - Tokens.padding.small
|
||||||
|
|
||||||
animate: true
|
animate: true
|
||||||
text: {
|
text: {
|
||||||
|
|
@ -52,6 +52,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
color: Config.bar.workspaces.occupiedBg || root.isOccupied || root.activeWsId === root.ws ? Colours.palette.m3onSurface : Colours.layer(Colours.palette.m3outlineVariant, 2)
|
color: Config.bar.workspaces.occupiedBg || root.isOccupied || root.activeWsId === root.ws ? Colours.palette.m3onSurface : Colours.layer(Colours.palette.m3outlineVariant, 2)
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
font.family: "Rubik" // Hard code rubik for now since google sans doesn't play well with certain unicode symbols apparently
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ StyledClippingRect {
|
||||||
property real blur: onSpecial ? 1 : 0
|
property real blur: onSpecial ? 1 : 0
|
||||||
|
|
||||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||||
implicitHeight: layout.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: layout.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
@ -51,7 +51,7 @@ StyledClippingRect {
|
||||||
active: Config.bar.workspaces.occupiedBg
|
active: Config.bar.workspaces.occupiedBg
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.extraSmall
|
||||||
|
|
||||||
sourceComponent: OccupiedBg {
|
sourceComponent: OccupiedBg {
|
||||||
workspaces: workspaces
|
workspaces: workspaces
|
||||||
|
|
@ -64,7 +64,7 @@ StyledClippingRect {
|
||||||
id: layout
|
id: layout
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Math.floor(Tokens.spacing.small / 2)
|
spacing: Math.floor(Tokens.spacing.extraSmall)
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: workspaces
|
id: workspaces
|
||||||
|
|
@ -108,7 +108,9 @@ StyledClippingRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +120,7 @@ StyledClippingRect {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.extraSmall
|
||||||
|
|
||||||
active: opacity > 0
|
active: opacity > 0
|
||||||
|
|
||||||
|
|
@ -134,7 +136,9 @@ StyledClippingRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,21 +12,21 @@ Item {
|
||||||
|
|
||||||
required property PopoutState popouts
|
required property PopoutState popouts
|
||||||
|
|
||||||
implicitWidth: Hypr.activeToplevel ? child.implicitWidth : -Tokens.padding.large * 2
|
implicitWidth: Hypr.activeToplevel ? child.implicitWidth : -Tokens.padding.extraLargeIncreased
|
||||||
implicitHeight: child.implicitHeight
|
implicitHeight: child.implicitHeight
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: child
|
id: child
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: detailsRow
|
id: detailsRow
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
id: icon
|
id: icon
|
||||||
|
|
@ -46,7 +46,7 @@ Item {
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: Hypr.activeToplevel?.title ?? ""
|
text: Hypr.activeToplevel?.title ?? ""
|
||||||
font.pointSize: Tokens.font.size.normal
|
font: Tokens.font.body.medium
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,13 +59,13 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
implicitWidth: expandIcon.implicitHeight + Tokens.padding.small * 2
|
implicitWidth: expandIcon.implicitHeight + Tokens.padding.small
|
||||||
implicitHeight: expandIcon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: expandIcon.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
onClicked: root.popouts.detachRequested("winfo")
|
onClicked: root.popouts.detachRequested("winfo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,14 +77,14 @@ Item {
|
||||||
|
|
||||||
text: "chevron_right"
|
text: "chevron_right"
|
||||||
|
|
||||||
font.pointSize: Tokens.font.size.large
|
fontStyle: Tokens.font.icon.large
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClippingWrapperRectangle {
|
ClippingWrapperRectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
ScreencopyView {
|
ScreencopyView {
|
||||||
id: preview
|
id: preview
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ Item {
|
||||||
|
|
||||||
required property PopoutState popouts
|
required property PopoutState popouts
|
||||||
|
|
||||||
implicitWidth: layout.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: layout.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: layout.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: layout.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
ButtonGroup {
|
ButtonGroup {
|
||||||
id: sinks
|
id: sinks
|
||||||
|
|
@ -30,11 +30,11 @@ Item {
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: qsTr("Output device")
|
text: qsTr("Output device")
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -53,9 +53,9 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.smaller
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
text: qsTr("Input device")
|
text: qsTr("Input device")
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -72,15 +72,14 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.smaller
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
Layout.bottomMargin: -Tokens.spacing.small / 2
|
|
||||||
text: qsTr("Volume (%1)").arg(Audio.muted ? qsTr("Muted") : `${Math.round(Audio.volume * 100)}%`)
|
text: qsTr("Volume (%1)").arg(Audio.muted ? qsTr("Muted") : `${Math.round(Audio.volume * 100)}%`)
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMouseArea {
|
CustomMouseArea {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: Tokens.padding.normal * 3
|
implicitHeight: Tokens.padding.medium * 3
|
||||||
|
|
||||||
onWheel: event => {
|
onWheel: event => {
|
||||||
if (event.angleDelta.y > 0)
|
if (event.angleDelta.y > 0)
|
||||||
|
|
@ -95,20 +94,16 @@ Item {
|
||||||
implicitHeight: parent.implicitHeight
|
implicitHeight: parent.implicitHeight
|
||||||
|
|
||||||
value: Audio.volume
|
value: Audio.volume
|
||||||
onMoved: Audio.setVolume(value)
|
onInteraction: value => Audio.setVolume(value)
|
||||||
|
|
||||||
Behavior on value {
|
|
||||||
Anim {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IconTextButton {
|
IconTextButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Tokens.spacing.normal
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
inactiveColour: Colours.palette.m3primaryContainer
|
inactiveColour: Colours.palette.m3primaryContainer
|
||||||
inactiveOnColour: Colours.palette.m3onPrimaryContainer
|
inactiveOnColour: Colours.palette.m3onPrimaryContainer
|
||||||
verticalPadding: Tokens.padding.small
|
verticalPadding: Tokens.padding.extraSmall
|
||||||
text: qsTr("Open settings")
|
text: qsTr("Open settings")
|
||||||
icon: "settings"
|
icon: "settings"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import qs.services
|
||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
width: Tokens.sizes.bar.batteryWidth
|
width: Tokens.sizes.bar.batteryWidth
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
@ -45,11 +45,11 @@ Column {
|
||||||
height: active ? ((item as Item)?.implicitHeight ?? 0) : 0
|
height: active ? ((item as Item)?.implicitHeight ?? 0) : 0
|
||||||
|
|
||||||
sourceComponent: StyledRect {
|
sourceComponent: StyledRect {
|
||||||
implicitWidth: child.implicitWidth + Tokens.padding.normal * 2
|
implicitWidth: child.implicitWidth + Tokens.padding.medium * 2
|
||||||
implicitHeight: child.implicitHeight + Tokens.padding.smaller * 2
|
implicitHeight: child.implicitHeight + Tokens.padding.large
|
||||||
|
|
||||||
color: Colours.palette.m3error
|
color: Colours.palette.m3error
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: child
|
id: child
|
||||||
|
|
@ -72,8 +72,7 @@ Column {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: qsTr("Performance Degraded")
|
text: qsTr("Performance Degraded")
|
||||||
color: Colours.palette.m3onError
|
color: Colours.palette.m3onError
|
||||||
font.family: Tokens.font.family.mono
|
font: Tokens.font.mono.builders.medium.weight(Font.Medium).build()
|
||||||
font.weight: 500
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
|
|
@ -109,8 +108,8 @@ Column {
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.normal * 2 + Tokens.spacing.large * 2
|
implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.medium * 2 + Tokens.spacing.largeIncreased * 2
|
||||||
implicitHeight: Math.max(saver.implicitHeight, balance.implicitHeight, perf.implicitHeight) + Tokens.padding.small * 2
|
implicitHeight: Math.max(saver.implicitHeight, balance.implicitHeight, perf.implicitHeight) + Tokens.padding.small
|
||||||
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
@ -147,9 +146,7 @@ Column {
|
||||||
]
|
]
|
||||||
|
|
||||||
transitions: Transition {
|
transitions: Transition {
|
||||||
AnchorAnim {
|
AnchorAnim {}
|
||||||
type: AnchorAnim.Emphasized
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,7 +155,7 @@ Column {
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Tokens.padding.small
|
anchors.leftMargin: Tokens.padding.extraSmall
|
||||||
|
|
||||||
profile: PowerProfile.PowerSaver
|
profile: PowerProfile.PowerSaver
|
||||||
icon: "energy_savings_leaf"
|
icon: "energy_savings_leaf"
|
||||||
|
|
@ -178,7 +175,7 @@ Column {
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Tokens.padding.small
|
anchors.rightMargin: Tokens.padding.extraSmall
|
||||||
|
|
||||||
profile: PowerProfile.Performance
|
profile: PowerProfile.Performance
|
||||||
icon: "rocket_launch"
|
icon: "rocket_launch"
|
||||||
|
|
@ -199,8 +196,8 @@ Column {
|
||||||
required property string icon
|
required property string icon
|
||||||
required property int profile
|
required property int profile
|
||||||
|
|
||||||
implicitWidth: icon.implicitHeight + Tokens.padding.small * 2
|
implicitWidth: icon.implicitHeight + Tokens.padding.small
|
||||||
implicitHeight: icon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: icon.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
@ -214,12 +211,14 @@ Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
text: parent.icon
|
text: parent.icon
|
||||||
font.pointSize: Tokens.font.size.large
|
fontStyle: Tokens.font.icon.large
|
||||||
color: profiles.current === text ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
|
color: profiles.current === text ? Colours.palette.m3onPrimary : Colours.palette.m3onSurfaceVariant
|
||||||
fill: profiles.current === text ? 1 : 0
|
fill: profiles.current === text ? 1 : 0
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,10 @@ ColumnLayout {
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.padding.normal
|
Layout.topMargin: Tokens.padding.medium
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: qsTr("Bluetooth")
|
text: qsTr("Bluetooth")
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
Toggle {
|
Toggle {
|
||||||
|
|
@ -47,7 +47,7 @@ ColumnLayout {
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.spacing.small
|
Layout.topMargin: Tokens.spacing.small
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: {
|
text: {
|
||||||
const devices = Bluetooth.devices.values; // qmllint disable unresolved-type
|
const devices = Bluetooth.devices.values; // qmllint disable unresolved-type
|
||||||
let available = qsTr("%1 device%2 available").arg(devices.length).arg(devices.length === 1 ? "" : "s");
|
let available = qsTr("%1 device%2 available").arg(devices.length).arg(devices.length === 1 ? "" : "s");
|
||||||
|
|
@ -57,7 +57,7 @@ ColumnLayout {
|
||||||
return available;
|
return available;
|
||||||
}
|
}
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -72,7 +72,7 @@ ColumnLayout {
|
||||||
readonly property bool loading: modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting // qmllint disable unresolved-type
|
readonly property bool loading: modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting // qmllint disable unresolved-type
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
@ -84,7 +84,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -96,8 +98,8 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.leftMargin: Tokens.spacing.small / 2
|
Layout.leftMargin: Tokens.spacing.extraSmall
|
||||||
Layout.rightMargin: Tokens.spacing.small / 2
|
Layout.rightMargin: Tokens.spacing.extraSmall
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: device.modelData.name
|
text: device.modelData.name
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
|
@ -105,15 +107,15 @@ ColumnLayout {
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
visible: device.modelData.state === BluetoothDeviceState.Connected // qmllint disable unresolved-type
|
visible: device.modelData.state === BluetoothDeviceState.Connected // qmllint disable unresolved-type
|
||||||
text: Icons.getBatteryIcon(device.modelData.batteryAvailable ? device.modelData.battery * 100 : -1)
|
text: device.modelData.batteryAvailable ? Icons.getBatteryIcon(device.modelData.battery) : "battery_alert"
|
||||||
color: device.modelData.battery < 0.2 ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant
|
color: device.modelData.batteryAvailable && device.modelData.battery < 0.2 ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
id: connectBtn
|
id: connectBtn
|
||||||
|
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: connectIcon.implicitHeight + Tokens.padding.small
|
implicitHeight: connectIcon.implicitHeight + Tokens.padding.extraSmall
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Qt.alpha(Colours.palette.m3primary, device.modelData.state === BluetoothDeviceState.Connected ? 1 : 0) // qmllint disable unresolved-type
|
color: Qt.alpha(Colours.palette.m3primary, device.modelData.state === BluetoothDeviceState.Connected ? 1 : 0) // qmllint disable unresolved-type
|
||||||
|
|
@ -140,7 +142,9 @@ ColumnLayout {
|
||||||
opacity: device.loading ? 0 : 1
|
opacity: device.loading ? 0 : 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -169,10 +173,10 @@ ColumnLayout {
|
||||||
|
|
||||||
IconTextButton {
|
IconTextButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Tokens.spacing.normal
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
inactiveColour: Colours.palette.m3primaryContainer
|
inactiveColour: Colours.palette.m3primaryContainer
|
||||||
inactiveOnColour: Colours.palette.m3onPrimaryContainer
|
inactiveOnColour: Colours.palette.m3onPrimaryContainer
|
||||||
verticalPadding: Tokens.padding.small
|
verticalPadding: Tokens.padding.extraSmall
|
||||||
text: qsTr("Open settings")
|
text: qsTr("Open settings")
|
||||||
icon: "settings"
|
icon: "settings"
|
||||||
|
|
||||||
|
|
@ -185,8 +189,8 @@ ColumnLayout {
|
||||||
property alias toggle: toggle
|
property alias toggle: toggle
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on offsetScale {
|
Behavior on offsetScale {
|
||||||
Anim {
|
Anim {}
|
||||||
type: Anim.DefaultSpatial
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on x {
|
Behavior on x {
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ Item {
|
||||||
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
||||||
readonly property Item current: currentPopout?.item ?? null
|
readonly property Item current: currentPopout?.item ?? null
|
||||||
|
|
||||||
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.large * 2
|
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.extraLargeIncreased
|
||||||
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.large * 2
|
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.extraLargeIncreased
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: content
|
id: content
|
||||||
|
|
@ -172,7 +172,6 @@ Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
scale: 0.8
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
states: State {
|
states: State {
|
||||||
|
|
@ -182,7 +181,6 @@ Item {
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
popout.active: true
|
popout.active: true
|
||||||
popout.opacity: 1
|
popout.opacity: 1
|
||||||
popout.scale: 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,11 +191,10 @@ Item {
|
||||||
|
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
properties: "opacity,scale"
|
property: "opacity"
|
||||||
type: Anim.StandardSmall
|
type: Anim.DefaultEffects
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: popout
|
|
||||||
property: "active"
|
property: "active"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -208,11 +205,11 @@ Item {
|
||||||
|
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
target: popout
|
|
||||||
property: "active"
|
property: "active"
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
properties: "opacity,scale"
|
property: "opacity"
|
||||||
|
type: Anim.SlowEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ ColumnLayout {
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: root.view === "wireless"
|
visible: root.view === "wireless"
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.topMargin: visible ? Tokens.padding.normal : 0
|
Layout.topMargin: visible ? Tokens.padding.medium : 0
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: qsTr("Wireless")
|
text: qsTr("Wireless")
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
Toggle {
|
Toggle {
|
||||||
|
|
@ -44,10 +44,10 @@ ColumnLayout {
|
||||||
visible: root.view === "wireless"
|
visible: root.view === "wireless"
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.topMargin: visible ? Tokens.spacing.small : 0
|
Layout.topMargin: visible ? Tokens.spacing.small : 0
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: qsTr("%1 networks available").arg(Nmcli.networks.length) // qmllint disable missing-property
|
text: qsTr("%1 networks available").arg(Nmcli.networks.length) // qmllint disable missing-property
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -70,7 +70,7 @@ ColumnLayout {
|
||||||
visible: root.view === "wireless"
|
visible: root.view === "wireless"
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
@ -82,7 +82,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -97,22 +99,22 @@ ColumnLayout {
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
visible: networkItem.modelData.isSecure
|
visible: networkItem.modelData.isSecure
|
||||||
text: "lock"
|
text: "lock"
|
||||||
font.pointSize: Tokens.font.size.small
|
fontStyle: Tokens.font.icon.small
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.leftMargin: Tokens.spacing.small / 2
|
Layout.leftMargin: Tokens.spacing.extraSmall
|
||||||
Layout.rightMargin: Tokens.spacing.small / 2
|
Layout.rightMargin: Tokens.spacing.extraSmall
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: networkItem.modelData.ssid
|
text: networkItem.modelData.ssid
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.weight: networkItem.modelData.active ? 500 : 400
|
font: Tokens.font.body.builders.medium.weight(networkItem.modelData.active ? Font.Medium : Font.Normal).build()
|
||||||
color: networkItem.modelData.active ? Colours.palette.m3primary : Colours.palette.m3onSurface
|
color: networkItem.modelData.active ? Colours.palette.m3primary : Colours.palette.m3onSurface
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: wirelessConnectIcon.implicitHeight + Tokens.padding.small
|
implicitHeight: wirelessConnectIcon.implicitHeight + Tokens.padding.extraSmall
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Qt.alpha(Colours.palette.m3primary, networkItem.modelData.active ? 1 : 0)
|
color: Qt.alpha(Colours.palette.m3primary, networkItem.modelData.active ? 1 : 0)
|
||||||
|
|
@ -155,7 +157,9 @@ ColumnLayout {
|
||||||
opacity: networkItem.loading ? 0 : 1
|
opacity: networkItem.loading ? 0 : 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,7 +171,7 @@ ColumnLayout {
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.topMargin: visible ? Tokens.spacing.small : 0
|
Layout.topMargin: visible ? Tokens.spacing.small : 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: rescanBtn.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: rescanBtn.implicitHeight + Tokens.padding.small
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Colours.palette.m3primaryContainer
|
color: Colours.palette.m3primaryContainer
|
||||||
|
|
@ -201,15 +205,17 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CircularIndicator {
|
CircularIndicator {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
strokeWidth: Tokens.padding.small / 2
|
strokeWidth: Tokens.padding.extraSmall / 2
|
||||||
bgColour: "transparent"
|
bgColour: "transparent"
|
||||||
implicitSize: parent.implicitHeight - Tokens.padding.smaller * 2
|
implicitSize: parent.implicitHeight - Tokens.padding.large
|
||||||
running: Nmcli.scanning
|
running: Nmcli.scanning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -218,20 +224,20 @@ ColumnLayout {
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: root.view === "ethernet"
|
visible: root.view === "ethernet"
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.topMargin: visible ? Tokens.padding.normal : 0
|
Layout.topMargin: visible ? Tokens.padding.medium : 0
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: qsTr("Ethernet")
|
text: qsTr("Ethernet")
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: root.view === "ethernet"
|
visible: root.view === "ethernet"
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.topMargin: visible ? Tokens.spacing.small : 0
|
Layout.topMargin: visible ? Tokens.spacing.small : 0
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: qsTr("%1 devices available").arg(Nmcli.ethernetDevices.length)
|
text: qsTr("%1 devices available").arg(Nmcli.ethernetDevices.length)
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
@ -253,7 +259,7 @@ ColumnLayout {
|
||||||
visible: root.view === "ethernet"
|
visible: root.view === "ethernet"
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
@ -265,7 +271,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -278,18 +286,18 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.leftMargin: Tokens.spacing.small / 2
|
Layout.leftMargin: Tokens.spacing.extraSmall
|
||||||
Layout.rightMargin: Tokens.spacing.small / 2
|
Layout.rightMargin: Tokens.spacing.extraSmall
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: ethernetItem.modelData.interface || qsTr("Unknown")
|
text: ethernetItem.modelData.interface || qsTr("Unknown")
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.weight: ethernetItem.modelData.connected ? 500 : 400
|
font: Tokens.font.body.builders.medium.weight(ethernetItem.modelData.connected ? Font.Medium : Font.Normal).build()
|
||||||
color: ethernetItem.modelData.connected ? Colours.palette.m3primary : Colours.palette.m3onSurface
|
color: ethernetItem.modelData.connected ? Colours.palette.m3primary : Colours.palette.m3onSurface
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: connectIcon.implicitHeight + Tokens.padding.small
|
implicitHeight: connectIcon.implicitHeight + Tokens.padding.extraSmall
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Qt.alpha(Colours.palette.m3primary, ethernetItem.modelData.connected ? 1 : 0)
|
color: Qt.alpha(Colours.palette.m3primary, ethernetItem.modelData.connected ? 1 : 0)
|
||||||
|
|
@ -323,7 +331,9 @@ ColumnLayout {
|
||||||
opacity: ethernetItem.loading ? 0 : 1
|
opacity: ethernetItem.loading ? 0 : 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -371,8 +381,8 @@ ColumnLayout {
|
||||||
property alias toggle: toggle
|
property alias toggle: toggle
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ StackView {
|
||||||
property bool isSubMenu
|
property bool isSubMenu
|
||||||
property bool shown
|
property bool shown
|
||||||
|
|
||||||
padding: Tokens.padding.smaller
|
padding: Tokens.padding.small
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
opacity: shown ? 1 : 0
|
opacity: shown ? 1 : 0
|
||||||
|
|
@ -57,7 +57,9 @@ StackView {
|
||||||
StackView.onRemoved: destroy()
|
StackView.onRemoved: destroy()
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -97,9 +99,9 @@ StackView {
|
||||||
implicitHeight: label.implicitHeight
|
implicitHeight: label.implicitHeight
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
anchors.margins: -Tokens.padding.small / 2
|
anchors.margins: -Tokens.padding.extraSmall / 2
|
||||||
anchors.leftMargin: -Tokens.padding.smaller
|
anchors.leftMargin: -Tokens.padding.small
|
||||||
anchors.rightMargin: -Tokens.padding.smaller
|
anchors.rightMargin: -Tokens.padding.small
|
||||||
|
|
||||||
radius: item.radius
|
radius: item.radius
|
||||||
disabled: !item.modelData.enabled
|
disabled: !item.modelData.enabled
|
||||||
|
|
@ -138,7 +140,7 @@ StackView {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
anchors.left: icon.right
|
anchors.left: icon.right
|
||||||
anchors.leftMargin: icon.active ? Tokens.spacing.smaller : 0
|
anchors.leftMargin: icon.active ? Tokens.spacing.medium : 0
|
||||||
|
|
||||||
text: labelMetrics.elidedText
|
text: labelMetrics.elidedText
|
||||||
color: item.modelData.enabled ? Colours.palette.m3onSurface : Colours.palette.m3outline
|
color: item.modelData.enabled ? Colours.palette.m3onSurface : Colours.palette.m3outline
|
||||||
|
|
@ -148,11 +150,10 @@ StackView {
|
||||||
id: labelMetrics
|
id: labelMetrics
|
||||||
|
|
||||||
text: item.modelData.text
|
text: item.modelData.text
|
||||||
font.pointSize: label.font.pointSize
|
font: label.font
|
||||||
font.family: label.font.family
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
elideWidth: root.Tokens.sizes.bar.trayMenuWidth - (icon.active ? icon.implicitWidth + label.anchors.leftMargin : 0) - (expand.active ? expand.implicitWidth + root.Tokens.spacing.normal : 0)
|
elideWidth: root.Tokens.sizes.bar.trayMenuWidth - (icon.active ? icon.implicitWidth + label.anchors.leftMargin : 0) - (expand.active ? expand.implicitWidth + root.Tokens.spacing.medium : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
|
@ -180,7 +181,7 @@ StackView {
|
||||||
|
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
implicitWidth: back.implicitWidth
|
implicitWidth: back.implicitWidth
|
||||||
implicitHeight: back.implicitHeight + Tokens.spacing.small / 2
|
implicitHeight: back.implicitHeight + Tokens.spacing.extraSmall
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
@ -189,9 +190,9 @@ StackView {
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: -Tokens.padding.small / 2
|
anchors.margins: -Tokens.padding.extraSmall / 2
|
||||||
anchors.leftMargin: -Tokens.padding.smaller
|
anchors.leftMargin: -Tokens.padding.small
|
||||||
anchors.rightMargin: -Tokens.padding.smaller * 2
|
anchors.rightMargin: -Tokens.padding.large
|
||||||
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
color: Colours.palette.m3secondaryContainer
|
color: Colours.palette.m3secondaryContainer
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: content.implicitHeight + Tokens.padding.large * 2
|
implicitHeight: content.implicitHeight + Tokens.padding.extraLargeIncreased
|
||||||
visible: shouldBeVisible || isClosing
|
visible: shouldBeVisible || isClosing
|
||||||
enabled: shouldBeVisible && !isClosing
|
enabled: shouldBeVisible && !isClosing
|
||||||
focus: enabled
|
focus: enabled
|
||||||
|
|
@ -128,8 +128,8 @@ ColumnLayout {
|
||||||
StyledRect {
|
StyledRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: 400
|
Layout.preferredWidth: 400
|
||||||
implicitHeight: content.implicitHeight + Tokens.padding.large * 2
|
implicitHeight: content.implicitHeight + Tokens.padding.extraLargeIncreased
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
visible: root.shouldBeVisible || root.isClosing
|
visible: root.shouldBeVisible || root.isClosing
|
||||||
opacity: root.shouldBeVisible && !root.isClosing ? 1 : 0
|
opacity: root.shouldBeVisible && !root.isClosing ? 1 : 0
|
||||||
|
|
@ -137,7 +137,9 @@ ColumnLayout {
|
||||||
Keys.onEscapePressed: root.closeDialog()
|
Keys.onEscapePressed: root.closeDialog()
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -153,6 +155,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
target: parent
|
target: parent
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 0
|
to: 0
|
||||||
|
|
@ -172,19 +175,18 @@ ColumnLayout {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.margins: Tokens.padding.large
|
anchors.margins: Tokens.padding.large
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: "lock"
|
text: "lock"
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 2
|
fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: qsTr("Enter password")
|
text: qsTr("Enter password")
|
||||||
font.pointSize: Tokens.font.size.large
|
font: Tokens.font.body.builders.large.weight(Font.Medium).build()
|
||||||
font.weight: 500
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
@ -201,7 +203,7 @@ ColumnLayout {
|
||||||
return qsTr("Network: Unknown");
|
return qsTr("Network: Unknown");
|
||||||
}
|
}
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.small
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
|
@ -249,10 +251,9 @@ ColumnLayout {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
color: connectButton.hasError ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant
|
color: connectButton.hasError ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Tokens.font.size.small
|
font: Tokens.font.body.builders.small.weight(Font.Normal).build()
|
||||||
font.weight: 400
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.maximumWidth: parent.width - Tokens.padding.large * 2
|
Layout.maximumWidth: parent.width - Tokens.padding.extraLargeIncreased
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusScope {
|
FocusScope {
|
||||||
|
|
@ -261,9 +262,9 @@ ColumnLayout {
|
||||||
property string passwordBuffer: ""
|
property string passwordBuffer: ""
|
||||||
|
|
||||||
objectName: "passwordContainer"
|
objectName: "passwordContainer"
|
||||||
Layout.topMargin: Tokens.spacing.large
|
Layout.topMargin: Tokens.spacing.largeIncreased
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: Math.max(48, charList.implicitHeight + Tokens.padding.normal * 2)
|
implicitHeight: Math.max(48, charList.implicitHeight + Tokens.padding.medium * 2)
|
||||||
focus: true
|
focus: true
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
|
@ -336,7 +337,7 @@ ColumnLayout {
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
color: passwordContainer.activeFocus ? Qt.lighter(Colours.tPalette.m3surfaceContainer, 1.05) : Colours.tPalette.m3surfaceContainer
|
color: passwordContainer.activeFocus ? Qt.lighter(Colours.tPalette.m3surfaceContainer, 1.05) : Colours.tPalette.m3surfaceContainer
|
||||||
border.width: passwordContainer.activeFocus || connectButton.hasError ? 4 : (root.shouldBeVisible ? 1 : 0)
|
border.width: passwordContainer.activeFocus || connectButton.hasError ? 4 : (root.shouldBeVisible ? 1 : 0)
|
||||||
border.color: {
|
border.color: {
|
||||||
|
|
@ -365,7 +366,7 @@ ColumnLayout {
|
||||||
StateLayer {
|
StateLayer {
|
||||||
hoverEnabled: false
|
hoverEnabled: false
|
||||||
cursorShape: Qt.IBeamCursor
|
cursorShape: Qt.IBeamCursor
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
onClicked: passwordContainer.forceActiveFocus()
|
onClicked: passwordContainer.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,12 +376,13 @@ ColumnLayout {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: qsTr("Password")
|
text: qsTr("Password")
|
||||||
color: Colours.palette.m3outline
|
color: Colours.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.normal
|
font: Tokens.font.mono.medium
|
||||||
font.family: Tokens.font.family.mono
|
|
||||||
opacity: passwordContainer.passwordBuffer ? 0 : 1
|
opacity: passwordContainer.passwordBuffer ? 0 : 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,10 +393,10 @@ ColumnLayout {
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: fullWidth
|
implicitWidth: fullWidth
|
||||||
implicitHeight: Tokens.font.size.normal
|
implicitHeight: Tokens.font.body.medium.pointSize
|
||||||
|
|
||||||
orientation: Qt.Horizontal
|
orientation: Qt.Horizontal
|
||||||
spacing: Tokens.spacing.small / 2
|
spacing: Tokens.spacing.extraSmall
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
|
|
@ -408,7 +410,7 @@ ColumnLayout {
|
||||||
implicitHeight: charList.implicitHeight
|
implicitHeight: charList.implicitHeight
|
||||||
|
|
||||||
color: Colours.palette.m3onSurface
|
color: Colours.palette.m3onSurface
|
||||||
radius: Tokens.rounding.small / 2
|
radius: Tokens.rounding.medium / 2
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
scale: 0
|
scale: 0
|
||||||
|
|
@ -428,6 +430,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
target: ch
|
target: ch
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
to: 0
|
to: 0
|
||||||
|
|
@ -446,7 +449,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
|
|
@ -463,15 +468,15 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.topMargin: Tokens.spacing.normal
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
TextButton {
|
TextButton {
|
||||||
id: cancelButton
|
id: cancelButton
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: Tokens.font.size.normal + Tokens.padding.normal * 2
|
Layout.minimumHeight: Tokens.font.body.medium.pointSize + Tokens.padding.medium * 2
|
||||||
inactiveColour: Colours.palette.m3secondaryContainer
|
inactiveColour: Colours.palette.m3secondaryContainer
|
||||||
inactiveOnColour: Colours.palette.m3onSecondaryContainer
|
inactiveOnColour: Colours.palette.m3onSecondaryContainer
|
||||||
text: qsTr("Cancel")
|
text: qsTr("Cancel")
|
||||||
|
|
@ -486,7 +491,7 @@ ColumnLayout {
|
||||||
property bool hasError: false
|
property bool hasError: false
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: Tokens.font.size.normal + Tokens.padding.normal * 2
|
Layout.minimumHeight: Tokens.font.body.medium.pointSize + Tokens.padding.medium * 2
|
||||||
inactiveColour: Colours.palette.m3primary
|
inactiveColour: Colours.palette.m3primary
|
||||||
inactiveOnColour: Colours.palette.m3onPrimary
|
inactiveOnColour: Colours.palette.m3onPrimary
|
||||||
text: qsTr("Connect")
|
text: qsTr("Connect")
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import Quickshell.Wayland
|
||||||
import Caelestia.Config
|
import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.controlcenter
|
import qs.modules.nexus
|
||||||
import qs.modules.windowinfo
|
import qs.modules.windowinfo
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -18,7 +18,7 @@ Item {
|
||||||
|
|
||||||
readonly property alias content: content
|
readonly property alias content: content
|
||||||
readonly property alias winfo: winfo
|
readonly property alias winfo: winfo
|
||||||
readonly property alias controlCenter: controlCenter
|
readonly property alias nexus: nexus
|
||||||
|
|
||||||
readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth
|
readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth
|
||||||
readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight
|
readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight
|
||||||
|
|
@ -128,15 +128,24 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Comp {
|
Comp {
|
||||||
id: controlCenter
|
id: nexus
|
||||||
|
|
||||||
shouldBeActive: root.detachedMode === "any"
|
shouldBeActive: root.detachedMode === "any"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
sourceComponent: ControlCenter {
|
sourceComponent: StyledClippingRect {
|
||||||
screen: root.screen
|
radius: Tokens.rounding.extraLarge
|
||||||
active: root.queuedMode
|
implicitWidth: nexusInner.implicitWidth
|
||||||
onClose: root.close()
|
implicitHeight: nexusInner.implicitHeight
|
||||||
|
|
||||||
|
Nexus {
|
||||||
|
id: nexusInner
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
nState.screen: root.screen
|
||||||
|
nState.currentPageIdx: ["appearance", "network", "bluetooth", "audio"].indexOf(root.queuedMode)
|
||||||
|
onClose: root.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,6 +194,7 @@ Item {
|
||||||
property: "active"
|
property: "active"
|
||||||
}
|
}
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,6 +205,7 @@ Item {
|
||||||
|
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
}
|
}
|
||||||
PropertyAction {
|
PropertyAction {
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.topMargin: Tokens.padding.normal
|
Layout.topMargin: Tokens.padding.medium
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
text: qsTr("Keyboard Layouts")
|
text: qsTr("Keyboard Layouts")
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
|
|
@ -36,7 +36,7 @@ ColumnLayout {
|
||||||
model: kb.visibleModel
|
model: kb.visibleModel
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
Layout.topMargin: Tokens.spacing.small
|
Layout.topMargin: Tokens.spacing.small
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
@ -88,7 +88,7 @@ ColumnLayout {
|
||||||
readonly property bool isDisabled: layoutIndex > 3
|
readonly property bool isDisabled: layoutIndex > 3
|
||||||
|
|
||||||
width: list.width
|
width: list.width
|
||||||
height: Math.max(36, rowText.implicitHeight + Tokens.padding.small * 2)
|
height: Math.max(36, rowText.implicitHeight + Tokens.padding.small)
|
||||||
ToolTip.visible: isDisabled && layer.containsMouse
|
ToolTip.visible: isDisabled && layer.containsMouse
|
||||||
ToolTip.text: "XKB limitation: maximum 4 layouts allowed"
|
ToolTip.text: "XKB limitation: maximum 4 layouts allowed"
|
||||||
|
|
||||||
|
|
@ -114,8 +114,8 @@ ColumnLayout {
|
||||||
anchors.verticalCenter: layer.verticalCenter
|
anchors.verticalCenter: layer.verticalCenter
|
||||||
anchors.left: layer.left
|
anchors.left: layer.left
|
||||||
anchors.right: layer.right
|
anchors.right: layer.right
|
||||||
anchors.leftMargin: Tokens.padding.small
|
anchors.leftMargin: Tokens.padding.extraSmall
|
||||||
anchors.rightMargin: Tokens.padding.small
|
anchors.rightMargin: Tokens.padding.extraSmall
|
||||||
text: kbDelegate.label
|
text: kbDelegate.label
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
opacity: kbDelegate.isDisabled ? 0.4 : 1.0
|
opacity: kbDelegate.isDisabled ? 0.4 : 1.0
|
||||||
|
|
@ -126,7 +126,7 @@ ColumnLayout {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: kb.activeLabel.length > 0
|
visible: kb.activeLabel.length > 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
Layout.topMargin: Tokens.spacing.small
|
Layout.topMargin: Tokens.spacing.small
|
||||||
|
|
||||||
implicitHeight: 1
|
implicitHeight: 1
|
||||||
|
|
@ -139,7 +139,7 @@ ColumnLayout {
|
||||||
|
|
||||||
visible: kb.activeLabel.length > 0
|
visible: kb.activeLabel.length > 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: Tokens.padding.small
|
Layout.rightMargin: Tokens.padding.extraSmall
|
||||||
Layout.topMargin: Tokens.spacing.small
|
Layout.topMargin: Tokens.spacing.small
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: kb.activeLabel
|
text: kb.activeLabel
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.weight: 500
|
font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
|
||||||
color: Colours.palette.m3primary
|
color: Colours.palette.m3primary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,25 +10,25 @@ import Caelestia.Config
|
||||||
Item {
|
Item {
|
||||||
id: model
|
id: model
|
||||||
|
|
||||||
property alias visibleModel: _visibleModel
|
property alias visibleModel: visibleModel
|
||||||
property string activeLabel: ""
|
property string activeLabel: ""
|
||||||
property int activeIndex: -1
|
property int activeIndex: -1
|
||||||
property var _xkbMap: ({})
|
property var _xkbMap: ({})
|
||||||
property bool _notifiedLimit: false
|
property bool _notifiedLimit: false
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
_xkbXmlBase.running = true;
|
xkbXmlBase.running = true;
|
||||||
_getKbLayoutOpt.running = true;
|
getKbLayoutOpt.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh() {
|
function refresh() {
|
||||||
_notifiedLimit = false;
|
_notifiedLimit = false;
|
||||||
_getKbLayoutOpt.running = true;
|
getKbLayoutOpt.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchTo(idx) {
|
function switchTo(idx) {
|
||||||
_switchProc.command = ["hyprctl", "switchxkblayout", "all", String(idx)];
|
switchProc.command = ["hyprctl", "switchxkblayout", "all", String(idx)];
|
||||||
_switchProc.running = true;
|
switchProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _buildXmlMap(xml) {
|
function _buildXmlMap(xml) {
|
||||||
|
|
@ -50,19 +50,19 @@ Item {
|
||||||
|
|
||||||
_xkbMap = map;
|
_xkbMap = map;
|
||||||
|
|
||||||
if (_layoutsModel.count > 0) {
|
if (layoutsModel.count > 0) {
|
||||||
const tmp = [];
|
const tmp = [];
|
||||||
for (let i = 0; i < _layoutsModel.count; i++) {
|
for (let i = 0; i < layoutsModel.count; i++) {
|
||||||
const it = _layoutsModel.get(i);
|
const it = layoutsModel.get(i);
|
||||||
tmp.push({
|
tmp.push({
|
||||||
layoutIndex: it.layoutIndex,
|
layoutIndex: it.layoutIndex,
|
||||||
token: it.token,
|
token: it.token,
|
||||||
label: _pretty(it.token)
|
label: _pretty(it.token)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_layoutsModel.clear();
|
layoutsModel.clear();
|
||||||
tmp.forEach(t => _layoutsModel.append(t));
|
tmp.forEach(t => layoutsModel.append(t));
|
||||||
_fetchActiveLayouts.running = true;
|
fetchActiveLayouts.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ Item {
|
||||||
|
|
||||||
function _setLayouts(raw) {
|
function _setLayouts(raw) {
|
||||||
const parts = raw.split(",").map(s => s.trim()).filter(Boolean);
|
const parts = raw.split(",").map(s => s.trim()).filter(Boolean);
|
||||||
_layoutsModel.clear();
|
layoutsModel.clear();
|
||||||
|
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
|
|
@ -87,7 +87,7 @@ Item {
|
||||||
if (seen.has(p))
|
if (seen.has(p))
|
||||||
continue;
|
continue;
|
||||||
seen.add(p);
|
seen.add(p);
|
||||||
_layoutsModel.append({
|
layoutsModel.append({
|
||||||
layoutIndex: idx,
|
layoutIndex: idx,
|
||||||
token: p,
|
token: p,
|
||||||
label: _pretty(p)
|
label: _pretty(p)
|
||||||
|
|
@ -97,19 +97,19 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _rebuildVisible() {
|
function _rebuildVisible() {
|
||||||
_visibleModel.clear();
|
visibleModel.clear();
|
||||||
|
|
||||||
let arr = [];
|
let arr = [];
|
||||||
for (let i = 0; i < _layoutsModel.count; i++)
|
for (let i = 0; i < layoutsModel.count; i++)
|
||||||
arr.push(_layoutsModel.get(i));
|
arr.push(layoutsModel.get(i));
|
||||||
|
|
||||||
arr = arr.filter(i => i.layoutIndex !== activeIndex);
|
arr = arr.filter(i => i.layoutIndex !== activeIndex);
|
||||||
arr.forEach(i => _visibleModel.append(i));
|
arr.forEach(i => visibleModel.append(i));
|
||||||
|
|
||||||
if (!GlobalConfig.utilities.toasts.kbLimit)
|
if (!GlobalConfig.utilities.toasts.kbLimit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_layoutsModel.count > 4) {
|
if (layoutsModel.count > 4) {
|
||||||
Toaster.toast(qsTr("Keyboard layout limit"), qsTr("XKB supports only 4 layouts at a time"), "warning");
|
Toaster.toast(qsTr("Keyboard layout limit"), qsTr("XKB supports only 4 layouts at a time"), "warning");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,26 +124,26 @@ Item {
|
||||||
visible: false
|
visible: false
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: _visibleModel
|
id: visibleModel
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: _layoutsModel
|
id: layoutsModel
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _xkbXmlBase
|
id: xkbXmlBase
|
||||||
|
|
||||||
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/base.xml"]
|
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/base.xml"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: model._buildXmlMap(text)
|
onStreamFinished: model._buildXmlMap(text)
|
||||||
}
|
}
|
||||||
onRunningChanged: if (!running && (typeof _xkbXmlBase.exitCode !== "undefined") && _xkbXmlBase.exitCode !== 0) // qmllint disable missing-property
|
onRunningChanged: if (!running && (typeof xkbXmlBase.exitCode !== "undefined") && xkbXmlBase.exitCode !== 0) // qmllint disable missing-property
|
||||||
_xkbXmlEvdev.running = true
|
xkbXmlEvdev.running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _xkbXmlEvdev
|
id: xkbXmlEvdev
|
||||||
|
|
||||||
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/evdev.xml"]
|
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/evdev.xml"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
|
|
@ -152,7 +152,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _getKbLayoutOpt
|
id: getKbLayoutOpt
|
||||||
|
|
||||||
command: ["hyprctl", "-j", "getoption", "input:kb_layout"]
|
command: ["hyprctl", "-j", "getoption", "input:kb_layout"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
|
|
@ -162,17 +162,17 @@ Item {
|
||||||
const raw = (j?.str || j?.value || "").toString().trim();
|
const raw = (j?.str || j?.value || "").toString().trim();
|
||||||
if (raw.length) {
|
if (raw.length) {
|
||||||
model._setLayouts(raw);
|
model._setLayouts(raw);
|
||||||
_fetchActiveLayouts.running = true;
|
fetchActiveLayouts.running = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
_fetchLayoutsFromDevices.running = true;
|
fetchLayoutsFromDevices.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _fetchLayoutsFromDevices
|
id: fetchLayoutsFromDevices
|
||||||
|
|
||||||
command: ["hyprctl", "-j", "devices"]
|
command: ["hyprctl", "-j", "devices"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
|
|
@ -184,13 +184,13 @@ Item {
|
||||||
if (raw.length)
|
if (raw.length)
|
||||||
model._setLayouts(raw);
|
model._setLayouts(raw);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
_fetchActiveLayouts.running = true;
|
fetchActiveLayouts.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _fetchActiveLayouts
|
id: fetchActiveLayouts
|
||||||
|
|
||||||
command: ["hyprctl", "-j", "devices"]
|
command: ["hyprctl", "-j", "devices"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
|
|
@ -201,7 +201,7 @@ Item {
|
||||||
const idx = kb?.active_layout_index ?? -1;
|
const idx = kb?.active_layout_index ?? -1;
|
||||||
|
|
||||||
model.activeIndex = idx >= 0 ? idx : -1;
|
model.activeIndex = idx >= 0 ? idx : -1;
|
||||||
model.activeLabel = (idx >= 0 && idx < _layoutsModel.count) ? _layoutsModel.get(idx).label : "";
|
model.activeLabel = (idx >= 0 && idx < layoutsModel.count) ? layoutsModel.get(idx).label : "";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
model.activeIndex = -1;
|
model.activeIndex = -1;
|
||||||
model.activeLabel = "";
|
model.activeLabel = "";
|
||||||
|
|
@ -213,9 +213,9 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _switchProc
|
id: switchProc
|
||||||
|
|
||||||
onRunningChanged: if (!running)
|
onRunningChanged: if (!running)
|
||||||
_fetchActiveLayouts.running = true
|
fetchActiveLayouts.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Caelestia.Config
|
|
||||||
import qs.components
|
|
||||||
import qs.components.controls
|
|
||||||
import qs.services
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property ShellScreen screen
|
|
||||||
readonly property int rounding: floating ? 0 : Tokens.rounding.large
|
|
||||||
|
|
||||||
property alias floating: session.floating
|
|
||||||
property alias active: session.active
|
|
||||||
property alias navExpanded: session.navExpanded
|
|
||||||
|
|
||||||
readonly property bool initialOpeningComplete: panes.initialOpeningComplete
|
|
||||||
readonly property Session session: Session {
|
|
||||||
id: session
|
|
||||||
|
|
||||||
root: root
|
|
||||||
}
|
|
||||||
|
|
||||||
signal close
|
|
||||||
|
|
||||||
implicitWidth: implicitHeight * Tokens.sizes.controlCenter.ratio
|
|
||||||
implicitHeight: screen.height * Tokens.sizes.controlCenter.heightMult
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
rowSpacing: 0
|
|
||||||
columnSpacing: 0
|
|
||||||
rows: root.floating ? 2 : 1
|
|
||||||
columns: 2
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.columnSpan: 2
|
|
||||||
|
|
||||||
asynchronous: true
|
|
||||||
active: root.floating
|
|
||||||
visible: active
|
|
||||||
|
|
||||||
sourceComponent: WindowTitle {
|
|
||||||
screen: root.screen
|
|
||||||
session: root.session
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
topLeftRadius: root.rounding
|
|
||||||
bottomLeftRadius: root.rounding
|
|
||||||
implicitWidth: navRail.implicitWidth
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
|
||||||
|
|
||||||
CustomMouseArea {
|
|
||||||
function onWheel(event: WheelEvent): void {
|
|
||||||
// Prevent tab switching during initial opening animation to avoid blank pages
|
|
||||||
if (!panes.initialOpeningComplete) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.angleDelta.y < 0)
|
|
||||||
root.session.activeIndex = Math.min(root.session.activeIndex + 1, root.session.panes.length - 1);
|
|
||||||
else if (event.angleDelta.y > 0)
|
|
||||||
root.session.activeIndex = Math.max(root.session.activeIndex - 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
NavRail {
|
|
||||||
id: navRail
|
|
||||||
|
|
||||||
screen: root.screen
|
|
||||||
session: root.session
|
|
||||||
initialOpeningComplete: root.initialOpeningComplete
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Panes {
|
|
||||||
id: panes
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
topRightRadius: root.rounding
|
|
||||||
bottomRightRadius: root.rounding
|
|
||||||
session: root.session
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue