Compare commits
90
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f6847ce0e | ||
|
|
e5e52802de | ||
|
|
42f02f4dd2 | ||
|
|
9df3a64815 | ||
|
|
9370284c6b | ||
|
|
5598f4f435 | ||
|
|
7e02c87b91 | ||
|
|
d3e61efd86 | ||
|
|
de95b6c8f9 | ||
|
|
4ff4afa279 | ||
|
|
8a83181f11 | ||
|
|
f778335600 | ||
|
|
6de7672c05 | ||
|
|
eb65e44ac8 | ||
|
|
d74daf96ca | ||
|
|
de44096132 | ||
|
|
59213cf30d | ||
|
|
7e9c05d90a | ||
|
|
f9a17caaf3 | ||
|
|
7d6f3cc275 | ||
|
|
8ec454306f | ||
|
|
968055a24e | ||
|
|
46855b6a7f | ||
|
|
dfc203f905 | ||
|
|
78c0a6fdfc | ||
|
|
98fc9aa97a | ||
|
|
db76ae7dc6 | ||
|
|
de55b5f1e4 | ||
|
|
2c62ad093c | ||
|
|
97c48d03f4 | ||
|
|
69d8f6d727 | ||
|
|
ddfa6cd3c4 | ||
|
|
c35e73886a | ||
|
|
c7bf7cdc0b | ||
|
|
177b0f319c | ||
|
|
d3e781731e | ||
|
|
abb180c947 | ||
|
|
babfe4b3de | ||
|
|
31f73b05e4 | ||
|
|
a6c1985bff | ||
|
|
69c2bfae9d | ||
|
|
43647dd486 | ||
|
|
43f070f887 | ||
|
|
4e75f21446 | ||
|
|
654632128f | ||
|
|
797fe31b2b | ||
|
|
4037a1dd0f | ||
|
|
03ef51cd0c | ||
|
|
a41c0adb3e | ||
|
|
33c9432390 | ||
|
|
bfaba488f3 | ||
|
|
0c788ca4dc | ||
|
|
4f4b3ce8c6 | ||
|
|
c42feec312 | ||
|
|
4f544981c1 | ||
|
|
ba567efc22 | ||
|
|
cbb24a2c40 | ||
|
|
da21675f03 | ||
|
|
02bb7e43d8 | ||
|
|
8883d98b00
|
||
|
|
cf907089da
|
||
|
|
070fe7add0 | ||
|
|
052e3a7800 | ||
|
|
fb0c75a2ba | ||
|
|
5efa0de3a5 | ||
|
|
858ef68565 | ||
|
|
5e97ea6867 | ||
|
|
9823c66299 | ||
|
|
0092b41a05 | ||
|
|
abf7382771
|
||
|
|
ec80adf0a5 | ||
|
|
a1a8a6e695
|
||
|
|
88a2808a47 | ||
|
|
a13daf27a6 | ||
|
|
abef1eb259 | ||
|
|
ef8811724f | ||
|
|
4517e5ecd0 | ||
|
|
75de349ff4 | ||
|
|
1d150292d3 | ||
|
|
439a14d29e | ||
|
|
bf5a8b8049 | ||
|
|
a9bbb21f54 | ||
|
|
bb50cf756d | ||
|
|
57147dc7c1 | ||
|
|
620fe001a4 | ||
|
|
85320e9ea1 | ||
|
|
259a4dde7a | ||
|
|
d6230bef34 | ||
|
|
4ee9bb3f12 | ||
|
|
8789d2d322 |
+21
-86
@@ -1,12 +1,15 @@
|
|||||||
name: Python
|
name: Python
|
||||||
|
|
||||||
|
env:
|
||||||
|
APT_DEPS: git python3 python3-pip python3-venv python3-gi python3-cairo python3-dbus python3-pyudev python3-psutil python3-evdev python3-yaml python3-xlib python3-pillow gir1.2-gtk-3.0
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
fmt:
|
static:
|
||||||
runs-on: alpine
|
runs-on: debian
|
||||||
container: node:26-alpine
|
container: node:26-trixie-slim
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -14,10 +17,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: |
|
run: |
|
||||||
apk add --no-cache \
|
apt-get update
|
||||||
git \
|
apt-get install -y --no-install-recommends git python3 python3-pip python3-venv
|
||||||
python3 \
|
|
||||||
py3-pip
|
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
pip install --no-cache-dir ruff
|
pip install --no-cache-dir ruff
|
||||||
@@ -27,32 +28,15 @@ jobs:
|
|||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
ruff format --check .
|
ruff format --check .
|
||||||
|
|
||||||
lint:
|
|
||||||
runs-on: alpine
|
|
||||||
container: node:26-alpine
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install tools
|
|
||||||
run: |
|
|
||||||
apk add --no-cache \
|
|
||||||
git \
|
|
||||||
python3 \
|
|
||||||
py3-pip
|
|
||||||
python3 -m venv .venv
|
|
||||||
. .venv/bin/activate
|
|
||||||
pip install --no-cache-dir ruff
|
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: |
|
run: |
|
||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
ruff check .
|
ruff check .
|
||||||
|
|
||||||
test:
|
verify:
|
||||||
runs-on: alpine
|
if: always()
|
||||||
container: node:26-alpine
|
runs-on: debian
|
||||||
|
container: node:26-trixie-slim
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -60,20 +44,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: |
|
run: |
|
||||||
apk add --no-cache \
|
apt-get update
|
||||||
git \
|
apt-get install -y --no-install-recommends $APT_DEPS build-essential python3-dev
|
||||||
python3 \
|
python3 -m venv --system-site-packages .venv
|
||||||
py3-pip \
|
|
||||||
py3-pillow \
|
|
||||||
build-base
|
|
||||||
python3 -m venv .venv
|
|
||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
pip install --no-cache-dir \
|
pip install --no-cache-dir basedpyright nuitka .
|
||||||
typer \
|
|
||||||
pillow \
|
- name: Type check
|
||||||
materialyoucolor \
|
run: |
|
||||||
jinja2 \
|
. .venv/bin/activate
|
||||||
pytest
|
basedpyright
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
@@ -81,51 +61,6 @@ jobs:
|
|||||||
cd cli
|
cd cli
|
||||||
python -m pytest tests/ -v
|
python -m pytest tests/ -v
|
||||||
|
|
||||||
typecheck:
|
|
||||||
runs-on: alpine
|
|
||||||
container: node:26-alpine
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install tools
|
|
||||||
run: |
|
|
||||||
apk add --no-cache \
|
|
||||||
git \
|
|
||||||
python3 \
|
|
||||||
py3-pip
|
|
||||||
python3 -m venv .venv
|
|
||||||
. .venv/bin/activate
|
|
||||||
pip install --no-cache-dir basedpyright
|
|
||||||
|
|
||||||
- name: Type check
|
|
||||||
run: |
|
|
||||||
. .venv/bin/activate
|
|
||||||
basedpyright
|
|
||||||
|
|
||||||
buildcheck:
|
|
||||||
runs-on: alpine
|
|
||||||
container: node:26-alpine
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install tools
|
|
||||||
run: |
|
|
||||||
apk add --no-cache \
|
|
||||||
git \
|
|
||||||
python3 \
|
|
||||||
py3-pip \
|
|
||||||
build-base \
|
|
||||||
python3-dev \
|
|
||||||
gcc \
|
|
||||||
g++
|
|
||||||
python3 -m venv .venv
|
|
||||||
. .venv/bin/activate
|
|
||||||
pip install --no-cache-dir nuitka
|
|
||||||
|
|
||||||
- name: Nuitka module check
|
- name: Nuitka module check
|
||||||
run: |
|
run: |
|
||||||
. .venv/bin/activate
|
. .venv/bin/activate
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ dist/
|
|||||||
**/test-plugins/
|
**/test-plugins/
|
||||||
**/Charts/
|
**/Charts/
|
||||||
network-dev/
|
network-dev/
|
||||||
|
**/zshell.build/
|
||||||
|
**/zshell.dist/
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ if("shell" IN_LIST ENABLE_MODULES)
|
|||||||
${NUITKA_EXECUTABLE}
|
${NUITKA_EXECUTABLE}
|
||||||
--standalone
|
--standalone
|
||||||
--include-data-dir=${CMAKE_SOURCE_DIR}/cli/src/zshell/assets=zshell/assets
|
--include-data-dir=${CMAKE_SOURCE_DIR}/cli/src/zshell/assets=zshell/assets
|
||||||
|
--include-package=gi.overrides
|
||||||
|
--include-package-data=solaar
|
||||||
--output-dir=${ZSHELL_CLI_BUILD_DIR}
|
--output-dir=${ZSHELL_CLI_BUILD_DIR}
|
||||||
--output-filename=zshell-cli
|
--output-filename=zshell-cli
|
||||||
${CMAKE_SOURCE_DIR}/cli/src/zshell/
|
${CMAKE_SOURCE_DIR}/cli/src/zshell/
|
||||||
|
|||||||
@@ -27,25 +27,25 @@ AnchorAnimation {
|
|||||||
if (type == AnchorAnim.DefaultSpatial)
|
if (type == AnchorAnim.DefaultSpatial)
|
||||||
return Tokens.anim.durations.expressiveDefaultSpatial;
|
return Tokens.anim.durations.expressiveDefaultSpatial;
|
||||||
if (type == AnchorAnim.SlowSpatial)
|
if (type == AnchorAnim.SlowSpatial)
|
||||||
return Tokens.anim.durations.large;
|
return Tokens.anim.durations.expressiveSlowSpatial;
|
||||||
|
|
||||||
const types = ["small", "normal", "large", "extraLarge"];
|
const types = ["small", "normal", "large", "extraLarge"];
|
||||||
const idx = type % 4;
|
const idx = type % 4; // 0-7 are the 4 standard types
|
||||||
return Tokens.anim.durations[types[idx]];
|
return Tokens.anim.durations[types[idx]];
|
||||||
}
|
}
|
||||||
easing.bezierCurve: {
|
easing: {
|
||||||
if (type == AnchorAnim.FastSpatial)
|
if (type == AnchorAnim.FastSpatial)
|
||||||
return Tokens.anim.curves.expressiveFastSpatial;
|
return Tokens.anim.expressiveFastSpatial;
|
||||||
if (type == AnchorAnim.DefaultSpatial)
|
if (type == AnchorAnim.DefaultSpatial)
|
||||||
return Tokens.anim.curves.expressiveDefaultSpatial;
|
return Tokens.anim.expressiveDefaultSpatial;
|
||||||
if (type == AnchorAnim.SlowSpatial)
|
if (type == AnchorAnim.SlowSpatial)
|
||||||
return Tokens.anim.curves.expressiveSlowSpatial;
|
return Tokens.anim.expressiveSlowSpatial;
|
||||||
|
|
||||||
if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge)
|
if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge)
|
||||||
return Tokens.anim.curves.standard;
|
return Tokens.anim.standard;
|
||||||
if (type >= AnchorAnim.EmphasizedSmall && type <= AnchorAnim.EmphasizedExtraLarge)
|
if (type >= AnchorAnim.EmphasizedSmall && type <= AnchorAnim.EmphasizedExtraLarge)
|
||||||
return Tokens.anim.curves.emphasized;
|
return Tokens.anim.emphasized;
|
||||||
|
|
||||||
return Tokens.anim.curves.expressiveDefaultSpatial;
|
return Tokens.anim.expressiveDefaultSpatial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -30,34 +30,34 @@ NumberAnimation {
|
|||||||
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.large;
|
return Tokens.anim.durations.expressiveSlowSpatial;
|
||||||
if (type === Anim.FastEffects)
|
if (type === Anim.FastEffects)
|
||||||
return Tokens.anim.durations.expressiveFastEffects;
|
return Tokens.anim.durations.expressiveFastEffects;
|
||||||
if (type === Anim.DefaultEffects)
|
if (type === Anim.DefaultEffects)
|
||||||
return Tokens.anim.durations.expressiveEffects;
|
return Tokens.anim.durations.expressiveDefaultEffects;
|
||||||
if (type === Anim.SlowEffects)
|
if (type === Anim.SlowEffects)
|
||||||
return Tokens.anim.durations.expressiveSlowEffects;
|
return Tokens.anim.durations.expressiveSlowEffects;
|
||||||
|
|
||||||
const types = ["small", "normal", "large", "extraLarge"];
|
const types = ["small", "normal", "large", "extraLarge"];
|
||||||
const idx = type % 4;
|
const idx = type % 4; // 0-7 are the 4 standard types
|
||||||
return Tokens.anim.durations[types[idx]];
|
return Tokens.anim.durations[types[idx]];
|
||||||
}
|
}
|
||||||
easing.bezierCurve: {
|
easing: {
|
||||||
if (type === Anim.FastSpatial)
|
if (type === Anim.FastSpatial)
|
||||||
return Tokens.anim.curves.expressiveFastSpatial;
|
return Tokens.anim.expressiveFastSpatial;
|
||||||
if (type === Anim.DefaultSpatial)
|
if (type === Anim.DefaultSpatial)
|
||||||
return Tokens.anim.curves.expressiveDefaultSpatial;
|
return Tokens.anim.expressiveDefaultSpatial;
|
||||||
if (type === Anim.SlowSpatial)
|
if (type === Anim.SlowSpatial)
|
||||||
return Tokens.anim.curves.expressiveSlowSpatial;
|
return Tokens.anim.expressiveSlowSpatial;
|
||||||
if (type === Anim.FastEffects)
|
if (type === Anim.FastEffects)
|
||||||
return Tokens.anim.curves.expressiveFastEffects;
|
return Tokens.anim.expressiveFastEffects;
|
||||||
if (type === Anim.DefaultEffects)
|
if (type === Anim.DefaultEffects)
|
||||||
return Tokens.anim.curves.expressiveDefaultEffects;
|
return Tokens.anim.expressiveDefaultEffects;
|
||||||
if (type === Anim.SlowEffects)
|
if (type === Anim.SlowEffects)
|
||||||
return Tokens.anim.curves.expressiveSlowEffects;
|
return Tokens.anim.expressiveSlowEffects;
|
||||||
|
|
||||||
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
||||||
return Tokens.anim.curves.emphasized;
|
return Tokens.anim.emphasized;
|
||||||
return Tokens.anim.curves.standard;
|
return Tokens.anim.standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ Slider {
|
|||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.normal / 2
|
duration: Tokens.anim.durations.normal / 2
|
||||||
easing.bezierCurve: Tokens.anim.curves.standardAccel
|
easing: Tokens.anim.standardAccel
|
||||||
property: "scale"
|
property: "scale"
|
||||||
target: icon
|
target: icon
|
||||||
to: 0
|
to: 0
|
||||||
@@ -119,7 +119,7 @@ Slider {
|
|||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.normal / 2
|
duration: Tokens.anim.durations.normal / 2
|
||||||
easing.bezierCurve: Tokens.anim.curves.standardDecel
|
easing: Tokens.anim.standardDecel
|
||||||
property: "scale"
|
property: "scale"
|
||||||
target: icon
|
target: icon
|
||||||
to: 1
|
to: 1
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
@@ -36,7 +37,7 @@ CustomRect {
|
|||||||
readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor
|
readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor
|
||||||
property real padding
|
property real padding
|
||||||
readonly property alias pressed: stateLayer.pressed
|
readonly property alias pressed: stateLayer.pressed
|
||||||
property real pressedRadius: Tokens.rounding.smallest
|
property real pressedRadius: Tokens.rounding.small
|
||||||
readonly property alias radiusAnim: radiusAnim
|
readonly property alias radiusAnim: radiusAnim
|
||||||
property bool radiusMorph: true
|
property bool radiusMorph: true
|
||||||
property alias shapeMorph: stateLayer.shapeMorph
|
property alias shapeMorph: stateLayer.shapeMorph
|
||||||
|
|||||||
+2
-58
@@ -2,62 +2,6 @@ import QtQuick
|
|||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
enum Type {
|
duration: Tokens.anim.durations.expressiveSlowEffects
|
||||||
StandardSmall = 0,
|
easing: Tokens.anim.expressiveSlowEffects
|
||||||
Standard,
|
|
||||||
StandardLarge,
|
|
||||||
StandardExtraLarge,
|
|
||||||
EmphasizedSmall,
|
|
||||||
Emphasized,
|
|
||||||
EmphasizedLarge,
|
|
||||||
EmphasizedExtraLarge,
|
|
||||||
FastSpatial,
|
|
||||||
DefaultSpatial,
|
|
||||||
SlowSpatial,
|
|
||||||
FastEffects,
|
|
||||||
DefaultEffects,
|
|
||||||
SlowEffects
|
|
||||||
}
|
|
||||||
|
|
||||||
property int type: CAnim.DefaultSpatial
|
|
||||||
|
|
||||||
duration: {
|
|
||||||
if (type < CAnim.StandardSmall || type > Anim.SlowEffects)
|
|
||||||
return Tokens.anim.durations.normal;
|
|
||||||
|
|
||||||
if (type === CAnim.FastSpatial)
|
|
||||||
return Tokens.anim.durations.expressiveFastSpatial;
|
|
||||||
if (type === CAnim.DefaultSpatial)
|
|
||||||
return Tokens.anim.durations.expressiveDefaultSpatial;
|
|
||||||
if (type === CAnim.SlowSpatial)
|
|
||||||
return Tokens.anim.durations.large;
|
|
||||||
if (type === CAnim.FastEffects)
|
|
||||||
return Tokens.anim.durations.expressiveFastEffects;
|
|
||||||
if (type === CAnim.DefaultEffects)
|
|
||||||
return Tokens.anim.durations.expressiveEffects;
|
|
||||||
if (type === CAnim.SlowEffects)
|
|
||||||
return Tokens.anim.durations.expressiveSlowEffects;
|
|
||||||
|
|
||||||
const types = ["small", "normal", "large", "extraLarge"];
|
|
||||||
const idx = type % 4;
|
|
||||||
return Tokens.anim.durations[types[idx]];
|
|
||||||
}
|
|
||||||
easing.bezierCurve: {
|
|
||||||
if (type === CAnim.FastSpatial)
|
|
||||||
return Tokens.anim.curves.expressiveFastSpatial;
|
|
||||||
if (type === CAnim.DefaultSpatial)
|
|
||||||
return Tokens.anim.curves.expressiveDefaultSpatial;
|
|
||||||
if (type === CAnim.SlowSpatial)
|
|
||||||
return Tokens.anim.curves.expressiveSlowSpatial;
|
|
||||||
if (type === CAnim.FastEffects)
|
|
||||||
return Tokens.anim.curves.expressiveFastEffects;
|
|
||||||
if (type === CAnim.DefaultEffects)
|
|
||||||
return Tokens.anim.curves.expressiveDefaultEffects;
|
|
||||||
if (type === CAnim.SlowEffects)
|
|
||||||
return Tokens.anim.curves.expressiveSlowEffects;
|
|
||||||
|
|
||||||
if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
|
||||||
return Tokens.anim.curves.emphasized;
|
|
||||||
return Tokens.anim.curves.standard;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ BusyIndicator {
|
|||||||
property real implicitSize: Tokens.font.size.normal * 3
|
property real implicitSize: Tokens.font.size.normal * 3
|
||||||
property real internalStrokeWidth: strokeWidth
|
property real internalStrokeWidth: strokeWidth
|
||||||
readonly property alias progress: manager.progress
|
readonly property alias progress: manager.progress
|
||||||
property real strokeWidth: Tokens.padding.small * 0.8
|
property real strokeWidth: Tokens.padding.extraSmall * 0.8
|
||||||
property alias type: manager.indeterminateAnimationType
|
property alias type: manager.indeterminateAnimationType
|
||||||
|
|
||||||
implicitHeight: implicitSize
|
implicitHeight: implicitSize
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Item {
|
|||||||
readonly property real size: Math.min(width, height)
|
readonly property real size: Math.min(width, height)
|
||||||
property int spacing: Tokens.spacing.small
|
property int spacing: Tokens.spacing.small
|
||||||
property int startAngle: -90
|
property int startAngle: -90
|
||||||
property int strokeWidth: Tokens.padding.small
|
property int strokeWidth: Tokens.padding.extraSmall
|
||||||
property int sweepAngle: 360
|
property int sweepAngle: 360
|
||||||
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
|
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
|
||||||
property real value
|
property real value
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ CheckBox {
|
|||||||
color: Colors.palette.m3surfaceVariant
|
color: Colors.palette.m3surfaceVariant
|
||||||
implicitHeight: control.checkHeight
|
implicitHeight: control.checkHeight
|
||||||
implicitWidth: control.checkWidth
|
implicitWidth: control.checkWidth
|
||||||
radius: Tokens.rounding.smallest / 2
|
radius: Tokens.rounding.small / 2
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ Slider {
|
|||||||
|
|
||||||
property bool animateWave
|
property bool animateWave
|
||||||
property color bgColor: enabled ? Colors.palette.m3secondaryContainer : Qt.alpha(Colors.palette.m3onSurface, 0.1)
|
property color bgColor: enabled ? Colors.palette.m3secondaryContainer : Qt.alpha(Colors.palette.m3onSurface, 0.1)
|
||||||
|
readonly property bool dragging: mouse.pressed
|
||||||
property color fgColor: enabled ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3onSurface, 0.38)
|
property color fgColor: enabled ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3onSurface, 0.38)
|
||||||
property real filledWidth
|
property real filledWidth
|
||||||
property alias inset: inset
|
property alias inset: inset
|
||||||
property color insetColor: enabled ? (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) : Colors.palette.m3onSurface
|
property color insetColor: enabled ? (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) : Colors.palette.m3onSurface
|
||||||
property string insetIcon: ""
|
property string insetIcon: ""
|
||||||
|
property bool interactionOnMove: true
|
||||||
property real pos: visualPosition
|
property real pos: visualPosition
|
||||||
property int radius: Tokens.rounding.small
|
property int radius: Tokens.rounding.small
|
||||||
property int waveDuration: 1000
|
property int waveDuration: 1000
|
||||||
@@ -186,7 +188,8 @@ Slider {
|
|||||||
|
|
||||||
onPositionChanged: e => {
|
onPositionChanged: e => {
|
||||||
dragMovement = (e.x - pressStartX) / width;
|
dragMovement = (e.x - pressStartX) / width;
|
||||||
root.interaction(posBinding.value);
|
if (root.interactionOnMove)
|
||||||
|
root.interaction(posBinding.value);
|
||||||
}
|
}
|
||||||
onPressed: e => {
|
onPressed: e => {
|
||||||
widthBehavior.enabled = false;
|
widthBehavior.enabled = false;
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ DoubleSpinBox {
|
|||||||
horizontalAlignment: TextField.AlignHCenter
|
horizontalAlignment: TextField.AlignHCenter
|
||||||
implicitWidth: 65
|
implicitWidth: 65
|
||||||
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||||
leftPadding: Tokens.padding.larger
|
leftPadding: Tokens.padding.small
|
||||||
readOnly: !root.editable
|
readOnly: !root.editable
|
||||||
rightPadding: Tokens.padding.larger
|
rightPadding: Tokens.padding.small
|
||||||
text: root.textFromValue(root.value, root.locale)
|
text: root.textFromValue(root.value, root.locale)
|
||||||
validator: root.validator
|
validator: root.validator
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import ZShell.Config
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property alias active: splitButton.active
|
|
||||||
property alias buttonAlias: splitButton
|
|
||||||
property alias expanded: splitButton.expanded
|
|
||||||
property int expandedZ: 100
|
|
||||||
required property string label
|
|
||||||
property alias menuItems: splitButton.menuItems
|
|
||||||
property bool shouldBeActive: true
|
|
||||||
property alias type: splitButton.type
|
|
||||||
|
|
||||||
signal selected(item: MenuItem)
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
clip: false
|
|
||||||
implicitHeight: row.implicitHeight + Tokens.padding.smaller * 2
|
|
||||||
opacity: shouldBeActive ? 1 : 0
|
|
||||||
scale: shouldBeActive ? 1 : 0.8
|
|
||||||
z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Behavior on scale {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: row
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Tokens.padding.small
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Tokens.spacing.normal
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: root.enabled ? Colors.palette.m3onSurface : Colors.palette.m3onSurfaceVariant
|
|
||||||
font.pointSize: Tokens.font.size.larger
|
|
||||||
text: root.label
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomSplitButton {
|
|
||||||
id: splitButton
|
|
||||||
|
|
||||||
enabled: root.enabled
|
|
||||||
type: CustomSplitButton.Filled
|
|
||||||
z: 2
|
|
||||||
|
|
||||||
menu.onItemSelected: item => {
|
|
||||||
root.selected(item);
|
|
||||||
}
|
|
||||||
stateLayer.onClicked: {
|
|
||||||
splitButton.expanded = !splitButton.expanded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,8 +13,12 @@ Switch {
|
|||||||
implicitWidth: implicitIndicatorWidth
|
implicitWidth: implicitIndicatorWidth
|
||||||
|
|
||||||
indicator: CustomRect {
|
indicator: CustomRect {
|
||||||
color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer)
|
color: {
|
||||||
implicitHeight: Tokens.font.size.medium + Tokens.padding.normal * 2
|
if (!root.enabled)
|
||||||
|
return root.checked ? Qt.alpha(Colors.palette.m3onSurface, 0.12) : Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.38);
|
||||||
|
return root.checked ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer);
|
||||||
|
}
|
||||||
|
implicitHeight: 14 + Tokens.padding.small * 2
|
||||||
implicitWidth: implicitHeight * 1.7
|
implicitWidth: implicitHeight * 1.7
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
@@ -22,7 +26,11 @@ Switch {
|
|||||||
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight
|
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: root.checked && root.enabled ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1)
|
color: {
|
||||||
|
if (!root.enabled)
|
||||||
|
return root.checked ? Qt.alpha(Colors.palette.m3surface, 0.7) : Qt.alpha(Colors.palette.m3onSurface, 0.12);
|
||||||
|
return root.checked ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1);
|
||||||
|
}
|
||||||
implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
|
implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
|
||||||
implicitWidth: nonAnimWidth
|
implicitWidth: nonAnimWidth
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
@@ -92,7 +100,7 @@ Switch {
|
|||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
height: parent.implicitHeight - Tokens.padding.larger
|
height: parent.implicitHeight - Tokens.padding.medium
|
||||||
preferredRendererType: Shape.CurveRenderer
|
preferredRendererType: Shape.CurveRenderer
|
||||||
width: height
|
width: height
|
||||||
|
|
||||||
@@ -114,12 +122,16 @@ Switch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ShapePath {
|
ShapePath {
|
||||||
capStyle: ShapePath.RoundCap
|
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
||||||
fillColor: "transparent"
|
fillColor: "transparent"
|
||||||
startX: icon.start1.x
|
startX: icon.start1.x
|
||||||
startY: icon.start1.y
|
startY: icon.start1.y
|
||||||
strokeColor: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest
|
strokeColor: {
|
||||||
strokeWidth: Tokens.font.size.larger * 0.15
|
if (!root.enabled)
|
||||||
|
return root.checked ? Colors.palette.m3outline : Colors.palette.m3surfaceContainer;
|
||||||
|
return root.checked ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest;
|
||||||
|
}
|
||||||
|
strokeWidth: 16 * 0.15
|
||||||
|
|
||||||
Behavior on strokeColor {
|
Behavior on strokeColor {
|
||||||
CAnim {
|
CAnim {
|
||||||
@@ -153,6 +165,6 @@ Switch {
|
|||||||
|
|
||||||
component PropAnim: PropertyAnimation {
|
component PropAnim: PropertyAnimation {
|
||||||
duration: Tokens.anim.durations.expressiveFastSpatial
|
duration: Tokens.anim.durations.expressiveFastSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
easing: Tokens.anim.expressiveFastSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,8 +129,8 @@ TextFieldBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AnchorAnim {
|
AnchorAnim {
|
||||||
duration: Tokens.anim.durations.expressiveEffects
|
duration: Tokens.anim.durations.expressiveDefaultEffects
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
|
easing: Tokens.anim.expressiveDefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ TextFieldBase {
|
|||||||
|
|
||||||
active: root.leadingIcon
|
active: root.leadingIcon
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Tokens.padding.normal
|
anchors.leftMargin: Tokens.padding.small
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
sourceComponent: MaterialIcon {
|
sourceComponent: MaterialIcon {
|
||||||
@@ -154,7 +154,7 @@ TextFieldBase {
|
|||||||
|
|
||||||
active: root.trailingIcon
|
active: root.trailingIcon
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Tokens.padding.normal
|
anchors.rightMargin: Tokens.padding.small
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
sourceComponent: MaterialIcon {
|
sourceComponent: MaterialIcon {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ ButtonBase {
|
|||||||
return Colors.palette.m3onPrimary;
|
return Colors.palette.m3onPrimary;
|
||||||
return type === IconButton.Tonal ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurfaceVariant;
|
return type === IconButton.Tonal ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurfaceVariant;
|
||||||
}
|
}
|
||||||
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small
|
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: label
|
id: label
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ ButtonBase {
|
|||||||
return Colors.palette.m3primary;
|
return Colors.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
|
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
|
||||||
}
|
}
|
||||||
horizontalPadding: Tokens.padding.larger
|
horizontalPadding: Tokens.padding.small
|
||||||
implicitHeight: row.implicitHeight + verticalPadding * 2
|
implicitHeight: row.implicitHeight + verticalPadding * 2
|
||||||
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
||||||
inactiveColor: {
|
inactiveColor: {
|
||||||
@@ -32,7 +32,7 @@ ButtonBase {
|
|||||||
return Colors.palette.m3primary;
|
return Colors.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
|
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
|
||||||
}
|
}
|
||||||
verticalPadding: Tokens.padding.small
|
verticalPadding: Tokens.padding.extraSmall
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: row
|
id: row
|
||||||
|
|||||||
+148
-130
@@ -18,13 +18,14 @@ Item {
|
|||||||
property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
|
property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
|
||||||
property int leftFadeWidth: 28
|
property int leftFadeWidth: 28
|
||||||
property bool marqueeEnabled: true
|
property bool marqueeEnabled: true
|
||||||
readonly property bool overflowing: metrics.width > root.width
|
readonly property bool overflowing: metrics.width > content.width
|
||||||
property int pauseMs: 1200
|
property int pauseMs: 1200
|
||||||
property real pixelsPerSecond: 40
|
property real pixelsPerSecond: 40
|
||||||
property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle
|
property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle
|
||||||
property int rightFadeWidth: 28
|
property int rightFadeWidth: 28
|
||||||
property bool sliding: false
|
property bool sliding: false
|
||||||
property alias text: elideText.text
|
property alias text: elideText.text
|
||||||
|
property bool vertical: false
|
||||||
|
|
||||||
function durationForDistance(px): int {
|
function durationForDistance(px): int {
|
||||||
return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000));
|
return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000));
|
||||||
@@ -41,8 +42,9 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clip: true
|
clip: false
|
||||||
implicitHeight: elideText.implicitHeight
|
implicitHeight: vertical ? elideText.implicitWidth : elideText.implicitHeight
|
||||||
|
implicitWidth: vertical ? elideText.implicitHeight : elideText.implicitWidth
|
||||||
|
|
||||||
Behavior on leftFadeStrength {
|
Behavior on leftFadeStrength {
|
||||||
Anim {
|
Anim {
|
||||||
@@ -53,171 +55,187 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onHeightChanged: resetMarquee()
|
||||||
onTextChanged: resetMarquee()
|
onTextChanged: resetMarquee()
|
||||||
|
onVerticalChanged: resetMarquee()
|
||||||
onVisibleChanged: if (!visible)
|
onVisibleChanged: if (!visible)
|
||||||
resetMarquee()
|
resetMarquee()
|
||||||
onWidthChanged: resetMarquee()
|
onWidthChanged: resetMarquee()
|
||||||
|
|
||||||
TextMetrics {
|
|
||||||
id: metrics
|
|
||||||
|
|
||||||
font: elideText.font
|
|
||||||
text: elideText.text
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: elideText
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
animate: root.animate
|
|
||||||
animateProp: "scale,opacity"
|
|
||||||
color: root.color
|
|
||||||
elide: Text.ElideNone
|
|
||||||
visible: !root.overflowing
|
|
||||||
width: root.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: marqueeViewport
|
id: content
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.centerIn: parent
|
||||||
clip: true
|
height: root.vertical ? root.width : root.height
|
||||||
layer.enabled: true
|
width: root.vertical ? root.height : root.width
|
||||||
visible: root.overflowing
|
|
||||||
|
|
||||||
layer.effect: OpacityMask {
|
transform: Rotation {
|
||||||
maskSource: rightFadeMask
|
angle: root.vertical ? -90 : 0
|
||||||
|
origin.x: content.width / 2
|
||||||
|
origin.y: content.height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: metrics
|
||||||
|
|
||||||
|
font: elideText.font
|
||||||
|
text: elideText.text
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: elideText
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
animate: root.animate
|
||||||
|
animateProp: "scale,opacity"
|
||||||
|
color: root.color
|
||||||
|
elide: Text.ElideNone
|
||||||
|
visible: !root.overflowing
|
||||||
|
width: content.width
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: strip
|
id: marqueeViewport
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.fill: parent
|
||||||
height: t1.implicitHeight
|
clip: false
|
||||||
width: t1.width + root.gap + t2.width
|
layer.enabled: true
|
||||||
x: 0
|
visible: root.overflowing
|
||||||
|
|
||||||
CustomText {
|
layer.effect: OpacityMask {
|
||||||
id: t1
|
maskSource: rightFadeMask
|
||||||
|
|
||||||
animate: root.animate
|
|
||||||
animateProp: "opacity"
|
|
||||||
color: root.color
|
|
||||||
font.pointSize: elideText.font.pointSize
|
|
||||||
text: elideText.text
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomText {
|
Item {
|
||||||
id: t2
|
id: strip
|
||||||
|
|
||||||
animate: root.animate
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
animateProp: "opacity"
|
height: t1.implicitHeight
|
||||||
color: root.color
|
width: t1.width + root.gap + t2.width
|
||||||
font.pointSize: elideText.font.pointSize
|
x: 0
|
||||||
text: t1.text
|
|
||||||
x: t1.width + root.gap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SequentialAnimation {
|
CustomText {
|
||||||
id: marqueeAnim
|
id: t1
|
||||||
|
|
||||||
running: false
|
animate: root.animate
|
||||||
|
animateProp: "opacity"
|
||||||
|
color: root.color
|
||||||
|
font.pointSize: elideText.font.pointSize
|
||||||
|
text: elideText.text
|
||||||
|
}
|
||||||
|
|
||||||
onFinished: pauseTimer.restart()
|
CustomText {
|
||||||
|
id: t2
|
||||||
|
|
||||||
ScriptAction {
|
animate: root.animate
|
||||||
script: {
|
animateProp: "opacity"
|
||||||
root.sliding = true;
|
color: root.color
|
||||||
root.leftFadeEnabled = true;
|
font.pointSize: elideText.font.pointSize
|
||||||
|
text: t1.text
|
||||||
|
x: t1.width + root.gap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Anim {
|
SequentialAnimation {
|
||||||
duration: root.durationForDistance(t1.width)
|
id: marqueeAnim
|
||||||
easing.bezierCurve: Easing.Linear
|
|
||||||
easing.type: Easing.Linear
|
|
||||||
from: 0
|
|
||||||
property: "x"
|
|
||||||
target: strip
|
|
||||||
to: -t1.width
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptAction {
|
running: false
|
||||||
script: {
|
|
||||||
root.leftFadeEnabled = false;
|
onFinished: pauseTimer.restart()
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.sliding = true;
|
||||||
|
root.leftFadeEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: root.durationForDistance(t1.width)
|
||||||
|
easing.bezierCurve: Easing.Linear
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
from: 0
|
||||||
|
property: "x"
|
||||||
|
target: strip
|
||||||
|
to: -t1.width
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.leftFadeEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: root.durationForDistance(root.gap)
|
||||||
|
easing.bezierCurve: Easing.Linear
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
from: -t1.width
|
||||||
|
property: "x"
|
||||||
|
target: strip
|
||||||
|
to: -(t1.width + root.gap)
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
root.sliding = false;
|
||||||
|
strip.x = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Anim {
|
Timer {
|
||||||
duration: root.durationForDistance(root.gap)
|
id: pauseTimer
|
||||||
easing.bezierCurve: Easing.Linear
|
|
||||||
easing.type: Easing.Linear
|
|
||||||
from: -t1.width
|
|
||||||
property: "x"
|
|
||||||
target: strip
|
|
||||||
to: -(t1.width + root.gap)
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptAction {
|
interval: root.pauseMs
|
||||||
script: {
|
repeat: false
|
||||||
root.sliding = false;
|
running: true
|
||||||
strip.x = 0;
|
|
||||||
|
onTriggered: {
|
||||||
|
if (root.marqueeEnabled)
|
||||||
|
marqueeAnim.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Rectangle {
|
||||||
id: pauseTimer
|
id: rightFadeMask
|
||||||
|
|
||||||
interval: root.pauseMs
|
readonly property real fadeStartPos: {
|
||||||
repeat: false
|
const w = Math.max(1, width);
|
||||||
running: true
|
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if (root.marqueeEnabled)
|
|
||||||
marqueeAnim.start();
|
|
||||||
}
|
}
|
||||||
}
|
readonly property real leftFadeEndPos: {
|
||||||
}
|
const w = Math.max(1, width);
|
||||||
|
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
|
||||||
Rectangle {
|
|
||||||
id: rightFadeMask
|
|
||||||
|
|
||||||
readonly property real fadeStartPos: {
|
|
||||||
const w = Math.max(1, width);
|
|
||||||
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
|
|
||||||
}
|
|
||||||
readonly property real leftFadeEndPos: {
|
|
||||||
const w = Math.max(1, width);
|
|
||||||
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.fill: marqueeViewport
|
|
||||||
layer.enabled: true
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
gradient: Gradient {
|
|
||||||
orientation: Gradient.Horizontal
|
|
||||||
|
|
||||||
GradientStop {
|
|
||||||
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
|
|
||||||
position: 0.0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GradientStop {
|
anchors.fill: marqueeViewport
|
||||||
color: Qt.rgba(1, 1, 1, 1.0)
|
layer.enabled: true
|
||||||
position: rightFadeMask.leftFadeEndPos
|
visible: false
|
||||||
}
|
|
||||||
|
|
||||||
GradientStop {
|
gradient: Gradient {
|
||||||
color: Qt.rgba(1, 1, 1, 1.0)
|
orientation: Gradient.Horizontal
|
||||||
position: rightFadeMask.fadeStartPos
|
|
||||||
}
|
|
||||||
|
|
||||||
GradientStop {
|
GradientStop {
|
||||||
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
|
color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength)
|
||||||
position: 1.0
|
position: 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0)
|
||||||
|
position: rightFadeMask.leftFadeEndPos
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0)
|
||||||
|
position: rightFadeMask.fadeStartPos
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
|
||||||
|
position: 1.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -78,7 +78,7 @@ MouseArea {
|
|||||||
implicitHeight: column.implicitHeight + column.anchors.margins * 2
|
implicitHeight: column.implicitHeight + column.anchors.margins * 2
|
||||||
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
|
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
|
||||||
level: 2
|
level: 2
|
||||||
radius: Tokens.rounding.medium
|
radius: Tokens.rounding.large
|
||||||
x: {
|
x: {
|
||||||
watcher.transform;
|
watcher.transform;
|
||||||
const item = root.attachTo;
|
const item = root.attachTo;
|
||||||
@@ -126,15 +126,15 @@ MouseArea {
|
|||||||
CustomRect {
|
CustomRect {
|
||||||
id: item
|
id: item
|
||||||
|
|
||||||
readonly property bool active: modelData === root.active
|
readonly property bool active: modelData === root?.active
|
||||||
required property int index
|
required property int index
|
||||||
required property MenuItem modelData
|
required property MenuItem modelData
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: Qt.alpha(Colors.palette.m3tertiaryContainer, active ? 1 : 0)
|
color: Qt.alpha(Colors.palette.m3tertiaryContainer, active ? 1 : 0)
|
||||||
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.larger * 2
|
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.medium * 2
|
||||||
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.larger * 2
|
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.medium * 2
|
||||||
radius: Tokens.rounding.small
|
radius: menu.radius - column.anchors.margins
|
||||||
|
|
||||||
Behavior on radius {
|
Behavior on radius {
|
||||||
Anim {
|
Anim {
|
||||||
@@ -157,25 +157,25 @@ MouseArea {
|
|||||||
id: menuOptionRow
|
id: menuOptionRow
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.larger
|
anchors.margins: Tokens.padding.medium
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
|
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
|
||||||
text: item.modelData.icon
|
text: item.modelData?.icon ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
|
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
|
||||||
text: item.modelData.text
|
text: item.modelData?.text ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
active: item.modelData.trailingIcon.length > 0
|
active: item.modelData?.trailingIcon.length > 0
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ TextFieldBase {
|
|||||||
id: clearIcon
|
id: clearIcon
|
||||||
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Tokens.padding.larger
|
anchors.rightMargin: Tokens.padding.small
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
enabled: root.text
|
enabled: root.text
|
||||||
icon: "clear"
|
icon: "clear"
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ Row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property alias active: menu.active
|
property alias active: menu.active
|
||||||
property color color: type == CustomSplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
|
property color color: type == SplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
|
||||||
property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
|
property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
|
||||||
property color disabledTextColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
|
property color disabledTextColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
|
||||||
readonly property alias expandBtn: expandBtn
|
readonly property alias expandBtn: expandBtn
|
||||||
property alias expanded: menu.expanded
|
property alias expanded: menu.expanded
|
||||||
property string fallbackIcon
|
property string fallbackIcon
|
||||||
property string fallbackText
|
property string fallbackText
|
||||||
property real horizontalPadding: Tokens.padding.larger
|
property real horizontalPadding: Tokens.padding.medium
|
||||||
readonly property alias iconLabel: iconLabel
|
readonly property alias iconLabel: iconLabel
|
||||||
readonly property alias label: label
|
readonly property alias label: label
|
||||||
readonly property alias menu: menu
|
readonly property alias menu: menu
|
||||||
@@ -27,20 +27,20 @@ Row {
|
|||||||
property bool menuOnTop
|
property bool menuOnTop
|
||||||
property real minLeftWidth
|
property real minLeftWidth
|
||||||
readonly property alias stateLayer: stateLayer
|
readonly property alias stateLayer: stateLayer
|
||||||
property color textColor: type == CustomSplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer
|
property color textColor: type == SplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer
|
||||||
readonly property alias textRow: textRow
|
readonly property alias textRow: textRow
|
||||||
property int type: CustomSplitButton.Filled
|
property int type: SplitButton.Filled
|
||||||
property real verticalPadding: Tokens.padding.small
|
property real verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
spacing: Math.floor(Tokens.spacing.extraSmall)
|
spacing: Math.floor(Tokens.spacing.extraSmall / 2)
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
bottomRightRadius: Tokens.rounding.small / 2
|
bottomRightRadius: Tokens.rounding.medium / 2
|
||||||
color: !root.enabled ? root.disabledColor : root.color
|
color: !root.enabled ? root.disabledColor : root.color
|
||||||
implicitHeight: expandBtn.implicitHeight
|
implicitHeight: expandBtn.implicitHeight
|
||||||
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
|
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
|
||||||
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
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
id: stateLayer
|
id: stateLayer
|
||||||
@@ -92,7 +92,7 @@ Row {
|
|||||||
CustomRect {
|
CustomRect {
|
||||||
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
|
||||||
|
|
||||||
bottomLeftRadius: rad
|
bottomLeftRadius: rad
|
||||||
color: !root.enabled ? root.disabledColor : root.color
|
color: !root.enabled ? root.disabledColor : root.color
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import ZShell
|
import ZShell
|
||||||
import ZShell.Components
|
|
||||||
import qs.Helpers
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Helpers
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -81,7 +80,7 @@ MouseArea {
|
|||||||
|
|
||||||
alwaysRunToEnd: true
|
alwaysRunToEnd: true
|
||||||
duration: Tokens.anim.durations.expressiveSlowEffects * 2
|
duration: Tokens.anim.durations.expressiveSlowEffects * 2
|
||||||
easing.bezierCurve: Tokens.anim.curves.standard
|
easing: Tokens.anim.standard
|
||||||
property: "circleRadius"
|
property: "circleRadius"
|
||||||
target: root
|
target: root
|
||||||
to: root.endRadius
|
to: root.endRadius
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ ButtonBase {
|
|||||||
return Colors.palette.m3primary;
|
return Colors.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
|
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
|
||||||
}
|
}
|
||||||
horizontalPadding: Tokens.padding.normal
|
horizontalPadding: Tokens.padding.small
|
||||||
implicitHeight: label.implicitHeight + verticalPadding * 2
|
implicitHeight: label.implicitHeight + verticalPadding * 2
|
||||||
implicitWidth: label.implicitWidth + horizontalPadding * 2
|
implicitWidth: label.implicitWidth + horizontalPadding * 2
|
||||||
inactiveColor: {
|
inactiveColor: {
|
||||||
@@ -29,7 +29,7 @@ ButtonBase {
|
|||||||
return Colors.palette.m3primary;
|
return Colors.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
|
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
|
||||||
}
|
}
|
||||||
verticalPadding: Tokens.padding.small
|
verticalPadding: Tokens.padding.extraSmall
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
id: label
|
id: label
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ TextField {
|
|||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
implicitHeight: root.cursorRectangle.height
|
implicitHeight: root.cursorRectangle.height
|
||||||
implicitWidth: 1.5
|
implicitWidth: 1.5
|
||||||
radius: Tokens.rounding.large
|
radius: Tokens.rounding.largeIncreased
|
||||||
x: root.cursorRectangle.x
|
x: root.cursorRectangle.x
|
||||||
y: root.cursorRectangle.y
|
y: root.cursorRectangle.y
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ CustomRect {
|
|||||||
return Colors.palette.m3errorContainer;
|
return Colors.palette.m3errorContainer;
|
||||||
return Colors.palette.m3surface;
|
return Colors.palette.m3surface;
|
||||||
}
|
}
|
||||||
implicitHeight: layout.implicitHeight + Tokens.padding.smaller * 2
|
implicitHeight: layout.implicitHeight + Tokens.padding.small * 2
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
Behavior on border.color {
|
Behavior on border.color {
|
||||||
CAnim {
|
CAnim {
|
||||||
@@ -52,10 +52,10 @@ CustomRect {
|
|||||||
id: layout
|
id: layout
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Tokens.padding.normal
|
anchors.leftMargin: Tokens.padding.small
|
||||||
anchors.margins: Tokens.padding.smaller
|
anchors.margins: Tokens.padding.small
|
||||||
anchors.rightMargin: Tokens.padding.normal
|
anchors.rightMargin: Tokens.padding.small
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
color: {
|
color: {
|
||||||
@@ -67,9 +67,9 @@ CustomRect {
|
|||||||
return Colors.palette.m3error;
|
return Colors.palette.m3error;
|
||||||
return Colors.palette.m3surfaceContainerHigh;
|
return Colors.palette.m3surfaceContainerHigh;
|
||||||
}
|
}
|
||||||
implicitHeight: icon.implicitHeight + Tokens.padding.smaller * 2
|
implicitHeight: icon.implicitHeight + Tokens.padding.small * 2
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: icon
|
id: icon
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Item {
|
|||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.normal * 2
|
implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.small * 2
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
@@ -82,7 +82,7 @@ Item {
|
|||||||
Behavior on anchors.bottomMargin {
|
Behavior on anchors.bottomMargin {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
@@ -105,7 +105,7 @@ Item {
|
|||||||
id: initAnim
|
id: initAnim
|
||||||
|
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
from: 0
|
from: 0
|
||||||
properties: "opacity,scale"
|
properties: "opacity,scale"
|
||||||
target: toast
|
target: toast
|
||||||
|
|||||||
+33
-2
@@ -11,15 +11,46 @@ Variants {
|
|||||||
|
|
||||||
required property ShellScreen modelData
|
required property ShellScreen modelData
|
||||||
|
|
||||||
|
function rebuild(): void {
|
||||||
|
loader.active = false;
|
||||||
|
loader.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
id: loader
|
||||||
|
|
||||||
|
active: true
|
||||||
|
|
||||||
|
Drawer {
|
||||||
|
screen: scope.modelData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onConfigPositionChanged(): void {
|
||||||
|
Qt.callLater(scope.rebuild);
|
||||||
|
}
|
||||||
|
|
||||||
|
target: (loader.item as Drawer)?.geometry ?? null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Drawer: Scope {
|
||||||
|
id: drawer
|
||||||
|
|
||||||
|
readonly property alias geometry: content.geometry
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
Exclusions {
|
Exclusions {
|
||||||
bar: content.bar
|
bar: content.bar
|
||||||
screen: scope.modelData
|
geometry: content.geometry
|
||||||
|
screen: drawer.screen
|
||||||
}
|
}
|
||||||
|
|
||||||
Windows {
|
Windows {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
screen: scope.modelData
|
screen: drawer.screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Modules.Bar as Bar
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Bar.BarLoader bar
|
||||||
|
readonly property real barClamped: bar.clampedExtent
|
||||||
|
readonly property real barExtent: bar.extent
|
||||||
|
readonly property bool barOnBottom: position === "bottom"
|
||||||
|
readonly property bool barOnLeft: position === "left"
|
||||||
|
readonly property bool barOnTop: position === "top"
|
||||||
|
required property string configPosition
|
||||||
|
readonly property bool horizontal: position !== "left"
|
||||||
|
readonly property string position: configPosition === "top" || configPosition === "bottom" ? configPosition : "left"
|
||||||
|
required property var win
|
||||||
|
|
||||||
|
function axisPos(x: real, y: real): real {
|
||||||
|
return horizontal ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function barContains(x: real, y: real, clamped = false): bool {
|
||||||
|
const extent = clamped ? barClamped : barExtent;
|
||||||
|
if (barOnTop)
|
||||||
|
return y < extent;
|
||||||
|
if (barOnBottom)
|
||||||
|
return y > win.height - extent;
|
||||||
|
return x < extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insetBottom(border: real, clamped = false): real {
|
||||||
|
return barOnBottom ? (clamped ? barClamped : barExtent) : border;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insetLeft(border: real, clamped = false): real {
|
||||||
|
return barOnLeft ? (clamped ? barClamped : barExtent) : border;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insetTop(border: real, clamped = false): real {
|
||||||
|
return barOnTop ? (clamped ? barClamped : barExtent) : border;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inwardDrag(dragX: real, dragY: real): real {
|
||||||
|
if (barOnTop)
|
||||||
|
return dragY;
|
||||||
|
if (barOnBottom)
|
||||||
|
return -dragY;
|
||||||
|
return dragX;
|
||||||
|
}
|
||||||
|
|
||||||
|
onConfigPositionChanged: {
|
||||||
|
if (!["left", "top", "bottom"].includes(configPosition))
|
||||||
|
console.warn(`Invalid bar position '${configPosition}', falling back to left`);
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-2
@@ -1,6 +1,7 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Components
|
import qs.Components
|
||||||
@@ -9,19 +10,24 @@ Scope {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Item bar
|
required property Item bar
|
||||||
|
required property EdgeGeometry geometry
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
|
|
||||||
ExclusionZone {
|
ExclusionZone {
|
||||||
id: top
|
id: top
|
||||||
|
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
anchors.left: true
|
||||||
|
anchors.right: true
|
||||||
anchors.top: true
|
anchors.top: true
|
||||||
exclusiveZone: root.bar.exclusiveZone
|
hasBar: root.geometry.barOnTop
|
||||||
}
|
}
|
||||||
|
|
||||||
ExclusionZone {
|
ExclusionZone {
|
||||||
id: left
|
id: left
|
||||||
|
|
||||||
anchors.left: true
|
anchors.left: true
|
||||||
|
hasBar: root.geometry.barOnLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
ExclusionZone {
|
ExclusionZone {
|
||||||
@@ -34,6 +40,7 @@ Scope {
|
|||||||
id: bottom
|
id: bottom
|
||||||
|
|
||||||
anchors.bottom: true
|
anchors.bottom: true
|
||||||
|
hasBar: root.geometry.barOnBottom
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -44,7 +51,9 @@ Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
component ExclusionZone: CustomWindow {
|
component ExclusionZone: CustomWindow {
|
||||||
exclusiveZone: Config.bar.border
|
property bool hasBar
|
||||||
|
|
||||||
|
exclusiveZone: hasBar ? root.bar.exclusiveZone : Config.bar.border
|
||||||
implicitHeight: 1
|
implicitHeight: 1
|
||||||
implicitWidth: 1
|
implicitWidth: 1
|
||||||
name: "Bar-Exclusion"
|
name: "Bar-Exclusion"
|
||||||
|
|||||||
+41
-23
@@ -3,7 +3,7 @@ import QtQuick
|
|||||||
import qs.Components
|
import qs.Components
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Modules as BarPopouts
|
import qs.Modules.Bar.Popouts
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -12,43 +12,47 @@ Item {
|
|||||||
required property real borderThickness
|
required property real borderThickness
|
||||||
property bool dashboardShortcutActive
|
property bool dashboardShortcutActive
|
||||||
required property Drawing drawing
|
required property Drawing drawing
|
||||||
|
required property EdgeGeometry geometry
|
||||||
property bool osdShortcutActive
|
property bool osdShortcutActive
|
||||||
required property Panels panels
|
required property Panels panels
|
||||||
required property BarPopouts.Wrapper popouts
|
required property Wrapper popouts
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
property bool singleGestureTriggered: false
|
property bool singleGestureTriggered: false
|
||||||
property bool utilitiesShortcutActive
|
property bool utilitiesShortcutActive
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
function inBottomPanel(panel: Item, x: real, y: real): bool {
|
function inBottomPanel(panel: Item, x: real, y: real): bool {
|
||||||
return y > root.height - panel.height - Config.bar.border && withinPanelWidth(panel, x, y);
|
const panelHeight = panel.height * (1 - (panel.offsetScale ?? 0));
|
||||||
|
return y > root.height - (panelHeight + geometry.insetBottom(borderThickness)) && withinPanelWidth(panel, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function inLeftPanel(panel: Item, x: real, y: real): bool {
|
function inLeftPanel(panel: Item, x: real, y: real): bool {
|
||||||
return x < panel.x + panel.width + Config.bar.border && withinPanelHeight(panel, x, y);
|
return x < panel.x + panel.width + geometry.insetLeft(borderThickness) && withinPanelHeight(panel, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inPopoutArea(x: real, y: real): bool {
|
||||||
|
const panel = panels.popoutsWrapper;
|
||||||
|
if (!geometry.horizontal)
|
||||||
|
return inLeftPanel(panel, x, y);
|
||||||
|
return withinPanelWidth(panel, x, y) && withinPanelHeight(panel, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function inRightPanel(panel: Item, x: real, y: real): bool {
|
function inRightPanel(panel: Item, x: real, y: real): bool {
|
||||||
return x > panel.x - Config.bar.border && withinPanelHeight(panel, x, y);
|
return x > panel.x + geometry.insetLeft(borderThickness) && withinPanelHeight(panel, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function inTopPanel(panel: Item, x: real, y: real): bool {
|
function inTopPanel(panel: Item, x: real, y: real): bool {
|
||||||
return y < bar.implicitHeight + panel.height && withinPanelWidth(panel, x, y);
|
const panelHeight = panel.height * (1 - (panel.offsetScale ?? 0));
|
||||||
}
|
return y < geometry.insetTop(borderThickness) + panelHeight && withinPanelWidth(panel, x, y);
|
||||||
|
|
||||||
function onWheel(event: WheelEvent): void {
|
|
||||||
if (event.x < bar.implicitWidth) {
|
|
||||||
bar.handleWheel(event.y, event.angleDelta);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function withinPanelHeight(panel: Item, x: real, y: real): bool {
|
function withinPanelHeight(panel: Item, x: real, y: real): bool {
|
||||||
const panelY = panel.y + bar.implicitHeight;
|
const panelY = panel.y + geometry.insetTop(borderThickness);
|
||||||
return y >= panelY && y <= panelY + panel.height;
|
return y >= panelY && y <= panelY + panel.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
function withinPanelWidth(panel: Item, x: real, y: real): bool {
|
function withinPanelWidth(panel: Item, x: real, y: real): bool {
|
||||||
const panelX = panel.x + root.borderThickness;
|
const panelX = panel.x + geometry.insetLeft(borderThickness);
|
||||||
return x >= panelX && x <= panelX + panel.width;
|
return x >= panelX && x <= panelX + panel.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +85,7 @@ Item {
|
|||||||
if (root.singleGestureTriggered)
|
if (root.singleGestureTriggered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (centroid.pressPosition.y < root.bar.implicitHeight) {
|
if (root.geometry.insetTop(root.borderThickness) > centroid.pressPosition.y) {
|
||||||
if (dragY > 20) {
|
if (dragY > 20) {
|
||||||
root.visibilities.settings = true;
|
root.visibilities.settings = true;
|
||||||
root.singleGestureTriggered = true;
|
root.singleGestureTriggered = true;
|
||||||
@@ -91,10 +95,10 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (centroid.pressPosition.y > root.screen.height - Config.bar.border && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50)
|
if (centroid.pressPosition.y > root.screen.height - root.geometry.insetBottom(root.borderThickness) && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50)
|
||||||
root.visibilities.clipboard = true;
|
root.visibilities.clipboard = true;
|
||||||
|
|
||||||
if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight && centroid.pressPosition.x > root.screen.width / 5 && !root.visibilities.launcher)
|
if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.geometry.insetTop(root.borderThickness) && centroid.pressPosition.x > root.screen.width / 5 && !root.visibilities.launcher)
|
||||||
if (dragY < -10) {
|
if (dragY < -10) {
|
||||||
root.visibilities.dock = true;
|
root.visibilities.dock = true;
|
||||||
root.singleGestureTriggered = true;
|
root.singleGestureTriggered = true;
|
||||||
@@ -158,6 +162,19 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: unhideTimer
|
||||||
|
|
||||||
|
interval: Config.bar.revealDelay
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
if (hoverHandler.hovered)
|
||||||
|
root.bar.isHovered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
id: hoverHandler
|
id: hoverHandler
|
||||||
|
|
||||||
@@ -174,7 +191,7 @@ Item {
|
|||||||
root.popouts.hasCurrent = false;
|
root.popouts.hasCurrent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.bar.autoHide)
|
if (Config.bar.autoHide || root.bar.fullscreen)
|
||||||
root.bar.isHovered = false;
|
root.bar.isHovered = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,9 +210,12 @@ Item {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!root.visibilities.bar && Config.bar.autoHide && y < root.bar.implicitHeight)
|
if (!root.visibilities.bar && Config.bar.autoHide && root.geometry.barContains(x, y, true))
|
||||||
root.bar.isHovered = true;
|
root.bar.isHovered = true;
|
||||||
|
|
||||||
|
if (root.bar.fullscreen && !root.bar.isHovered)
|
||||||
|
unhideTimer.start();
|
||||||
|
|
||||||
if (root.panels.sidebar.offsetScale === 1) {
|
if (root.panels.sidebar.offsetScale === 1) {
|
||||||
const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y);
|
const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y);
|
||||||
|
|
||||||
@@ -219,8 +239,8 @@ Item {
|
|||||||
if (Config.dock.enable && Config.dock.hoverToReveal && !root.visibilities.dock && !root.visibilities.launcher && root.inBottomPanel(root.panels.dock, x, y))
|
if (Config.dock.enable && Config.dock.hoverToReveal && !root.visibilities.dock && !root.visibilities.launcher && root.inBottomPanel(root.panels.dock, x, y))
|
||||||
root.visibilities.dock = true;
|
root.visibilities.dock = true;
|
||||||
|
|
||||||
if (y < root.bar.implicitHeight)
|
if (root.geometry.barContains(x, y))
|
||||||
root.bar.checkPopout(x);
|
root.bar.checkPopout(root.geometry.axisPos(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,8 +318,6 @@ Item {
|
|||||||
root.visibilities.sidebar = false;
|
root.visibilities.sidebar = false;
|
||||||
root.panels.popouts.hasCurrent = false;
|
root.panels.popouts.hasCurrent = false;
|
||||||
root.visibilities.launcher = false;
|
root.visibilities.launcher = false;
|
||||||
} else {
|
|
||||||
Config.save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-18
@@ -1,7 +1,7 @@
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Modules as Modules
|
import qs.Modules.Bar.Popouts as Popouts
|
||||||
import qs.Modules.Notifications as Notifications
|
import qs.Modules.Notifications as Notifications
|
||||||
import qs.Modules.Notifications.Sidebar as Sidebar
|
import qs.Modules.Notifications.Sidebar as Sidebar
|
||||||
import qs.Modules.Notifications.Sidebar.Utils as Utils
|
import qs.Modules.Notifications.Sidebar.Utils as Utils
|
||||||
@@ -27,6 +27,7 @@ Item {
|
|||||||
readonly property alias dock: dock
|
readonly property alias dock: dock
|
||||||
readonly property alias drawing: drawing
|
readonly property alias drawing: drawing
|
||||||
required property var drawingItem
|
required property var drawingItem
|
||||||
|
required property EdgeGeometry geometry
|
||||||
readonly property alias launcher: launcher
|
readonly property alias launcher: launcher
|
||||||
readonly property alias notifications: notifications
|
readonly property alias notifications: notifications
|
||||||
readonly property alias osd: osd
|
readonly property alias osd: osd
|
||||||
@@ -43,24 +44,26 @@ Item {
|
|||||||
readonly property alias utilities: utilities
|
readonly property alias utilities: utilities
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
|
anchors.bottomMargin: geometry.insetBottom(borderThickness)
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: geometry.insetLeft(borderThickness)
|
||||||
anchors.margins: borderThickness
|
anchors.margins: borderThickness
|
||||||
anchors.topMargin: bar.implicitHeight
|
anchors.topMargin: geometry.insetTop(borderThickness)
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: resourcesWrapper
|
id: resourcesWrapper
|
||||||
|
|
||||||
|
anchors.bottom: root.geometry.position === "bottom" ? parent.bottom : undefined
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: root.geometry.position !== "bottom" ? parent.top : undefined
|
||||||
clip: true
|
clip: true
|
||||||
implicitHeight: resources.implicitHeight * (1 - resources.offsetScale)
|
implicitHeight: root.geometry.horizontal ? resources.implicitHeight * (1 - resources.offsetScale) : resources.implicitHeight
|
||||||
implicitWidth: resources.implicitWidth
|
implicitWidth: root.geometry.horizontal ? resources.implicitWidth : resources.implicitWidth * (1 - resources.offsetScale)
|
||||||
|
|
||||||
Resources.Wrapper {
|
Resources.Wrapper {
|
||||||
id: resources
|
id: resources
|
||||||
|
|
||||||
anchors.left: parent.left
|
position: root.geometry.position
|
||||||
anchors.top: parent.top
|
|
||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,11 +99,11 @@ Item {
|
|||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
}
|
}
|
||||||
|
|
||||||
Modules.ClipWrapper {
|
Popouts.ClipWrapper {
|
||||||
id: popouts
|
id: popouts
|
||||||
|
|
||||||
anchors.top: parent.top
|
|
||||||
borderThickness: root.borderThickness
|
borderThickness: root.borderThickness
|
||||||
|
position: root.geometry.position
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +111,7 @@ Item {
|
|||||||
id: toasts
|
id: toasts
|
||||||
|
|
||||||
anchors.bottom: sidebar.visible ? parent.bottom : utilities.top
|
anchors.bottom: sidebar.visible ? parent.bottom : utilities.top
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.small
|
||||||
anchors.right: sidebar.left
|
anchors.right: sidebar.left
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,26 +150,26 @@ Item {
|
|||||||
|
|
||||||
property real offsetScale: dashboard.shouldBeActive ? 0 : 1
|
property real offsetScale: dashboard.shouldBeActive ? 0 : 1
|
||||||
|
|
||||||
anchors.right: parent.right
|
anchors.bottom: root.geometry.barOnLeft || root.geometry.barOnBottom ? parent.bottom : undefined
|
||||||
anchors.top: parent.top
|
anchors.left: root.geometry.barOnLeft ? parent.left : undefined
|
||||||
|
anchors.right: root.geometry.barOnLeft ? undefined : parent.right
|
||||||
|
anchors.top: root.geometry.barOnBottom || root.geometry.barOnLeft ? undefined : parent.top
|
||||||
clip: true
|
clip: true
|
||||||
implicitHeight: dashboard.implicitHeight * (1 - offsetScale)
|
implicitHeight: root.geometry.horizontal ? dashboard.implicitHeight * (1 - offsetScale) : dashboard.implicitHeight
|
||||||
implicitWidth: dashboard.implicitWidth
|
implicitWidth: root.geometry.horizontal ? dashboard.implicitWidth : dashboard.implicitWidth * (1 - offsetScale)
|
||||||
|
|
||||||
Behavior on offsetScale {
|
Behavior on offsetScale {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dashboard.Wrapper {
|
Dashboard.Wrapper {
|
||||||
id: dashboard
|
id: dashboard
|
||||||
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: (-implicitHeight - 5) * offsetScale
|
|
||||||
offsetScale: dashboardWrapper.offsetScale
|
offsetScale: dashboardWrapper.offsetScale
|
||||||
|
position: root.geometry.position
|
||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-8
@@ -7,17 +7,18 @@ import qs.Modules.Bar as Bar
|
|||||||
Region {
|
Region {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Bar.BarLoader bar
|
// required property Bar.BarLoader bar
|
||||||
readonly property real borderThickness: win.borderThickness
|
readonly property real borderThickness: win.borderThickness
|
||||||
|
required property EdgeGeometry geometry
|
||||||
readonly property alias menuPopoutRegion: menuPopoutRegion
|
readonly property alias menuPopoutRegion: menuPopoutRegion
|
||||||
required property Panels panels
|
required property Panels panels
|
||||||
required property var win
|
required property var win
|
||||||
|
|
||||||
height: win.height - bar.implicitHeight - win.borderThickness - win.dragMaskPadding * 2
|
height: win.height - geometry.insetTop(borderThickness, true) - geometry.insetBottom(borderThickness, true) - win.dragMaskPadding * 2
|
||||||
intersection: Intersection.Xor
|
intersection: Intersection.Xor
|
||||||
width: win.width - win.borderThickness * 2 - win.dragMaskPadding * 2
|
width: win.width - geometry.insetLeft(borderThickness, true) * 2 - win.dragMaskPadding * 2
|
||||||
x: win.borderThickness + win.dragMaskPadding
|
x: geometry.insetLeft(borderThickness, true) + win.dragMaskPadding
|
||||||
y: bar.implicitHeight + win.dragMaskPadding
|
y: geometry.insetTop(borderThickness, true) + win.dragMaskPadding
|
||||||
|
|
||||||
R {
|
R {
|
||||||
panel: root.panels.dashboardWrapper
|
panel: root.panels.dashboardWrapper
|
||||||
@@ -41,17 +42,21 @@ Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R {
|
R {
|
||||||
|
height: panel.height + root.geometry.insetTop(root.borderThickness)
|
||||||
panel: root.panels.notifications
|
panel: root.panels.notifications
|
||||||
|
y: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
R {
|
R {
|
||||||
height: panel.height * (1 - root.panels.utilities.offsetScale) + root.borderThickness
|
height: panel.height * (1 - root.panels.utilities.offsetScale) + root.geometry.insetBottom(root.borderThickness)
|
||||||
panel: root.panels.utilities
|
panel: root.panels.utilities
|
||||||
y: root.win.height - height
|
y: root.win.height - height
|
||||||
}
|
}
|
||||||
|
|
||||||
R {
|
R {
|
||||||
|
height: root.geometry.horizontal ? panel.height * (1 - root.panels.popoutsWrapper.offsetScale) : panel.height
|
||||||
panel: root.panels.popoutsWrapper
|
panel: root.panels.popoutsWrapper
|
||||||
|
width: root.geometry.horizontal ? panel.width : panel.width * (1 - root.panels.popoutsWrapper.offsetScale)
|
||||||
}
|
}
|
||||||
|
|
||||||
R {
|
R {
|
||||||
@@ -82,7 +87,7 @@ Region {
|
|||||||
height: panel.height
|
height: panel.height
|
||||||
intersection: Intersection.Subtract
|
intersection: Intersection.Subtract
|
||||||
width: panel.width
|
width: panel.width
|
||||||
x: panel.x + root.borderThickness
|
x: panel.x + root.geometry.insetLeft(root.borderThickness)
|
||||||
y: panel.y + root.bar.implicitHeight
|
y: panel.y + root.geometry.insetTop(root.borderThickness)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-36
@@ -33,6 +33,7 @@ CustomWindow {
|
|||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
property real fsTransitionProg: hasFullscreen ? 1 : 0
|
property real fsTransitionProg: hasFullscreen ? 1 : 0
|
||||||
|
readonly property alias geometry: geometry
|
||||||
readonly property bool hasFullscreen: {
|
readonly property bool hasFullscreen: {
|
||||||
if (hasSpecialWorkspace) {
|
if (hasSpecialWorkspace) {
|
||||||
const specialName = monitor?.lastIpcObject.specialWorkspace?.name;
|
const specialName = monitor?.lastIpcObject.specialWorkspace?.name;
|
||||||
@@ -50,7 +51,7 @@ CustomWindow {
|
|||||||
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
|
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
|
||||||
property var root: Quickshell.shellDir
|
property var root: Quickshell.shellDir
|
||||||
readonly property real sdfBorderOffset: 2 * fsTransitionProg
|
readonly property real sdfBorderOffset: 2 * fsTransitionProg
|
||||||
readonly property real shadowOpacity: 0.7 * (1 - fsTransitionProg)
|
readonly property real shadowOpacity: 0.7 * (1 - (bar.isHovered ? 0 : fsTransitionProg))
|
||||||
property color surfaceColor: Colors.tPalette.m3surface
|
property color surfaceColor: Colors.tPalette.m3surface
|
||||||
|
|
||||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||||
@@ -58,7 +59,7 @@ CustomWindow {
|
|||||||
WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top
|
WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
contentItem.focus: true
|
contentItem.focus: true
|
||||||
mask: visibilities.isDrawing ? null : (hasFullscreen ? emptyRegion : regions)
|
mask: visibilities.isDrawing ? null : (hasFullscreen && !bar.isHovered ? emptyRegion : regions)
|
||||||
name: "Bar"
|
name: "Bar"
|
||||||
|
|
||||||
Behavior on fsTransitionProg {
|
Behavior on fsTransitionProg {
|
||||||
@@ -95,13 +96,21 @@ CustomWindow {
|
|||||||
panels.popouts.hasCurrent = false;
|
panels.popouts.hasCurrent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgeGeometry {
|
||||||
|
id: geometry
|
||||||
|
|
||||||
|
bar: bar
|
||||||
|
configPosition: Config.bar.position
|
||||||
|
win: root
|
||||||
|
}
|
||||||
|
|
||||||
Region {
|
Region {
|
||||||
id: emptyRegion
|
id: emptyRegion
|
||||||
|
|
||||||
height: panels.notifications.height
|
height: panels.notifications.height
|
||||||
width: panels.notifications.width
|
width: panels.notifications.width
|
||||||
x: panels.notifications.x + root.borderThickness
|
x: panels.notifications.x + geometry.insetLeft(root.borderThickness)
|
||||||
y: panels.notifications.y + bar.implicitHeight
|
y: panels.notifications.y + geometry.insetTop(root.borderThickness)
|
||||||
|
|
||||||
Region {
|
Region {
|
||||||
height: panels.osd.height
|
height: panels.osd.height
|
||||||
@@ -109,12 +118,18 @@ CustomWindow {
|
|||||||
x: root.width - width
|
x: root.width - width
|
||||||
y: panels.osdWrapper.y + bar.implicitHeight
|
y: panels.osdWrapper.y + bar.implicitHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Region {
|
||||||
|
height: geometry.horizontal ? 1 : root.screen.height
|
||||||
|
width: geometry.horizontal ? root.screen.width : 1
|
||||||
|
y: geometry.position === "bottom" ? root.screen.height - 1 : 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Regions {
|
Regions {
|
||||||
id: regions
|
id: regions
|
||||||
|
|
||||||
bar: bar
|
geometry: geometry
|
||||||
panels: panels
|
panels: panels
|
||||||
win: root
|
win: root
|
||||||
}
|
}
|
||||||
@@ -193,10 +208,10 @@ CustomWindow {
|
|||||||
BlobInvertedRect {
|
BlobInvertedRect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: -50
|
anchors.margins: -50
|
||||||
borderBottom: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
borderBottom: geometry.insetBottom(root.borderThickness) - anchors.margins - root.sdfBorderOffset
|
||||||
borderLeft: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
borderLeft: geometry.insetLeft(root.borderThickness) - anchors.margins - root.sdfBorderOffset
|
||||||
borderRight: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
borderRight: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
||||||
borderTop: bar.implicitHeight - anchors.margins - root.sdfBorderOffset
|
borderTop: geometry.insetTop(root.borderThickness) - anchors.margins - root.sdfBorderOffset
|
||||||
group: blobGroup
|
group: blobGroup
|
||||||
radius: root.borderRounding
|
radius: root.borderRounding
|
||||||
}
|
}
|
||||||
@@ -204,15 +219,15 @@ CustomWindow {
|
|||||||
PanelBg {
|
PanelBg {
|
||||||
id: dashBg
|
id: dashBg
|
||||||
|
|
||||||
property real extraHeight: 0.2
|
property real extraExtent: 0.2
|
||||||
|
|
||||||
deformAmount: 0.06
|
deformAmount: 0.06
|
||||||
implicitHeight: panels.dashboard.height * (1 + extraHeight)
|
implicitHeight: panels.dashboard.height * (geometry.horizontal ? 1 + extraExtent : 1)
|
||||||
implicitWidth: panels.dashboard.width
|
implicitWidth: panels.dashboard.width * (geometry.horizontal ? 1 : 1 + extraExtent)
|
||||||
panel: panels.dashboardWrapper
|
panel: panels.dashboardWrapper
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.extraLarge
|
||||||
x: panels.dashboardWrapper.x + panels.dashboard.x + root.borderThickness
|
x: panels.dashboardWrapper.x + panels.dashboard.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.dashboard.width * extraExtent)
|
||||||
y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight
|
y: panels.dashboardWrapper.y + panels.dashboard.y + geometry.insetTop(root.borderThickness) - (geometry.horizontal && geometry.position !== "bottom" ? panels.dashboard.height * extraExtent : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -223,8 +238,8 @@ CustomWindow {
|
|||||||
deformAmount: 0.06
|
deformAmount: 0.06
|
||||||
implicitHeight: panels.launcher.height * (1 + extraHeight)
|
implicitHeight: panels.launcher.height * (1 + extraHeight)
|
||||||
panel: panels.launcher
|
panel: panels.launcher
|
||||||
radius: Tokens.rounding.smallest + 5
|
radius: Tokens.rounding.medium + (Tokens.padding.largeIncreased / 4)
|
||||||
y: panels.launcher.y + bar.implicitHeight
|
y: panels.launcher.y + geometry.insetTop(root.borderThickness)
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -245,15 +260,14 @@ CustomWindow {
|
|||||||
implicitWidth: panels.osd.width
|
implicitWidth: panels.osd.width
|
||||||
panel: panels.osdWrapper
|
panel: panels.osdWrapper
|
||||||
radius: 20
|
radius: 20
|
||||||
x: panels.osdWrapper.x + panels.osd.x + root.borderThickness
|
x: panels.osdWrapper.x + panels.osd.x + geometry.insetLeft(root.borderThickness)
|
||||||
y: panels.osdWrapper.y + panels.osd.y + bar.implicitHeight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
id: notifsBg
|
id: notifsBg
|
||||||
|
|
||||||
panel: panels.notifications
|
panel: panels.notifications
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.large
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -268,17 +282,17 @@ CustomWindow {
|
|||||||
PanelBg {
|
PanelBg {
|
||||||
id: popoutBg
|
id: popoutBg
|
||||||
|
|
||||||
property real extraHeight: 0.2
|
property real extraExtent: 0.2
|
||||||
|
|
||||||
deformAmount: panels.popouts.currentName.startsWith("traymenu") ? 0.15 : 0.08
|
deformAmount: panels.popouts.currentName.startsWith("traymenu") ? 0.15 : 0.08
|
||||||
implicitHeight: panels.popouts.height * (1 + extraHeight)
|
implicitHeight: panels.popouts.height * (geometry.horizontal ? 1 + extraExtent : 1)
|
||||||
implicitWidth: panels.popouts.width
|
implicitWidth: panels.popouts.width * (geometry.horizontal ? 1 : 1 + extraExtent)
|
||||||
panel: panels.popoutsWrapper
|
panel: panels.popoutsWrapper
|
||||||
radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.normal
|
radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.large
|
||||||
x: panels.popoutsWrapper.x + panels.popouts.x + root.borderThickness
|
x: panels.popoutsWrapper.x + panels.popouts.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.popouts.width * extraExtent)
|
||||||
y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight
|
y: panels.popoutsWrapper.y + panels.popouts.y + geometry.insetTop(root.borderThickness) - (geometry.barOnTop ? panels.popouts.height * extraExtent : 0)
|
||||||
|
|
||||||
Behavior on extraHeight {
|
Behavior on extraExtent {
|
||||||
Anim {
|
Anim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,9 +305,9 @@ CustomWindow {
|
|||||||
implicitHeight: panels.resources.height
|
implicitHeight: panels.resources.height
|
||||||
implicitWidth: panels.resources.width
|
implicitWidth: panels.resources.width
|
||||||
panel: panels.resourcesWrapper
|
panel: panels.resourcesWrapper
|
||||||
radius: Tokens.rounding.large
|
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
|
||||||
x: panels.resourcesWrapper.x + panels.resources.x + root.borderThickness
|
x: panels.resourcesWrapper.x + panels.resources.x + geometry.insetLeft(root.borderThickness)
|
||||||
y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight
|
y: panels.resourcesWrapper.y + panels.resources.y + geometry.insetTop(root.borderThickness)
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -301,7 +315,7 @@ CustomWindow {
|
|||||||
|
|
||||||
deformAmount: 0.03
|
deformAmount: 0.03
|
||||||
panel: panels.settings
|
panel: panels.settings
|
||||||
radius: Tokens.rounding.large + Tokens.padding.normal
|
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -309,7 +323,7 @@ CustomWindow {
|
|||||||
|
|
||||||
deformAmount: 0.08
|
deformAmount: 0.08
|
||||||
panel: panels.dock
|
panel: panels.dock
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.medium
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -317,7 +331,7 @@ CustomWindow {
|
|||||||
|
|
||||||
deformAmount: 0.08
|
deformAmount: 0.08
|
||||||
panel: panels.drawing
|
panel: panels.drawing
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.medium
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelBg {
|
PanelBg {
|
||||||
@@ -371,6 +385,7 @@ CustomWindow {
|
|||||||
borderThickness: root.borderLayoutThickness
|
borderThickness: root.borderLayoutThickness
|
||||||
drawing: drawing
|
drawing: drawing
|
||||||
enabled: true
|
enabled: true
|
||||||
|
geometry: geometry
|
||||||
panels: panels
|
panels: panels
|
||||||
popouts: panels.popouts
|
popouts: panels.popouts
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
@@ -382,6 +397,7 @@ CustomWindow {
|
|||||||
bar: bar
|
bar: bar
|
||||||
borderThickness: root.borderThickness
|
borderThickness: root.borderThickness
|
||||||
drawingItem: drawing
|
drawingItem: drawing
|
||||||
|
geometry: geometry
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
visibilities: visibilities
|
visibilities: visibilities
|
||||||
|
|
||||||
@@ -423,14 +439,18 @@ CustomWindow {
|
|||||||
BarLoader {
|
BarLoader {
|
||||||
id: bar
|
id: bar
|
||||||
|
|
||||||
|
anchors.bottom: geometry.barOnBottom ? parent.bottom : undefined
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.top: geometry.barOnBottom ? undefined : parent.top
|
||||||
enabled: !visibilities.isDrawing
|
enabled: !visibilities.isDrawing
|
||||||
fullscreen: root.hasFullscreen
|
fullscreen: root.hasFullscreen
|
||||||
|
height: geometry.horizontal ? implicitHeight : parent.height
|
||||||
popouts: panels.popouts
|
popouts: panels.popouts
|
||||||
popoutsWrapper: panels.popoutsWrapper
|
popoutsWrapper: panels.popoutsWrapper
|
||||||
|
position: geometry.position
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
visibilities: visibilities
|
visibilities: visibilities
|
||||||
|
width: geometry.horizontal ? parent.width : implicitWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,8 +462,8 @@ CustomWindow {
|
|||||||
group: blobGroup
|
group: blobGroup
|
||||||
implicitHeight: panel.height
|
implicitHeight: panel.height
|
||||||
implicitWidth: panel.width
|
implicitWidth: panel.width
|
||||||
radius: Tokens.rounding.smallest
|
radius: Tokens.rounding.small
|
||||||
x: panel.x + root.borderThickness
|
x: panel.x + geometry.insetLeft(root.borderThickness)
|
||||||
y: panel.y + bar.implicitHeight
|
y: panel.y + geometry.insetTop(root.borderThickness)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Effects
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property real radius
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: shadowRect
|
|
||||||
|
|
||||||
anchors.fill: root
|
|
||||||
color: "black"
|
|
||||||
layer.enabled: true
|
|
||||||
radius: root.radius
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiEffect {
|
|
||||||
id: effects
|
|
||||||
|
|
||||||
anchors.fill: shadowRect
|
|
||||||
autoPaddingEnabled: true
|
|
||||||
maskEnabled: true
|
|
||||||
maskInverted: true
|
|
||||||
maskSource: shadowRect
|
|
||||||
shadowBlur: 2.0
|
|
||||||
shadowColor: "black"
|
|
||||||
shadowEnabled: true
|
|
||||||
shadowOpacity: 1
|
|
||||||
source: shadowRect
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+8
-8
@@ -18,7 +18,7 @@ ColumnLayout {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: false
|
Layout.fillWidth: false
|
||||||
Layout.preferredWidth: centerWidth
|
Layout.preferredWidth: centerWidth
|
||||||
spacing: Tokens.spacing.large * 2
|
spacing: Tokens.spacing.largeIncreased * 2
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
@@ -64,7 +64,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
CustomClippingRect {
|
CustomClippingRect {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.topMargin: Tokens.spacing.large * 2
|
Layout.topMargin: Tokens.spacing.largeIncreased * 2
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: root.centerWidth / 2
|
implicitHeight: root.centerWidth / 2
|
||||||
implicitWidth: root.centerWidth / 2
|
implicitWidth: root.centerWidth / 2
|
||||||
@@ -99,7 +99,7 @@ ColumnLayout {
|
|||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
focus: true
|
focus: true
|
||||||
implicitHeight: input.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: input.implicitHeight + Tokens.padding.extraSmall * 2
|
||||||
implicitWidth: root.centerWidth * 0.8
|
implicitWidth: root.centerWidth * 0.8
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
@@ -130,11 +130,11 @@ ColumnLayout {
|
|||||||
id: input
|
id: input
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.extraSmall
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
implicitHeight: statusIcon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: statusIcon.implicitHeight + Tokens.padding.extraSmall * 2
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
@@ -174,7 +174,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
|
color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
|
||||||
implicitHeight: enterIcon.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: enterIcon.implicitHeight + Tokens.padding.extraSmall * 2
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: -Tokens.spacing.large
|
Layout.topMargin: -Tokens.spacing.largeIncreased
|
||||||
implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight)
|
implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight)
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
|
|||||||
+11
-11
@@ -30,11 +30,11 @@ NumberAnimation {
|
|||||||
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.large;
|
return Tokens.anim.durations.expressiveSlowSpatial;
|
||||||
if (type === Anim.FastEffects)
|
if (type === Anim.FastEffects)
|
||||||
return Tokens.anim.durations.expressiveFastEffects;
|
return Tokens.anim.durations.expressiveFastEffects;
|
||||||
if (type === Anim.DefaultEffects)
|
if (type === Anim.DefaultEffects)
|
||||||
return Tokens.anim.durations.expressiveEffects;
|
return Tokens.anim.durations.expressiveDefaultEffects;
|
||||||
if (type === Anim.SlowEffects)
|
if (type === Anim.SlowEffects)
|
||||||
return Tokens.anim.durations.expressiveSlowEffects;
|
return Tokens.anim.durations.expressiveSlowEffects;
|
||||||
|
|
||||||
@@ -42,22 +42,22 @@ NumberAnimation {
|
|||||||
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.bezierCurve: {
|
easing: {
|
||||||
if (type === Anim.FastSpatial)
|
if (type === Anim.FastSpatial)
|
||||||
return Tokens.anim.curves.expressiveFastSpatial;
|
return Tokens.anim.expressiveFastSpatial;
|
||||||
if (type === Anim.DefaultSpatial)
|
if (type === Anim.DefaultSpatial)
|
||||||
return Tokens.anim.curves.expressiveDefaultSpatial;
|
return Tokens.anim.expressiveDefaultSpatial;
|
||||||
if (type === Anim.SlowSpatial)
|
if (type === Anim.SlowSpatial)
|
||||||
return Tokens.anim.curves.expressiveSlowSpatial;
|
return Tokens.anim.expressiveSlowSpatial;
|
||||||
if (type === Anim.FastEffects)
|
if (type === Anim.FastEffects)
|
||||||
return Tokens.anim.curves.expressiveFastEffects;
|
return Tokens.anim.expressiveFastEffects;
|
||||||
if (type === Anim.DefaultEffects)
|
if (type === Anim.DefaultEffects)
|
||||||
return Tokens.anim.curves.expressiveDefaultEffects;
|
return Tokens.anim.expressiveDefaultEffects;
|
||||||
if (type === Anim.SlowEffects)
|
if (type === Anim.SlowEffects)
|
||||||
return Tokens.anim.curves.expressiveSlowEffects;
|
return Tokens.anim.expressiveSlowEffects;
|
||||||
|
|
||||||
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
||||||
return Tokens.anim.curves.emphasized;
|
return Tokens.anim.emphasized;
|
||||||
return Tokens.anim.curves.standard;
|
return Tokens.anim.standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,62 +2,6 @@ import QtQuick
|
|||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
enum Type {
|
duration: Tokens.anim.durations.expressiveSlowEffects
|
||||||
StandardSmall = 0,
|
easing: Tokens.anim.expressiveSlowEffects
|
||||||
Standard,
|
|
||||||
StandardLarge,
|
|
||||||
StandardExtraLarge,
|
|
||||||
EmphasizedSmall,
|
|
||||||
Emphasized,
|
|
||||||
EmphasizedLarge,
|
|
||||||
EmphasizedExtraLarge,
|
|
||||||
FastSpatial,
|
|
||||||
DefaultSpatial,
|
|
||||||
SlowSpatial,
|
|
||||||
FastEffects,
|
|
||||||
DefaultEffects,
|
|
||||||
SlowEffects
|
|
||||||
}
|
|
||||||
|
|
||||||
property int type: CAnim.DefaultSpatial
|
|
||||||
|
|
||||||
duration: {
|
|
||||||
if (type < CAnim.StandardSmall || type > Anim.SlowEffects)
|
|
||||||
return Tokens.anim.durations.normal;
|
|
||||||
|
|
||||||
if (type === CAnim.FastSpatial)
|
|
||||||
return Tokens.anim.durations.expressiveFastSpatial;
|
|
||||||
if (type === CAnim.DefaultSpatial)
|
|
||||||
return Tokens.anim.durations.expressiveDefaultSpatial;
|
|
||||||
if (type === CAnim.SlowSpatial)
|
|
||||||
return Tokens.anim.durations.large;
|
|
||||||
if (type === CAnim.FastEffects)
|
|
||||||
return Tokens.anim.durations.expressiveFastEffects;
|
|
||||||
if (type === CAnim.DefaultEffects)
|
|
||||||
return Tokens.anim.durations.expressiveEffects;
|
|
||||||
if (type === CAnim.SlowEffects)
|
|
||||||
return Tokens.anim.durations.expressiveSlowEffects;
|
|
||||||
|
|
||||||
const types = ["small", "normal", "large", "extraLarge"];
|
|
||||||
const idx = type % 4;
|
|
||||||
return Tokens.anim.durations[types[idx]];
|
|
||||||
}
|
|
||||||
easing.bezierCurve: {
|
|
||||||
if (type === CAnim.FastSpatial)
|
|
||||||
return Tokens.anim.curves.expressiveFastSpatial;
|
|
||||||
if (type === CAnim.DefaultSpatial)
|
|
||||||
return Tokens.anim.curves.expressiveDefaultSpatial;
|
|
||||||
if (type === CAnim.SlowSpatial)
|
|
||||||
return Tokens.anim.curves.expressiveSlowSpatial;
|
|
||||||
if (type === CAnim.FastEffects)
|
|
||||||
return Tokens.anim.curves.expressiveFastEffects;
|
|
||||||
if (type === CAnim.DefaultEffects)
|
|
||||||
return Tokens.anim.curves.expressiveDefaultEffects;
|
|
||||||
if (type === CAnim.SlowEffects)
|
|
||||||
return Tokens.anim.curves.expressiveSlowEffects;
|
|
||||||
|
|
||||||
if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
|
|
||||||
return Tokens.anim.curves.emphasized;
|
|
||||||
return Tokens.anim.curves.standard;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ BusyIndicator {
|
|||||||
property real implicitSize: Tokens.font.size.normal * 3
|
property real implicitSize: Tokens.font.size.normal * 3
|
||||||
property real internalStrokeWidth: strokeWidth
|
property real internalStrokeWidth: strokeWidth
|
||||||
readonly property alias progress: manager.progress
|
readonly property alias progress: manager.progress
|
||||||
property real strokeWidth: Tokens.padding.small * 0.8
|
property real strokeWidth: Tokens.padding.extraSmall * 0.8
|
||||||
property alias type: manager.indeterminateAnimationType
|
property alias type: manager.indeterminateAnimationType
|
||||||
|
|
||||||
implicitHeight: implicitSize
|
implicitHeight: implicitSize
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Item {
|
|||||||
readonly property real size: Math.min(width, height)
|
readonly property real size: Math.min(width, height)
|
||||||
property int spacing: Tokens.spacing.small
|
property int spacing: Tokens.spacing.small
|
||||||
property int startAngle: -90
|
property int startAngle: -90
|
||||||
property int strokeWidth: Tokens.padding.small
|
property int strokeWidth: Tokens.padding.extraSmall
|
||||||
property int sweepAngle: 360
|
property int sweepAngle: 360
|
||||||
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
|
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
|
||||||
property real value
|
property real value
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ TextField {
|
|||||||
|
|
||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
implicitWidth: 2
|
implicitWidth: 2
|
||||||
radius: Tokens.rounding.normal
|
radius: Tokens.rounding.medium
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {
|
Anim {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
@@ -11,6 +10,6 @@ TextInput {
|
|||||||
font {
|
font {
|
||||||
family: Config.appearance?.font.family.sans ?? "sans-serif"
|
family: Config.appearance?.font.family.sans ?? "sans-serif"
|
||||||
hintingPreference: Font.PreferFullHinting
|
hintingPreference: Font.PreferFullHinting
|
||||||
pixelSize: Config.appearance?.font.size.normal ?? 15
|
pixelSize: Tokens?.font.size.normal ?? 15
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ MouseArea {
|
|||||||
|
|
||||||
alwaysRunToEnd: true
|
alwaysRunToEnd: true
|
||||||
duration: Tokens.anim.durations.expressiveSlowEffects * 2
|
duration: Tokens.anim.durations.expressiveSlowEffects * 2
|
||||||
easing.bezierCurve: Tokens.anim.curves.standard
|
easing: Tokens.anim.standard
|
||||||
property: "circleRadius"
|
property: "circleRadius"
|
||||||
target: root
|
target: root
|
||||||
to: root.endRadius
|
to: root.endRadius
|
||||||
|
|||||||
+7
-7
@@ -11,18 +11,18 @@ RowLayout {
|
|||||||
required property var greeter
|
required property var greeter
|
||||||
required property real screenHeight
|
required property real screenHeight
|
||||||
|
|
||||||
spacing: Tokens.spacing.large * 2
|
spacing: Tokens.spacing.largeIncreased * 2
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: weather.implicitHeight
|
implicitHeight: weather.implicitHeight
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.small
|
||||||
topLeftRadius: Tokens.rounding.large
|
topLeftRadius: Tokens.rounding.largeIncreased
|
||||||
|
|
||||||
WeatherInfo {
|
WeatherInfo {
|
||||||
id: weather
|
id: weather
|
||||||
@@ -34,7 +34,7 @@ RowLayout {
|
|||||||
CustomClippingRect {
|
CustomClippingRect {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
bottomLeftRadius: Tokens.rounding.large
|
bottomLeftRadius: Tokens.rounding.largeIncreased
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.small
|
||||||
|
|
||||||
@@ -51,15 +51,15 @@ RowLayout {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
bottomRightRadius: Tokens.rounding.large
|
bottomRightRadius: Tokens.rounding.largeIncreased
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.small
|
||||||
topRightRadius: Tokens.rounding.large
|
topRightRadius: Tokens.rounding.largeIncreased
|
||||||
|
|
||||||
SessionDock {
|
SessionDock {
|
||||||
greeter: root.greeter
|
greeter: root.greeter
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Scope {
|
|||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveFastSpatial
|
duration: Tokens.anim.durations.expressiveFastSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
easing: Tokens.anim.expressiveFastSpatial
|
||||||
property: "scale"
|
property: "scale"
|
||||||
target: lockContent
|
target: lockContent
|
||||||
to: 1
|
to: 1
|
||||||
@@ -65,7 +65,7 @@ Scope {
|
|||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
property: "scale"
|
property: "scale"
|
||||||
target: content
|
target: content
|
||||||
to: 1
|
to: 1
|
||||||
@@ -74,12 +74,12 @@ Scope {
|
|||||||
Anim {
|
Anim {
|
||||||
property: "radius"
|
property: "radius"
|
||||||
target: lockBg
|
target: lockBg
|
||||||
to: Tokens.rounding.large * 1.5
|
to: Tokens.rounding.largeIncreased * 1.5
|
||||||
}
|
}
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
property: "implicitWidth"
|
property: "implicitWidth"
|
||||||
target: lockContent
|
target: lockContent
|
||||||
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio
|
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio
|
||||||
@@ -87,7 +87,7 @@ Scope {
|
|||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
property: "implicitHeight"
|
property: "implicitHeight"
|
||||||
target: lockContent
|
target: lockContent
|
||||||
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult
|
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ Item {
|
|||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveFastSpatial
|
duration: Tokens.anim.durations.expressiveFastSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
easing: Tokens.anim.expressiveFastSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.large
|
anchors.margins: Tokens.padding.large
|
||||||
spacing: Tokens.spacing.smaller
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -41,7 +41,7 @@ ColumnLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceComponent: ColumnLayout {
|
sourceComponent: ColumnLayout {
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
@@ -79,8 +79,8 @@ ColumnLayout {
|
|||||||
|
|
||||||
anchors.left: parent?.left
|
anchors.left: parent?.left
|
||||||
anchors.right: parent?.right
|
anchors.right: parent?.right
|
||||||
implicitHeight: row.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: row.implicitHeight + Tokens.padding.small * 2
|
||||||
radius: Tokens.rounding.normal - Tokens.padding.smaller
|
radius: Tokens.rounding.medium - Tokens.padding.small
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -92,8 +92,8 @@ ColumnLayout {
|
|||||||
id: row
|
id: row
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.small
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurfaceVariant
|
color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurfaceVariant
|
||||||
@@ -129,13 +129,13 @@ ColumnLayout {
|
|||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
implicitHeight: sessions.currentItem?.implicitHeight ?? 0
|
implicitHeight: sessions.currentItem?.implicitHeight ?? 0
|
||||||
implicitWidth: sessions.width
|
implicitWidth: sessions.width
|
||||||
radius: Tokens.rounding.normal - Tokens.padding.smaller
|
radius: Tokens.rounding.medium - Tokens.padding.small
|
||||||
y: sessions.currentItem?.y ?? 0
|
y: sessions.currentItem?.y ?? 0
|
||||||
|
|
||||||
Behavior on y {
|
Behavior on y {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.small
|
duration: Tokens.anim.durations.small
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
|
easing: Tokens.anim.expressiveDefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.large
|
anchors.margins: Tokens.padding.large
|
||||||
spacing: Tokens.spacing.smaller
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -42,7 +42,7 @@ ColumnLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceComponent: ColumnLayout {
|
sourceComponent: ColumnLayout {
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
@@ -81,8 +81,8 @@ ColumnLayout {
|
|||||||
|
|
||||||
anchors.left: parent?.left
|
anchors.left: parent?.left
|
||||||
anchors.right: parent?.right
|
anchors.right: parent?.right
|
||||||
implicitHeight: row.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: row.implicitHeight + Tokens.padding.small * 2
|
||||||
radius: Tokens.rounding.normal - Tokens.padding.smaller
|
radius: Tokens.rounding.medium - Tokens.padding.small
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -94,8 +94,8 @@ ColumnLayout {
|
|||||||
id: row
|
id: row
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.small
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
CustomClippingRect {
|
CustomClippingRect {
|
||||||
Layout.preferredHeight: 50
|
Layout.preferredHeight: 50
|
||||||
@@ -135,13 +135,13 @@ ColumnLayout {
|
|||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
implicitHeight: users.currentItem?.implicitHeight ?? 0
|
implicitHeight: users.currentItem?.implicitHeight ?? 0
|
||||||
implicitWidth: users.width
|
implicitWidth: users.width
|
||||||
radius: Tokens.rounding.normal - Tokens.padding.smaller
|
radius: Tokens.rounding.medium - Tokens.padding.small
|
||||||
y: users.currentItem?.y ?? 0
|
y: users.currentItem?.y ?? 0
|
||||||
|
|
||||||
Behavior on y {
|
Behavior on y {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.small
|
duration: Tokens.anim.durations.expressiveDefaultEffects
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
|
easing: Tokens.anim.expressiveDefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
animate: true
|
animate: true
|
||||||
@@ -67,7 +67,7 @@ ColumnLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
Layout.rightMargin: Tokens.padding.smaller
|
Layout.rightMargin: Tokens.padding.small
|
||||||
active: root.width > 400
|
active: root.width > 400
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
@@ -103,12 +103,12 @@ ColumnLayout {
|
|||||||
|
|
||||||
Layout.bottomMargin: Tokens.padding.large * 2
|
Layout.bottomMargin: Tokens.padding.large * 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Tokens.spacing.smaller
|
Layout.topMargin: Tokens.spacing.small
|
||||||
active: root.rootHeight > 820
|
active: root.rootHeight > 820
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
sourceComponent: RowLayout {
|
sourceComponent: RowLayout {
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: {
|
model: {
|
||||||
|
|||||||
+40
-12
@@ -1,35 +1,63 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
import qs.Paths
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property var colors: {
|
readonly property list<var> allPeripherals: [...logiDevices, ...upowerDevices.filter(d => !Battery.logiDevices.some(l => l.nativePath === d.nativePath))]
|
||||||
if (deviceState === UPowerDeviceState.Charging || deviceState === UPowerDeviceState.FullyCharged)
|
readonly property real currentPerc: UPower.displayDevice.percentage
|
||||||
|
readonly property var deviceState: UPower.displayDevice.state
|
||||||
|
readonly property string deviceStateString: UPowerDeviceState.toString(deviceState)
|
||||||
|
readonly property bool isLaptop: UPower.displayDevice.isLaptopBattery
|
||||||
|
readonly property alias logiDevices: adapter.devices
|
||||||
|
readonly property var lowestPeripheral: allPeripherals.reduce((lowest, current) => current.percentage < lowest.percentage ? current : lowest)
|
||||||
|
readonly property bool onBattery: UPower.onBattery
|
||||||
|
readonly property bool ready: UPower.displayDevice.ready
|
||||||
|
readonly property real timeToEmpty: UPower.displayDevice.timeToEmpty
|
||||||
|
readonly property real timeToFull: UPower.displayDevice.timeToFull
|
||||||
|
readonly property list<UPowerDevice> upowerDevices: UPower.devices.values.filter(d => d.state !== UPowerDeviceState.Unknown)
|
||||||
|
|
||||||
|
function getColors(percentage: real, state: string): var {
|
||||||
|
if (state === "charging" || state === "full" || state === "recharging")
|
||||||
return {
|
return {
|
||||||
fg: Colors.swapRG(Colors.palette.m3error),
|
fg: Colors.swapRG(Colors.palette.m3error),
|
||||||
bg: Colors.swapRG(Colors.palette.m3onError)
|
bg: Colors.swapRG(Colors.palette.m3onError)
|
||||||
};
|
};
|
||||||
else if (currentPerc <= 0.2)
|
else if (percentage <= 0.2)
|
||||||
return {
|
return {
|
||||||
fg: Colors.palette.m3error,
|
fg: Colors.palette.m3error,
|
||||||
bg: Colors.palette.m3onError
|
bg: Colors.palette.m3onError
|
||||||
};
|
};
|
||||||
else
|
else
|
||||||
return {
|
return {
|
||||||
fg: Colors.palette.m3onSurface,
|
fg: Colors.palette.m3tertiary,
|
||||||
bg: Colors.palette.m3surface
|
bg: Colors.palette.m3onTertiary
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
readonly property real currentPerc: UPower.displayDevice.percentage
|
|
||||||
readonly property var deviceState: UPower.displayDevice.state
|
function startDaemon(): void {
|
||||||
readonly property bool isLaptop: UPower.displayDevice.isLaptopBattery
|
Quickshell.execDetached(["zshell-cli", "battery", "daemon"]);
|
||||||
readonly property bool onBattery: UPower.onBattery
|
}
|
||||||
readonly property bool ready: UPower.displayDevice.ready
|
|
||||||
readonly property real timeToEmpty: UPower.displayDevice.timeToEmpty
|
FileView {
|
||||||
readonly property real timeToFull: UPower.displayDevice.timeToFull
|
id: fileView
|
||||||
|
|
||||||
|
path: `${Paths.cache}/battery.json`
|
||||||
|
watchChanges: true
|
||||||
|
|
||||||
|
onFileChanged: reload()
|
||||||
|
|
||||||
|
JsonAdapter {
|
||||||
|
id: adapter
|
||||||
|
|
||||||
|
property list<var> devices: []
|
||||||
|
property real updated: 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import qs.Components
|
|
||||||
import ZShell.Config
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property list<var> apps: {
|
|
||||||
var map = new Map();
|
|
||||||
|
|
||||||
const pinnedApps = Config.dock?.pinnedApps ?? [];
|
|
||||||
for (const appId of pinnedApps) {
|
|
||||||
if (!map.has(appId.toLowerCase()))
|
|
||||||
map.set(appId.toLowerCase(), ({
|
|
||||||
pinned: true,
|
|
||||||
toplevels: []
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pinnedApps.length > 0) {
|
|
||||||
map.set("SEPARATOR", {
|
|
||||||
pinned: false,
|
|
||||||
toplevels: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var values = [];
|
|
||||||
|
|
||||||
for (const [key, value] of map) {
|
|
||||||
values.push(appEntryComp.createObject(null, {
|
|
||||||
appId: key,
|
|
||||||
toplevels: value.toplevels,
|
|
||||||
pinned: value.pinned
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isPinned(appId) {
|
|
||||||
return Config.dock.pinnedApps.indexOf(appId) !== -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function togglePin(appId) {
|
|
||||||
if (root.isPinned(appId)) {
|
|
||||||
Config.dock.pinnedApps = Config.dock.pinnedApps.filter(id => id !== appId);
|
|
||||||
} else {
|
|
||||||
Config.dock.pinnedApps = Config.dock.pinnedApps.concat([appId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: appEntryComp
|
|
||||||
|
|
||||||
TaskbarAppEntry {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component TaskbarAppEntry: QtObject {
|
|
||||||
id: wrapper
|
|
||||||
|
|
||||||
required property string appId
|
|
||||||
required property bool pinned
|
|
||||||
required property list<var> toplevels
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
// FetchPresets.qml
|
|
||||||
pragma Singleton
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var parsedPresets: ({})
|
|
||||||
readonly property var presets: parsedPresets
|
|
||||||
property bool ready: false
|
|
||||||
|
|
||||||
function accents(presetName, variantName) {
|
|
||||||
const variant = parsedPresets[presetName]?.variants?.[variantName];
|
|
||||||
|
|
||||||
return variant?.accents ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function defaultAccent(presetName, variantName) {
|
|
||||||
const variant = parsedPresets[presetName]?.variants?.[variantName];
|
|
||||||
|
|
||||||
return variant?.default_accent ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function modes(presetName, variantName) {
|
|
||||||
const variant = parsedPresets[presetName]?.variants?.[variantName];
|
|
||||||
|
|
||||||
return variant?.modes ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function presetNames() {
|
|
||||||
return Object.keys(parsedPresets);
|
|
||||||
}
|
|
||||||
|
|
||||||
function variantNames(presetName) {
|
|
||||||
const preset = parsedPresets[presetName];
|
|
||||||
|
|
||||||
if (!preset || !preset.variants)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
return Object.keys(preset.variants);
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
command: ["zshell-cli", "scheme", "list-presets", "--json"]
|
|
||||||
running: true
|
|
||||||
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(text);
|
|
||||||
|
|
||||||
root.parsedPresets = parsed.presets ?? {};
|
|
||||||
root.ready = true;
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to parse presets JSON:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+51
-2
@@ -1,9 +1,8 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import ZShell.Config
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
import QtQuick
|
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
@@ -95,6 +94,15 @@ Singleton {
|
|||||||
return Quickshell.iconPath(icon);
|
return Quickshell.iconPath(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBatteryIcon(percentage: real, charging = false): string {
|
||||||
|
if (percentage === 1)
|
||||||
|
return charging ? "battery_charging_full" : "battery_full";
|
||||||
|
let level = Math.floor(percentage * 7);
|
||||||
|
if (charging && (level === 4 || level === 1))
|
||||||
|
level--;
|
||||||
|
return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`;
|
||||||
|
}
|
||||||
|
|
||||||
function getBluetoothIcon(icon: string): string {
|
function getBluetoothIcon(icon: string): string {
|
||||||
if (icon.includes("headset") || icon.includes("headphones"))
|
if (icon.includes("headset") || icon.includes("headphones"))
|
||||||
return "headphones";
|
return "headphones";
|
||||||
@@ -168,6 +176,32 @@ Singleton {
|
|||||||
return "chat";
|
return "chat";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSpecialWsIcon(name: string): string {
|
||||||
|
name = name.toLowerCase().slice("special:".length);
|
||||||
|
|
||||||
|
if (name === "special")
|
||||||
|
return "star";
|
||||||
|
if (name === "communication")
|
||||||
|
return "forum";
|
||||||
|
if (name === "music")
|
||||||
|
return "music_cast";
|
||||||
|
if (name === "todo")
|
||||||
|
return "checklist";
|
||||||
|
if (name === "sysmon")
|
||||||
|
return "monitor_heart";
|
||||||
|
return name[0].toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTrayIcon(id: string, icon: string): string {
|
||||||
|
if (icon.includes("?path=")) {
|
||||||
|
const [name, path] = icon.split("?path=");
|
||||||
|
const file = name.slice(name.lastIndexOf("/") + 1);
|
||||||
|
const themed = Quickshell.iconPath(file, true);
|
||||||
|
icon = themed ? themed : Qt.resolvedUrl(`${path}/${file}`);
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
function getVolumeIcon(volume: real, isMuted: bool): string {
|
function getVolumeIcon(volume: real, isMuted: bool): string {
|
||||||
if (isMuted)
|
if (isMuted)
|
||||||
return "no_sound";
|
return "no_sound";
|
||||||
@@ -183,4 +217,19 @@ Singleton {
|
|||||||
return weatherIcons[code];
|
return weatherIcons[code];
|
||||||
return "air";
|
return "air";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function matchIconConfig(name: string, iconConfig: var): bool {
|
||||||
|
if (!iconConfig.icon)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (iconConfig.regex) {
|
||||||
|
const re = new RegExp(iconConfig.regex, iconConfig.flags ?? "");
|
||||||
|
if (re.test(name))
|
||||||
|
return true;
|
||||||
|
} else if (iconConfig.name === name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -391,7 +391,7 @@ Item {
|
|||||||
tool: root.tool
|
tool: root.tool
|
||||||
visible: root.mode === "edit"
|
visible: root.mode === "edit"
|
||||||
x: Math.max(8, Math.min(root.rsx + root.sw / 2 - width / 2, root.screen.width - width - 8))
|
x: Math.max(8, Math.min(root.rsx + root.sw / 2 - width / 2, root.screen.width - width - 8))
|
||||||
y: (root.rsy + root.sh + height + Tokens.padding.normal <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.normal : (root.rsy - height - Tokens.padding.normal <= 0) ? root.rsy + root.sh - height - Tokens.padding.normal : root.rsy - height - Tokens.padding.normal
|
y: (root.rsy + root.sh + height + Tokens.padding.small <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.small : (root.rsy - height - Tokens.padding.small <= 0) ? root.rsy + root.sh - height - Tokens.padding.small : root.rsy - height - Tokens.padding.small
|
||||||
|
|
||||||
onCancelRequested: root.cancel()
|
onCancelRequested: root.cancel()
|
||||||
onClearRequested: annotations.clearAll()
|
onClearRequested: annotations.clearAll()
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ CustomRect {
|
|||||||
signal undoRequested
|
signal undoRequested
|
||||||
|
|
||||||
color: Colors.palette.m3surface
|
color: Colors.palette.m3surface
|
||||||
height: row.implicitHeight + Tokens.padding.normal * 2
|
height: row.implicitHeight + Tokens.padding.small * 2
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
width: row.implicitWidth + Tokens.padding.normal * 2
|
width: row.implicitWidth + Tokens.padding.small * 2
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: row
|
id: row
|
||||||
@@ -73,6 +73,7 @@ CustomRect {
|
|||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
color: root.tool === modelData.id ? "#3584e4" : "transparent"
|
color: root.tool === modelData.id ? "#3584e4" : "transparent"
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: tool.modelData.glyph
|
icon: tool.modelData.glyph
|
||||||
inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent"
|
inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent"
|
||||||
inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
@@ -98,11 +99,11 @@ CustomRect {
|
|||||||
model: root.colorPalette
|
model: root.colorPalette
|
||||||
|
|
||||||
delegate: IconButton {
|
delegate: IconButton {
|
||||||
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.normal
|
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.small
|
||||||
required property color modelData
|
required property color modelData
|
||||||
|
|
||||||
fillWidth: false
|
fillWidth: false
|
||||||
font.pointSize: 0
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: ""
|
icon: ""
|
||||||
implicitHeight: buttonSize
|
implicitHeight: buttonSize
|
||||||
implicitWidth: buttonSize
|
implicitWidth: buttonSize
|
||||||
@@ -127,6 +128,7 @@ CustomRect {
|
|||||||
spacing: Tokens.spacing.extraSmall
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: "undo"
|
icon: "undo"
|
||||||
inactiveColor: "transparent"
|
inactiveColor: "transparent"
|
||||||
inactiveOnColor: Colors.palette.m3onSurface
|
inactiveOnColor: Colors.palette.m3onSurface
|
||||||
@@ -138,6 +140,7 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: "delete_history"
|
icon: "delete_history"
|
||||||
inactiveColor: "transparent"
|
inactiveColor: "transparent"
|
||||||
inactiveOnColor: Colors.palette.m3onSurface
|
inactiveOnColor: Colors.palette.m3onSurface
|
||||||
@@ -149,6 +152,7 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: "content_copy"
|
icon: "content_copy"
|
||||||
inactiveColor: "transparent"
|
inactiveColor: "transparent"
|
||||||
inactiveOnColor: Colors.palette.m3onSurface
|
inactiveOnColor: Colors.palette.m3onSurface
|
||||||
@@ -160,6 +164,7 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: "delete_forever"
|
icon: "delete_forever"
|
||||||
inactiveColor: "transparent"
|
inactiveColor: "transparent"
|
||||||
inactiveOnColor: Colors.palette.m3onSurface
|
inactiveOnColor: Colors.palette.m3onSurface
|
||||||
@@ -171,6 +176,7 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
icon: "check"
|
icon: "check"
|
||||||
inactiveColor: "transparent"
|
inactiveColor: "transparent"
|
||||||
inactiveOnColor: Colors.palette.m3onSurface
|
inactiveOnColor: Colors.palette.m3onSurface
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ Singleton {
|
|||||||
|
|
||||||
Config.dock.pinnedApps = pinnedApps;
|
Config.dock.pinnedApps = pinnedApps;
|
||||||
root.unpinnedOrder = visibleUnpinned.concat(root.unpinnedOrder.map(normalizeId).filter(id => !pinnedApps.includes(id) && !visibleUnpinned.includes(id)));
|
root.unpinnedOrder = visibleUnpinned.concat(root.unpinnedOrder.map(normalizeId).filter(id => !pinnedApps.includes(id) && !visibleUnpinned.includes(id)));
|
||||||
Config.saveNoToast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPinned(appId) {
|
function isPinned(appId) {
|
||||||
|
|||||||
+8
-41
@@ -11,8 +11,8 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property int availableUpdates: 0
|
property int availableUpdates: 0
|
||||||
property string cmd: ""
|
|
||||||
property bool commandReady
|
property bool commandReady
|
||||||
|
property bool hasHelper
|
||||||
property bool loaded
|
property bool loaded
|
||||||
property double now: Date.now()
|
property double now: Date.now()
|
||||||
property var updates: ({})
|
property var updates: ({})
|
||||||
@@ -38,18 +38,12 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function performPackageUpdate(pkg: string): void {
|
function performPackageUpdate(pkg: string): void {
|
||||||
if (root.cmd === "pacman")
|
pkgUpdateProc.command = ["pkexec", "pacman", "--noconfirm", "-Sy", pkg];
|
||||||
pkgUpdateProc.command = ["pkexec", root.cmd, "--noconfirm", "-Sy", pkg];
|
|
||||||
else
|
|
||||||
pkgUpdateProc.command = [root.cmd, "--noconfirm", "--sudo", "pkexec", "-Sy", pkg];
|
|
||||||
pkgUpdateProc.running = true;
|
pkgUpdateProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function performSystemUpdate(): void {
|
function performSystemUpdate(): void {
|
||||||
if (root.cmd === "pacman")
|
sysUpdateProc.command = ["pkexec", "pacman", "--noconfirm", "-Syu"];
|
||||||
sysUpdateProc.command = ["pkexec", root.cmd, "--noconfirm", "-Syu"];
|
|
||||||
else
|
|
||||||
sysUpdateProc.command = [root.cmd, "--noconfirm", "--sudo", "pkexec", "-Syu"];
|
|
||||||
sysUpdateProc.running = true;
|
sysUpdateProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +81,7 @@ Singleton {
|
|||||||
Process {
|
Process {
|
||||||
id: cmdDetect
|
id: cmdDetect
|
||||||
|
|
||||||
command: ["sh", "-c", "command -v checkupdates || command -v yay || command -v paru"]
|
command: ["sh", "-c", "command -v checkupdates"]
|
||||||
running: true
|
running: true
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
@@ -96,47 +90,20 @@ Singleton {
|
|||||||
let helper;
|
let helper;
|
||||||
|
|
||||||
if (cmd.length > 0) {
|
if (cmd.length > 0) {
|
||||||
helper = cmd.split("/").pop();
|
helper = true;
|
||||||
} else {
|
} else {
|
||||||
helper = "pacman";
|
helper = false;
|
||||||
}
|
|
||||||
|
|
||||||
if (helper === "checkupdates") {
|
|
||||||
updatesProc.command = [helper];
|
|
||||||
} else {
|
|
||||||
updatesProc.command = [helper, "-Qu"];
|
|
||||||
}
|
}
|
||||||
|
root.hasHelper = helper;
|
||||||
root.commandReady = true;
|
root.commandReady = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
|
||||||
id: updateCmdDetect
|
|
||||||
|
|
||||||
command: ["sh", "-c", "command -v yay || command -v paru"]
|
|
||||||
running: true
|
|
||||||
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
const cmd = this.text.trim();
|
|
||||||
let helper;
|
|
||||||
|
|
||||||
if (cmd.length > 0) {
|
|
||||||
helper = cmd.split("/").pop();
|
|
||||||
} else {
|
|
||||||
helper = "pacman";
|
|
||||||
}
|
|
||||||
|
|
||||||
root.cmd = helper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: updatesProc
|
id: updatesProc
|
||||||
|
|
||||||
command: []
|
command: root.hasHelper ? ["checkupdates"] : []
|
||||||
running: false
|
running: false
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ Singleton {
|
|||||||
watchChanges: true
|
watchChanges: true
|
||||||
|
|
||||||
onAdapterUpdated: writeAdapter()
|
onAdapterUpdated: writeAdapter()
|
||||||
onFileChanged: reload()
|
onFileChanged: {
|
||||||
|
reload();
|
||||||
|
Wallpapers.previewColorLock = false;
|
||||||
|
}
|
||||||
|
|
||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: adapter
|
id: adapter
|
||||||
|
|||||||
+28
-6
@@ -6,7 +6,7 @@ import Quickshell.Io
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import ZShell.Models
|
import ZShell.Models
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Modules
|
import qs.Services
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Paths
|
import qs.Paths
|
||||||
|
|
||||||
@@ -17,6 +17,8 @@ Searcher {
|
|||||||
property alias crops: adapter.monitorCrops
|
property alias crops: adapter.monitorCrops
|
||||||
readonly property string current: showPreview ? previewPath : actualCurrent
|
readonly property string current: showPreview ? previewPath : actualCurrent
|
||||||
property alias monitorCrops: monitorCrops
|
property alias monitorCrops: monitorCrops
|
||||||
|
property bool pendingPreviewClear
|
||||||
|
property bool previewColorLock
|
||||||
property string previewPath
|
property string previewPath
|
||||||
property bool recentlyChanged
|
property bool recentlyChanged
|
||||||
property bool showPreview: false
|
property bool showPreview: false
|
||||||
@@ -34,9 +36,10 @@ Searcher {
|
|||||||
|
|
||||||
function preview(path: string): void {
|
function preview(path: string): void {
|
||||||
previewPath = path;
|
previewPath = path;
|
||||||
if (Config.general.color.schemeGeneration)
|
|
||||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${previewPath}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
|
|
||||||
showPreview = true;
|
showPreview = true;
|
||||||
|
|
||||||
|
if (Config.general.color.schemeGeneration)
|
||||||
|
previewColorsProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCrop(screen: string, rect: rect, zoom: real): void {
|
function setCrop(screen: string, rect: rect, zoom: real): void {
|
||||||
@@ -52,7 +55,6 @@ Searcher {
|
|||||||
height: rect.height,
|
height: rect.height,
|
||||||
zoom: zoom
|
zoom: zoom
|
||||||
};
|
};
|
||||||
// root.crops = updated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWallpaper(path: string): void {
|
function setWallpaper(path: string): void {
|
||||||
@@ -66,8 +68,10 @@ Searcher {
|
|||||||
|
|
||||||
function stopPreview(): void {
|
function stopPreview(): void {
|
||||||
showPreview = false;
|
showPreview = false;
|
||||||
if (Config.general.color.schemeGeneration)
|
if (previewColorLock)
|
||||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
|
pendingPreviewClear = true;
|
||||||
|
else
|
||||||
|
Colors.showPreview = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extraOpts: useFuzzy ? ({}) : ({
|
extraOpts: useFuzzy ? ({}) : ({
|
||||||
@@ -77,6 +81,11 @@ Searcher {
|
|||||||
list: wallpapers.entries
|
list: wallpapers.entries
|
||||||
useFuzzy: true
|
useFuzzy: true
|
||||||
|
|
||||||
|
onPreviewColorLockChanged: {
|
||||||
|
if (!previewColorLock && pendingPreviewClear)
|
||||||
|
Colors.showPreview = false;
|
||||||
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
function set(path: string): void {
|
function set(path: string): void {
|
||||||
root.setWallpaper(path);
|
root.setWallpaper(path);
|
||||||
@@ -118,4 +127,17 @@ Searcher {
|
|||||||
path: Config.general.wallpaperPath
|
path: Config.general.wallpaperPath
|
||||||
recursive: true
|
recursive: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: previewColorsProc
|
||||||
|
|
||||||
|
command: ["zshell-cli", "scheme", "generate", "-p", "-i", root.previewPath]
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
Colors.load(text, true);
|
||||||
|
Colors.showPreview = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-31
@@ -3,24 +3,29 @@ pragma ComponentBehavior: Bound
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Modules
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Modules.SysTray
|
import qs.Modules.Bar.Components
|
||||||
import qs.Modules.Network
|
import qs.Modules.Bar.Popouts
|
||||||
import qs.Modules.Updates
|
|
||||||
|
|
||||||
RowLayout {
|
GridLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property bool fullscreen
|
required property bool fullscreen
|
||||||
|
required property bool horizontal
|
||||||
|
required property bool isHovered
|
||||||
required property Wrapper popouts
|
required property Wrapper popouts
|
||||||
required property ClipWrapper popoutsWrapper
|
required property ClipWrapper popoutsWrapper
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
readonly property int vPadding: 6
|
readonly property int vPadding: 6
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
function checkPopout(x: real): void {
|
function axisCenterOf(item: Item): real {
|
||||||
const ch = childAt(x, height / 2) as EntryWrapper;
|
const c = item.mapToItem(root, item.implicitWidth / 2, item.implicitHeight / 2);
|
||||||
|
return horizontal ? c.x : c.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPopout(pos: real): void {
|
||||||
|
const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper;
|
||||||
const id = ch?.entryId;
|
const id = ch?.entryId;
|
||||||
|
|
||||||
if (!ch || id === undefined) {
|
if (!ch || id === undefined) {
|
||||||
@@ -34,26 +39,21 @@ RowLayout {
|
|||||||
|
|
||||||
if (id === "statusIcons" && Config.bar.popouts.statusIcons) {
|
if (id === "statusIcons" && Config.bar.popouts.statusIcons) {
|
||||||
const items = (ch.item as StatusIcons).items;
|
const items = (ch.item as StatusIcons).items;
|
||||||
const localX = mapToItem(items, x, 0).x;
|
const icon = horizontal ? items.childAt(mapToItem(items, pos, 0).x, items.height / 2) : items.childAt(items.width / 2, mapToItem(items, 0, pos).y);
|
||||||
const icon = items.childAt(localX, items.height / 2);
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
popouts.currentName = icon.name;
|
popouts.currentName = icon.name;
|
||||||
popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, icon.implicitWidth / 2, 0).x);
|
popouts.currentCenter = Qt.binding(() => axisCenterOf(icon));
|
||||||
popouts.hasCurrent = true;
|
popouts.hasCurrent = true;
|
||||||
}
|
}
|
||||||
} else if (id === "tray" && Config.bar.popouts.tray && Config.bar.tray.showOnHover) {
|
} else if (id === "tray" && Config.bar.popouts.tray && Config.bar.tray.showOnHover) {
|
||||||
const tray = ch.item as TrayIcons;
|
const tray = ch.item as TrayIcons;
|
||||||
const layout = tray.layout;
|
const layout = tray.layout;
|
||||||
const localX = mapToItem(layout, x, 0).x;
|
const trayItem = horizontal ? layout.childAt(mapToItem(layout, pos, 0).x, layout.height / 2) : layout.childAt(tray.width / 2, mapToItem(layout, 0, pos).y);
|
||||||
const trayItem = layout.childAt(localX, layout.height / 2);
|
|
||||||
|
|
||||||
if (trayItem) {
|
if (trayItem) {
|
||||||
const idx = trayItem.index;
|
const idx = trayItem.index;
|
||||||
popouts.currentName = `traymenu${idx}`;
|
popouts.currentName = `traymenu${idx}`;
|
||||||
popouts.currentCenter = Qt.binding(() => {
|
popouts.currentCenter = Qt.binding(() => axisCenterOf(trayItem));
|
||||||
const it = tray.items.itemAt(idx);
|
|
||||||
return it ? it.mapToItem(root, it.implicitWidth / 2, 0).x : popouts.currentCenter;
|
|
||||||
});
|
|
||||||
popouts.hasCurrent = true;
|
popouts.hasCurrent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,12 +63,19 @@ RowLayout {
|
|||||||
|
|
||||||
if (id === "updates") {
|
if (id === "updates") {
|
||||||
popouts.currentName = "updates";
|
popouts.currentName = "updates";
|
||||||
popouts.currentCenter = Qt.binding(() => ch.item.mapToItem(root, (ch.item as Item).implicitWidth / 2, 0).x);
|
popouts.currentCenter = Qt.binding(() => axisCenterOf(ch.item as Item));
|
||||||
popouts.hasCurrent = true;
|
popouts.hasCurrent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing: Tokens.spacing.small
|
function entryAt(pos: real): string {
|
||||||
|
const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper;
|
||||||
|
return ch?.entryId ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
columnSpacing: Tokens.spacing.small
|
||||||
|
columns: horizontal ? -1 : 1
|
||||||
|
rowSpacing: Tokens.spacing.small
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
@@ -85,7 +92,8 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
HyprsunsetWidget {
|
HyprsunsetWidget {
|
||||||
visible: !root.fullscreen
|
horizontal: root.horizontal
|
||||||
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +102,8 @@ RowLayout {
|
|||||||
roleValue: "spacer"
|
roleValue: "spacer"
|
||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
Layout.fillWidth: true
|
Layout.fillHeight: !root.horizontal
|
||||||
|
Layout.fillWidth: root.horizontal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +112,9 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
Workspaces {
|
Workspaces {
|
||||||
|
horizontal: root.horizontal
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
visible: !root.fullscreen
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,9 +124,10 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
TrayIcons {
|
TrayIcons {
|
||||||
|
horizontal: root.horizontal
|
||||||
loader: root
|
loader: root
|
||||||
popouts: root.popouts
|
popouts: root.popouts
|
||||||
visible: !root.fullscreen
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +137,8 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
StatusIcons {
|
StatusIcons {
|
||||||
|
horizontal: root.horizontal
|
||||||
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,8 +148,9 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
Resources {
|
Resources {
|
||||||
|
horizontal: root.horizontal
|
||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
visible: !root.fullscreen
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +160,8 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
UpdatesWidget {
|
UpdatesWidget {
|
||||||
visible: !root.fullscreen
|
horizontal: root.horizontal
|
||||||
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,9 +171,10 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
NotifBell {
|
NotifBell {
|
||||||
|
horizontal: root.horizontal
|
||||||
popouts: root.popouts
|
popouts: root.popouts
|
||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
visible: !root.fullscreen
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,10 +184,11 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
Clock {
|
Clock {
|
||||||
|
horizontal: root.horizontal
|
||||||
loader: root
|
loader: root
|
||||||
popouts: root.popouts
|
popouts: root.popouts
|
||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
visible: !root.fullscreen
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +199,8 @@ RowLayout {
|
|||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
WindowTitle {
|
WindowTitle {
|
||||||
bar: root
|
bar: root
|
||||||
visible: !root.fullscreen
|
horizontal: root.horizontal
|
||||||
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,7 +219,8 @@ RowLayout {
|
|||||||
|
|
||||||
delegate: EntryWrapper {
|
delegate: EntryWrapper {
|
||||||
MediaWidget {
|
MediaWidget {
|
||||||
visible: !root.fullscreen
|
horizontal: root.horizontal
|
||||||
|
visible: !root.fullscreen || root.isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,9 +233,11 @@ RowLayout {
|
|||||||
default property Item item
|
default property Item item
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
|
||||||
Layout.leftMargin: index === 0 ? root.vPadding : (entryId === "statusIcons") ? -root.spacing + Tokens.spacing.extraSmall : 0
|
Layout.bottomMargin: !root.horizontal && index === repeater.count - 1 ? root.vPadding : 0
|
||||||
Layout.rightMargin: index === repeater.count - 1 ? root.vPadding : 0
|
Layout.leftMargin: root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && root.horizontal) ? -root.rowSpacing + Tokens.spacing.extraSmall : 0
|
||||||
|
Layout.rightMargin: root.horizontal && index === repeater.count - 1 ? root.vPadding : 0
|
||||||
|
Layout.topMargin: !root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && !root.horizontal) ? -root.columnSpacing + Tokens.spacing.extraSmall : 0
|
||||||
children: item
|
children: item
|
||||||
implicitHeight: item?.implicitHeight ?? 0
|
implicitHeight: item?.implicitHeight ?? 0
|
||||||
implicitWidth: item?.implicitWidth ?? 0
|
implicitWidth: item?.implicitWidth ?? 0
|
||||||
|
|||||||
+30
-22
@@ -1,45 +1,48 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
|
||||||
import qs.Components
|
|
||||||
import qs.Modules
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Helpers
|
import qs.Modules.Bar.Popouts
|
||||||
import qs.Modules.SysTray
|
import qs.Components
|
||||||
import qs.Modules.SysTray.Widgets
|
|
||||||
import qs.Modules.Network
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property int contentHeight: Config.bar.height + padding * 2
|
readonly property int clampedExtent: Math.max(Config.bar.border, extent)
|
||||||
readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentHeight
|
readonly property int contentThickness: Math.floor(Math.max(Config.bar.height, Tokens.bar.innerSize * (horizontal ? 1 : 1.5))) + padding * 2
|
||||||
|
readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentThickness
|
||||||
|
property real extent: fullscreen ? 0 : Config.bar.border
|
||||||
required property bool fullscreen
|
required property bool fullscreen
|
||||||
|
readonly property bool horizontal: position !== "left"
|
||||||
property bool isHovered
|
property bool isHovered
|
||||||
readonly property int padding: Math.max(Tokens.padding.smaller, Config.bar.border)
|
readonly property int padding: Math.max(Tokens.padding.small, Config.bar.border)
|
||||||
required property Wrapper popouts
|
required property Wrapper popouts
|
||||||
required property ClipWrapper popoutsWrapper
|
required property ClipWrapper popoutsWrapper
|
||||||
|
required property string position
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
readonly property bool shouldBeVisible: !fullscreen && (!Config.bar.autoHide || visibilities.bar || isHovered)
|
readonly property bool shouldBeVisible: (!fullscreen && (!Config.bar.autoHide || visibilities.bar)) || isHovered
|
||||||
readonly property int vPadding: 6
|
readonly property int vPadding: 6
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
function checkPopout(x: real): void {
|
function checkPopout(pos: real): void {
|
||||||
content.item?.checkPopout(x);
|
(content.item as Bar)?.checkPopout(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: fullscreen ? 0 : Config.bar.border
|
function entryAt(pos: real): string {
|
||||||
visible: height > Config.bar.border
|
return (content.item as Bar)?.entryAt(pos) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitHeight: extent
|
||||||
|
implicitWidth: extent
|
||||||
|
visible: extent > Config.bar.border
|
||||||
|
|
||||||
states: State {
|
states: State {
|
||||||
name: "visible"
|
name: "visible"
|
||||||
when: root.shouldBeVisible
|
when: root.shouldBeVisible
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
root.implicitHeight: root.contentHeight
|
root.extent: root.contentThickness
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transitions: [
|
transitions: [
|
||||||
@@ -48,7 +51,7 @@ Item {
|
|||||||
to: "visible"
|
to: "visible"
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
property: "implicitHeight"
|
property: "extent"
|
||||||
target: root
|
target: root
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -57,7 +60,7 @@ Item {
|
|||||||
to: ""
|
to: ""
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
property: "implicitHeight"
|
property: "extent"
|
||||||
target: root
|
target: root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,13 +70,18 @@ Item {
|
|||||||
id: content
|
id: content
|
||||||
|
|
||||||
active: root.shouldBeVisible || root.visible
|
active: root.shouldBeVisible || root.visible
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: root.position !== "bottom" ? parent.bottom : undefined
|
||||||
anchors.left: parent.left
|
anchors.left: root.horizontal ? parent.left : undefined
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
anchors.top: root.position !== "top" ? parent.top : undefined
|
||||||
|
height: root.contentThickness
|
||||||
|
width: root.contentThickness
|
||||||
|
|
||||||
sourceComponent: Bar {
|
sourceComponent: Bar {
|
||||||
fullscreen: root.fullscreen
|
fullscreen: root.fullscreen
|
||||||
height: root.contentHeight
|
height: root.contentThickness
|
||||||
|
horizontal: root.horizontal
|
||||||
|
isHovered: root.isHovered
|
||||||
popouts: root.popouts
|
popouts: root.popouts
|
||||||
popoutsWrapper: root.popoutsWrapper
|
popoutsWrapper: root.popoutsWrapper
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Modules.Bar.Popouts
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Components
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
WidgetBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property color contentColor: visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
|
readonly property string effectiveFormat: {
|
||||||
|
let fmt = Config.general.dateFormat;
|
||||||
|
if (!root.horizontal)
|
||||||
|
fmt = fmt.replace("dddd", "ddd");
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
readonly property var formatParts: {
|
||||||
|
const segments = root.effectiveFormat.split(" - ");
|
||||||
|
let datePart = "";
|
||||||
|
let timePart = "";
|
||||||
|
|
||||||
|
if (segments.length > 1) {
|
||||||
|
datePart = segments[0];
|
||||||
|
timePart = segments[1];
|
||||||
|
} else if (/[hms]/.test(segments[0])) {
|
||||||
|
timePart = segments[0];
|
||||||
|
} else {
|
||||||
|
datePart = segments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateTokens = datePart.trim().length ? datePart.trim().split(/\s+/) : [];
|
||||||
|
const timeTokens = timePart.trim().length ? timePart.trim().split(":") : [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
dateTokens: dateTokens,
|
||||||
|
timeTokens: timeTokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
required property GridLayout loader
|
||||||
|
required property Wrapper popouts
|
||||||
|
readonly property real size: horizontal ? timeText.contentWidth + Tokens.padding.small * 2 : verticalColumn.implicitHeight + Tokens.padding.small * 2
|
||||||
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
|
color: visibilities.dashboard ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
||||||
|
implicitHeight: horizontal ? baseSize : size
|
||||||
|
implicitWidth: horizontal ? size : baseSize
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: timeText
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: root.contentColor
|
||||||
|
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
|
||||||
|
height: implicitHeight
|
||||||
|
text: Time.dateStr
|
||||||
|
visible: root.horizontal
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: verticalColumn
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Tokens.padding.extraSmall ?? 2
|
||||||
|
visible: !root.horizontal
|
||||||
|
width: root.baseSize
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.formatParts.dateTokens
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
required property string modelData
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
color: root.contentColor
|
||||||
|
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
|
||||||
|
text: Qt.formatDateTime(Time.date, modelData)
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.bottomMargin: Tokens.padding.extraSmall ?? 2
|
||||||
|
Layout.topMargin: Tokens.padding.extraSmall ?? 2
|
||||||
|
color: root.contentColor
|
||||||
|
height: 1
|
||||||
|
implicitWidth: root.baseSize * 0.5
|
||||||
|
opacity: 0.4
|
||||||
|
radius: 1
|
||||||
|
visible: root.formatParts.dateTokens.length > 0 && root.formatParts.timeTokens.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.formatParts.timeTokens
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
required property string modelData
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
color: root.contentColor
|
||||||
|
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
|
||||||
|
text: {
|
||||||
|
if (modelData.includes("h"))
|
||||||
|
return Time.hourStr;
|
||||||
|
if (modelData.includes("m"))
|
||||||
|
return Time.minuteStr;
|
||||||
|
if (modelData.includes("s"))
|
||||||
|
return Time.secondStr;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
color: root.contentColor
|
||||||
|
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
|
||||||
|
text: Qt.formatDateTime(Time.date, "AP")
|
||||||
|
visible: Config.services.useTwelveHourClock && root.formatParts.timeTokens.length > 0
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
color: root.contentColor
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.visibilities.dashboard = !root.visibilities.dashboard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import QtQuick
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Services
|
||||||
|
import qs.Components
|
||||||
|
import qs.Helpers
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real batHeight: Tokens.padding.small * 2
|
||||||
|
property real batWidth: Tokens.padding.medium * 2
|
||||||
|
required property string devState
|
||||||
|
property real nubHeight: Tokens.padding.extraSmall
|
||||||
|
property real nubWidth: 2
|
||||||
|
required property real percentage
|
||||||
|
property real radius: Tokens.rounding.small / 2
|
||||||
|
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: track
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: Battery.getColors(root.percentage, root.devState).bg
|
||||||
|
height: root.batHeight
|
||||||
|
radius: root.radius
|
||||||
|
width: root.batWidth
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
color: Battery.getColors(root.percentage, root.devState).fg
|
||||||
|
font.pointSize: Tokens.font.size.larger / 1.5
|
||||||
|
font.weight: 800
|
||||||
|
height: track.height
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: Math.round(root.percentage * 100)
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: track.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
clip: true
|
||||||
|
width: parent.width * root.percentage
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: fill
|
||||||
|
|
||||||
|
color: Battery.getColors(root.percentage, root.devState).fg
|
||||||
|
height: track.height
|
||||||
|
radius: track.radius
|
||||||
|
width: track.width
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: batteryLabel
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
color: Battery.getColors(root.percentage, root.devState).bg
|
||||||
|
font.pointSize: Tokens.font.size.larger / 1.5
|
||||||
|
font.weight: 800
|
||||||
|
height: track.height
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: Math.round(root.percentage * 100)
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: track.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: nub
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
bottomRightRadius: 20
|
||||||
|
color: root.percentage < 0.99 ? track.color : fill.color
|
||||||
|
height: root.nubHeight
|
||||||
|
topRightRadius: 20
|
||||||
|
width: root.nubWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import QtQuick
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property int baseSize: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : Math.max(Config.bar.height, Math.floor(Tokens.bar.innerSize * 1.5))
|
||||||
|
required property bool horizontal
|
||||||
|
|
||||||
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
|
implicitHeight: horizontal ? baseSize : width
|
||||||
|
implicitWidth: horizontal ? height : baseSize
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
}
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Components
|
|
||||||
import qs.Helpers
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Helpers
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
CustomRect {
|
WidgetBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool tempEnabled: Hyprsunset.enabled
|
property bool tempEnabled: Hyprsunset.enabled
|
||||||
|
|
||||||
color: root.tempEnabled ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
color: root.tempEnabled ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
|
|
||||||
implicitWidth: implicitHeight
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
@@ -26,6 +25,7 @@ CustomRect {
|
|||||||
animate: true
|
animate: true
|
||||||
color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
fill: root.tempEnabled ? 1 : 0
|
fill: root.tempEnabled ? 1 : 0
|
||||||
|
font.pointSize: Tokens.font.size.larger
|
||||||
text: root.tempEnabled ? "lightbulb" : "light_off"
|
text: root.tempEnabled ? "lightbulb" : "light_off"
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
WidgetBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property string currentMedia: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
|
||||||
|
readonly property int textWidth: Math.min(metrics.width, 200)
|
||||||
|
|
||||||
|
implicitHeight: horizontal ? baseSize : layout.implicitHeight + Tokens.padding.small * 2
|
||||||
|
implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.small * 2 : baseSize
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
enabled: !root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
enabled: root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: metrics
|
||||||
|
|
||||||
|
font: mediatext.font
|
||||||
|
text: mediatext.text
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: layout
|
||||||
|
|
||||||
|
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.small
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: root.horizontal ? Tokens.padding.small : 0
|
||||||
|
anchors.rightMargin: root.horizontal ? Tokens.padding.small : 0
|
||||||
|
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.small
|
||||||
|
columns: root.horizontal ? -1 : 1
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
|
||||||
|
animate: true
|
||||||
|
color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface
|
||||||
|
font.pointSize: Tokens.font.size.larger
|
||||||
|
text: Players.active?.isPlaying ? "music_note" : "music_off"
|
||||||
|
}
|
||||||
|
|
||||||
|
MarqueeText {
|
||||||
|
id: mediatext
|
||||||
|
|
||||||
|
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
|
||||||
|
animate: true
|
||||||
|
color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface
|
||||||
|
font.pointSize: Tokens.font.size.normal
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
implicitHeight: root.horizontal ? root.implicitHeight : root.textWidth
|
||||||
|
implicitWidth: root.horizontal ? root.textWidth : root.implicitWidth
|
||||||
|
marqueeEnabled: false
|
||||||
|
pauseMs: 4000
|
||||||
|
text: root.currentMedia
|
||||||
|
vertical: !root.horizontal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (!containsMouse) {
|
||||||
|
mediatext.marqueeEnabled = false;
|
||||||
|
} else {
|
||||||
|
mediatext.marqueeEnabled = true;
|
||||||
|
mediatext.anim.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Modules.Bar.Popouts
|
||||||
import qs.Daemons
|
import qs.Daemons
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
CustomRect {
|
WidgetBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Wrapper popouts
|
required property Wrapper popouts
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
color: visibilities.sidebar ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
color: visibilities.sidebar ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
|
|
||||||
implicitWidth: implicitHeight
|
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
@@ -22,7 +22,6 @@ CustomRect {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: root.visibilities.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
color: root.visibilities.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
fill: root.visibilities.sidebar ? 1 : 0
|
fill: root.visibilities.sidebar ? 1 : 0
|
||||||
font.family: "Material Symbols Rounded"
|
|
||||||
font.pointSize: Tokens.font.size.larger
|
font.pointSize: Tokens.font.size.larger
|
||||||
text: NotifServer.list.length ? "\uf4fe" : "\ue7f4"
|
text: NotifServer.list.length ? "\uf4fe" : "\ue7f4"
|
||||||
|
|
||||||
@@ -5,13 +5,14 @@ import qs.Components
|
|||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
RowLayout {
|
GridLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property color accentColor: warning ? Colors.palette.m3error : mainColor
|
property color accentColor: warning ? Colors.palette.m3error : mainColor
|
||||||
property real animatedPercentage: 0
|
property real animatedPercentage: 0
|
||||||
readonly property real arcStartAngle: 0.75 * Math.PI
|
readonly property real arcStartAngle: 0.75 * Math.PI
|
||||||
readonly property real arcSweep: 1.5 * Math.PI
|
readonly property real arcSweep: 1.5 * Math.PI
|
||||||
|
required property bool horizontal
|
||||||
property string icon
|
property string icon
|
||||||
required property color iconColor
|
required property color iconColor
|
||||||
required property color mainColor
|
required property color mainColor
|
||||||
@@ -21,8 +22,9 @@ RowLayout {
|
|||||||
property bool warning: percentage * 100 >= warningThreshold
|
property bool warning: percentage * 100 >= warningThreshold
|
||||||
property int warningThreshold: 80
|
property int warningThreshold: 80
|
||||||
|
|
||||||
|
columnSpacing: Tokens.spacing.medium
|
||||||
|
columns: horizontal ? -1 : 1
|
||||||
percentage: 0
|
percentage: 0
|
||||||
spacing: Tokens.spacing.smaller
|
|
||||||
|
|
||||||
Behavior on animatedPercentage {
|
Behavior on animatedPercentage {
|
||||||
Anim {
|
Anim {
|
||||||
@@ -47,8 +49,8 @@ RowLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomClippingRect {
|
CustomClippingRect {
|
||||||
Layout.preferredHeight: root.height - Tokens.padding.small
|
Layout.preferredHeight: root.horizontal ? icon.implicitHeight - Tokens.padding.extraSmall : 4
|
||||||
Layout.preferredWidth: 4
|
Layout.preferredWidth: root.horizontal ? 4 : icon.implicitWidth
|
||||||
color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
|
color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
@@ -57,9 +59,11 @@ RowLayout {
|
|||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: root.horizontal ? parent.right : undefined
|
||||||
|
anchors.top: root.horizontal ? undefined : parent.top
|
||||||
color: root.mainColor
|
color: root.mainColor
|
||||||
implicitHeight: Math.ceil(root.percentage * parent.height)
|
implicitHeight: root.horizontal ? Math.ceil(root.percentage * parent.height) : 0
|
||||||
|
implicitWidth: root.horizontal ? 0 : Math.ceil(root.percentage * parent.width)
|
||||||
|
|
||||||
// Behavior on implicitHeight {
|
// Behavior on implicitHeight {
|
||||||
// Anim {
|
// Anim {
|
||||||
@@ -6,18 +6,18 @@ import QtQuick.Layouts
|
|||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import ZShell.Services
|
import ZShell.Services
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Modules
|
import qs.Modules.Bar.Components.Common
|
||||||
import qs.Components
|
import qs.Components
|
||||||
|
|
||||||
CustomRect {
|
WidgetBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
color: visibilities.resources ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
color: visibilities.resources ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
|
implicitHeight: horizontal ? baseSize : gridLayout.implicitHeight + Tokens.padding.medium * 2
|
||||||
implicitWidth: rowLayout.implicitWidth + Tokens.padding.larger * 2
|
implicitWidth: horizontal ? gridLayout.implicitWidth + Tokens.padding.medium * 2 : baseSize
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
@@ -26,13 +26,14 @@ CustomRect {
|
|||||||
onClicked: root.visibilities.resources = !root.visibilities.resources
|
onClicked: root.visibilities.resources = !root.visibilities.resources
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
GridLayout {
|
||||||
id: rowLayout
|
id: gridLayout
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.horizontalCenterOffset: -2
|
anchors.horizontalCenterOffset: root.horizontal ? 0 : 1
|
||||||
implicitHeight: root.implicitHeight
|
anchors.verticalCenterOffset: root.horizontal ? 0 : -3
|
||||||
spacing: Tokens.spacing.smaller
|
columnSpacing: Tokens.spacing.small
|
||||||
|
columns: root.horizontal ? -1 : 1
|
||||||
|
|
||||||
ServiceRef {
|
ServiceRef {
|
||||||
service: Gpu
|
service: Gpu
|
||||||
@@ -48,7 +49,9 @@ CustomRect {
|
|||||||
|
|
||||||
Resource {
|
Resource {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: root.horizontal
|
||||||
|
Layout.fillWidth: !root.horizontal
|
||||||
|
horizontal: root.horizontal
|
||||||
icon: "memory"
|
icon: "memory"
|
||||||
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3primary
|
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3primary
|
||||||
@@ -57,7 +60,9 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Resource {
|
Resource {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: root.horizontal
|
||||||
|
Layout.fillWidth: !root.horizontal
|
||||||
|
horizontal: root.horizontal
|
||||||
icon: "memory_alt"
|
icon: "memory_alt"
|
||||||
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3secondary
|
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3secondary
|
||||||
@@ -66,7 +71,9 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Resource {
|
Resource {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: root.horizontal
|
||||||
|
Layout.fillWidth: !root.horizontal
|
||||||
|
horizontal: root.horizontal
|
||||||
icon: "gamepad"
|
icon: "gamepad"
|
||||||
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3tertiary
|
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3tertiary
|
||||||
@@ -74,7 +81,9 @@ CustomRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Resource {
|
Resource {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: root.horizontal
|
||||||
|
Layout.fillWidth: !root.horizontal
|
||||||
|
horizontal: root.horizontal
|
||||||
icon: "developer_board"
|
icon: "developer_board"
|
||||||
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3primary
|
mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3primary
|
||||||
@@ -3,13 +3,14 @@ pragma ComponentBehavior: Bound
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Helpers
|
|
||||||
import qs.Modules.SysTray.Widgets
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Modules.Bar.Components.StatusIcons
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
CustomClippingRect {
|
WidgetBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property int firstPresent: {
|
readonly property int firstPresent: {
|
||||||
@@ -21,7 +22,7 @@ CustomClippingRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Index of the first/last entry that isn't collapsed, for edge margin gating
|
// Index of the first/last entry that isn't collapsed, for edge margin gating
|
||||||
readonly property alias items: row
|
readonly property alias items: grid
|
||||||
readonly property int lastPresent: {
|
readonly property int lastPresent: {
|
||||||
const values = model.values;
|
const values = model.values;
|
||||||
for (let i = values.length - 1; i >= 0; i--)
|
for (let i = values.length - 1; i >= 0; i--)
|
||||||
@@ -29,7 +30,8 @@ CustomClippingRect {
|
|||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
readonly property int spacing: Tokens.spacing.normal / 2
|
readonly property real size: horizontal ? grid.implicitWidth + grid.anchors.leftMargin + grid.anchors.rightMargin : grid.implicitHeight + grid.anchors.bottomMargin + grid.anchors.topMargin
|
||||||
|
readonly property int spacing: Tokens.spacing.medium / 2
|
||||||
|
|
||||||
// Entries that can shrink to nothing, spacing included
|
// Entries that can shrink to nothing, spacing included
|
||||||
function collapsed(entry: var): bool {
|
function collapsed(entry: var): bool {
|
||||||
@@ -38,19 +40,36 @@ CustomClippingRect {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bottomLeftRadius: Tokens.rounding.smallest / 2
|
bottomLeftRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
|
implicitHeight: horizontal ? baseSize : size
|
||||||
implicitWidth: row.implicitWidth + Tokens.padding.small * 2
|
implicitWidth: horizontal ? size : baseSize
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
topLeftRadius: Tokens.rounding.smallest / 2
|
topLeftRadius: Tokens.rounding.small / 2
|
||||||
|
topRightRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.small / 2
|
||||||
|
|
||||||
RowLayout {
|
Behavior on implicitHeight {
|
||||||
id: row
|
enabled: !root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
enabled: root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: grid
|
||||||
|
|
||||||
|
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Tokens.padding.small
|
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
|
||||||
anchors.rightMargin: Tokens.padding.small
|
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
|
||||||
|
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
|
||||||
|
columns: root.horizontal ? -1 : 1
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
@@ -69,6 +88,7 @@ CustomClippingRect {
|
|||||||
name: "audio"
|
name: "audio"
|
||||||
|
|
||||||
AudioWidget {
|
AudioWidget {
|
||||||
|
horizontal: root.horizontal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,6 +100,7 @@ CustomClippingRect {
|
|||||||
name: "audio"
|
name: "audio"
|
||||||
|
|
||||||
MicWidget {
|
MicWidget {
|
||||||
|
horizontal: root.horizontal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,8 +130,10 @@ CustomClippingRect {
|
|||||||
property real rightGap: present && index !== root.firstPresent ? margin : 0
|
property real rightGap: present && index !== root.firstPresent ? margin : 0
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.leftMargin: Math.round(leftGap)
|
Layout.bottomMargin: root.horizontal ? 0 : Math.round(rightGap)
|
||||||
Layout.rightMargin: Math.round(rightGap)
|
Layout.leftMargin: root.horizontal ? Math.round(leftGap) : 0
|
||||||
|
Layout.rightMargin: root.horizontal ? Math.round(rightGap) : 0
|
||||||
|
Layout.topMargin: root.horizontal ? 0 : Math.round(leftGap)
|
||||||
children: item
|
children: item
|
||||||
implicitHeight: item?.implicitHeight ?? 0
|
implicitHeight: item?.implicitHeight ?? 0
|
||||||
implicitWidth: item?.implicitWidth ?? 0
|
implicitWidth: item?.implicitWidth ?? 0
|
||||||
+3
-4
@@ -1,16 +1,15 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell.Io
|
|
||||||
import Quickshell.Services.Pipewire
|
|
||||||
import qs.Daemons
|
|
||||||
import qs.Modules
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Daemons
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: speaker
|
id: speaker
|
||||||
|
|
||||||
|
required property bool horizontal
|
||||||
|
|
||||||
animate: true
|
animate: true
|
||||||
color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3onSurface
|
color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3onSurface
|
||||||
fill: 1
|
fill: 1
|
||||||
+3
-4
@@ -1,16 +1,15 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell.Io
|
|
||||||
import Quickshell.Services.Pipewire
|
|
||||||
import qs.Daemons
|
|
||||||
import qs.Modules
|
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Daemons
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: mic
|
id: mic
|
||||||
|
|
||||||
|
required property bool horizontal
|
||||||
|
|
||||||
animate: true
|
animate: true
|
||||||
color: (Audio.sourceMuted ?? false) ? Colors.palette.m3error : Colors.palette.m3onSurface
|
color: (Audio.sourceMuted ?? false) ? Colors.palette.m3error : Colors.palette.m3onSurface
|
||||||
fill: 1
|
fill: 1
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import Quickshell.Services.UPower
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Components
|
||||||
|
import qs.Helpers
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property Item currentItem: batteryIconLoader?.item ?? peripheralIconLoader?.item ?? upowerIconLoader.item
|
||||||
|
|
||||||
|
implicitHeight: currentItem?.implicitHeight ?? 0
|
||||||
|
implicitWidth: currentItem?.implicitWidth ?? 0
|
||||||
|
|
||||||
|
Behavior on Layout.preferredHeight {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on Layout.preferredWidth {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on scale {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: Battery.startDaemon()
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: batteryIconLoader
|
||||||
|
|
||||||
|
active: Battery.isLaptop
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
sourceComponent: BatteryIcon {
|
||||||
|
devState: Battery.deviceStateString.toLowerCase()
|
||||||
|
percentage: Battery.currentPerc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: peripheralIconLoader
|
||||||
|
|
||||||
|
active: (Battery.lowestPeripheral?.isPresent ?? false) && !batteryIconLoader.active
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
sourceComponent: BatteryIcon {
|
||||||
|
devState: Battery.lowestPeripheral?.state ?? ""
|
||||||
|
percentage: Battery.lowestPeripheral?.percentage ?? 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: upowerIconLoader
|
||||||
|
|
||||||
|
active: !batteryIconLoader.active && !peripheralIconLoader.active
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
sourceComponent: MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
animate: true
|
||||||
|
fill: 1
|
||||||
|
font.pointSize: Tokens.font.size.larger
|
||||||
|
text: {
|
||||||
|
if (PowerProfiles.profile === PowerProfile.PowerSaver)
|
||||||
|
return "energy_savings_leaf";
|
||||||
|
if (PowerProfiles.profile === PowerProfile.Performance)
|
||||||
|
return "bolt";
|
||||||
|
return "balance";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.VectorImage
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.SystemTray
|
import Quickshell.Services.SystemTray
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Modules
|
import qs.Modules.Bar.Popouts
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Services
|
import qs.Services
|
||||||
@@ -13,10 +12,10 @@ Item {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool current: popouts.currentName.startsWith(`traymenu${ind}`) && popouts.hasCurrent
|
property bool current: popouts.currentName.startsWith(`traymenu${ind}`) && popouts.hasCurrent
|
||||||
readonly property real dpr: Hypr.monitorFor(loader.screen).scale
|
readonly property real dpr: Hypr.monitorFor(loader?.screen).scale
|
||||||
required property int ind
|
required property int ind
|
||||||
required property SystemTrayItem item
|
required property SystemTrayItem item
|
||||||
required property RowLayout loader
|
required property GridLayout loader
|
||||||
required property Wrapper popouts
|
required property Wrapper popouts
|
||||||
|
|
||||||
function resolveIcon(app: string, icon: string): string {
|
function resolveIcon(app: string, icon: string): string {
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell.Services.SystemTray
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Modules.Bar.Components.Tray
|
||||||
|
import qs.Modules.Bar.Popouts
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
WidgetBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property alias items: repeater
|
||||||
|
readonly property alias layout: sysGrid
|
||||||
|
required property GridLayout loader
|
||||||
|
readonly property int padding: Tokens.padding.extraSmall
|
||||||
|
required property Wrapper popouts
|
||||||
|
readonly property real size: horizontal ? sysGrid.implicitWidth + sysGrid.anchors.leftMargin + sysGrid.anchors.rightMargin : sysGrid.implicitHeight + sysGrid.anchors.topMargin + sysGrid.anchors.bottomMargin
|
||||||
|
|
||||||
|
bottomLeftRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.small / 2
|
||||||
|
bottomRightRadius: Tokens.rounding.small / 2
|
||||||
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
|
implicitHeight: horizontal ? baseSize : size
|
||||||
|
implicitWidth: horizontal ? size : baseSize
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
topRightRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: sysGrid
|
||||||
|
|
||||||
|
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
|
||||||
|
anchors.centerIn: parent
|
||||||
|
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
|
||||||
|
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
|
||||||
|
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
|
||||||
|
columns: root.horizontal ? -1 : 1
|
||||||
|
rowSpacing: -2
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
|
||||||
|
model: SystemTray.items
|
||||||
|
|
||||||
|
TrayItem {
|
||||||
|
id: trayItem
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property SystemTrayItem modelData
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
implicitHeight: 34
|
||||||
|
implicitWidth: 34
|
||||||
|
ind: index
|
||||||
|
item: modelData
|
||||||
|
loader: root.loader
|
||||||
|
popouts: root.popouts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
WidgetBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int countUpdates: Updates.availableUpdates
|
||||||
|
property color textColor: Colors.palette.m3onSurface
|
||||||
|
|
||||||
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
|
implicitHeight: horizontal ? baseSize : content.implicitHeight + Tokens.spacing.small
|
||||||
|
implicitWidth: horizontal ? content.implicitWidth + Tokens.spacing.small * 2 : baseSize
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
columnSpacing: Tokens.spacing.small
|
||||||
|
columns: root.horizontal ? -1 : 1
|
||||||
|
rowSpacing: -Tokens.spacing.extraSmall / 2
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
|
||||||
|
font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large
|
||||||
|
text: "package_2"
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
|
||||||
|
color: root.textColor
|
||||||
|
font.pointSize: Tokens.font.size.normal
|
||||||
|
text: root.countUpdates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var bar
|
||||||
|
property color color: Colors.palette.m3primary
|
||||||
|
property Title current: text1
|
||||||
|
required property bool horizontal
|
||||||
|
// readonly property int maxWidth: 300
|
||||||
|
readonly property int maxSize: {
|
||||||
|
const otherModules = bar.children.filter(c => c.enabled && c.entryId && c.item !== this && c.entryId !== "spacer");
|
||||||
|
const otherSize = otherModules.reduce((acc, curr) => acc + (horizontal ? (curr.item?.nonAnimWidth ?? curr.width ?? 0) : (curr.item.nonAnimHeight ?? curr.height ?? 0)), 0);
|
||||||
|
return horizontal ? (bar.width - otherSize - bar.columnSpacing * (bar.children.length - 1) - bar.vPadding * 2) : (bar.height - otherSize - bar.rowSpacing * (bar.children.length - 1) - bar.vPadding * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
implicitHeight: horizontal ? current.implicitHeight : current.implicitWidth + current.anchors.topMargin
|
||||||
|
implicitWidth: horizontal ? current.implicitWidth + current.anchors.leftMargin : current.implicitHeight + current.anchors.topMargin
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
enabled: !root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
enabled: root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Title {
|
||||||
|
id: text1
|
||||||
|
}
|
||||||
|
|
||||||
|
Title {
|
||||||
|
id: text2
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: metrics
|
||||||
|
|
||||||
|
elide: Qt.ElideRight
|
||||||
|
elideWidth: root.maxSize - (root.horizontal ? root.current.anchors.leftMargin : 0)
|
||||||
|
font.family: "Rubik"
|
||||||
|
font.pointSize: Tokens.font.size.normal
|
||||||
|
text: Hypr.activeToplevel?.title ?? qsTr("Desktop")
|
||||||
|
|
||||||
|
onElideWidthChanged: root.current.text = elidedText
|
||||||
|
onTextChanged: {
|
||||||
|
const next = root.current === text1 ? text2 : text1;
|
||||||
|
next.text = elidedText;
|
||||||
|
root.current = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Title: CustomText {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
anchors.horizontalCenter: root.horizontal ? undefined : parent.horizontalCenter
|
||||||
|
anchors.left: root.horizontal ? parent.left : undefined
|
||||||
|
anchors.leftMargin: root.horizontal ? Tokens.spacing.small : 0
|
||||||
|
anchors.top: root.horizontal ? undefined : parent.top
|
||||||
|
anchors.topMargin: root.horizontal ? 0 : Tokens.spacing.small
|
||||||
|
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
|
||||||
|
color: root.color
|
||||||
|
font.family: metrics.font.family
|
||||||
|
font.pointSize: metrics.font.pointSize
|
||||||
|
height: root.horizontal ? implicitHeight : implicitWidth
|
||||||
|
opacity: root.current === this ? 1 : 0
|
||||||
|
width: root.horizontal ? implicitWidth : implicitHeight
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transform: [
|
||||||
|
Translate {
|
||||||
|
x: !root.horizontal ? -text.implicitWidth + text.implicitHeight : 0
|
||||||
|
},
|
||||||
|
Rotation {
|
||||||
|
angle: root.horizontal ? 0 : 270
|
||||||
|
origin.x: text.implicitHeight / 2
|
||||||
|
origin.y: text.implicitHeight / 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,53 +2,69 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Effects
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Modules.Bar.Components.Workspaces
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property real activeWorkspaceMargin: Math.ceil(Tokens.padding.small / 2)
|
property real activeWorkspaceMargin: Math.ceil(Tokens.padding.medium / 4)
|
||||||
readonly property int effectiveActiveWorkspaceId: monitor?.activeWorkspace?.id ?? 1
|
readonly property int effectiveActiveWorkspaceId: monitor?.activeWorkspace?.id ?? 1
|
||||||
|
required property bool horizontal
|
||||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen)
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen)
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
property int workspaceButtonWidth: bgRect.implicitHeight - root.activeWorkspaceMargin * 2
|
readonly property real shortSize: Math.max(Config.bar.height, Tokens.bar.innerSize)
|
||||||
|
readonly property real size: (workspaceButtonWidth * workspacesShown) + activeWorkspaceMargin * 2
|
||||||
|
property int workspaceButtonWidth: (horizontal ? bgRect.implicitHeight : bgRect.implicitWidth) - root.activeWorkspaceMargin * 2
|
||||||
property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown
|
property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown
|
||||||
readonly property list<var> workspaces: Hyprland.workspaces.values.filter(w => w.monitor === root.monitor)
|
readonly property list<var> workspaces: Hyprland.workspaces.values.filter(w => w.monitor === root.monitor)
|
||||||
readonly property int workspacesShown: workspaces.length
|
readonly property int workspacesShown: workspaces.length
|
||||||
|
|
||||||
height: implicitHeight
|
implicitHeight: horizontal ? shortSize : size
|
||||||
implicitHeight: Config.bar.height + Tokens.padding.smaller * 2
|
implicitWidth: horizontal ? size : shortSize
|
||||||
implicitWidth: (root.workspaceButtonWidth * root.workspacesShown) + root.activeWorkspaceMargin * 2
|
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
enabled: !root.horizontal
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
Behavior on implicitWidth {
|
Behavior on implicitWidth {
|
||||||
|
enabled: root.horizontal
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
|
// qmllint disable Quick.anchor-combinations
|
||||||
id: bgRect
|
id: bgRect
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.bottom: root.horizontal ? undefined : parent.bottom
|
||||||
anchors.right: parent.right
|
anchors.horizontalCenter: root.horizontal ? undefined : parent.horizontalCenter
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.left: root.horizontal ? parent.left : undefined
|
||||||
|
anchors.right: root.horizontal ? parent.right : undefined
|
||||||
|
anchors.top: root.horizontal ? undefined : parent.top
|
||||||
|
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: root.implicitHeight - ((Tokens.padding.small - 1) * 2)
|
implicitHeight: root.horizontal ? root.implicitHeight : 0
|
||||||
|
implicitWidth: root.horizontal ? 0 : root.implicitWidth
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
|
|
||||||
|
// qmllint enable Quick.anchor-combinations
|
||||||
Grid {
|
Grid {
|
||||||
id: grid
|
id: grid
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: root.activeWorkspaceMargin
|
anchors.margins: root.activeWorkspaceMargin
|
||||||
columnSpacing: 0
|
columnSpacing: 0
|
||||||
columns: root.workspacesShown
|
columns: root.horizontal ? root.workspacesShown : 1
|
||||||
rowSpacing: 0
|
rowSpacing: 0
|
||||||
rows: 1
|
rows: root.horizontal ? 1 : root.workspacesShown
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.workspaces
|
model: root.workspaces
|
||||||
@@ -74,7 +90,7 @@ Item {
|
|||||||
color: Colors.palette.m3onSecondaryContainer
|
color: Colors.palette.m3onSecondaryContainer
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
text: button.modelData.name
|
text: button.modelData?.name ?? ""
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,13 +110,15 @@ Item {
|
|||||||
property real indicatorPosition: Math.min(idxPair.idx1, idxPair.idx2) * root.workspaceButtonWidth + root.activeWorkspaceMargin
|
property real indicatorPosition: Math.min(idxPair.idx1, idxPair.idx2) * root.workspaceButtonWidth + root.activeWorkspaceMargin
|
||||||
property real indicatorThickness: root.workspaceButtonWidth
|
property real indicatorThickness: root.workspaceButtonWidth
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.horizontalCenter: root.horizontal ? undefined : parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
|
||||||
clip: true
|
clip: true
|
||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
implicitHeight: indicatorThickness
|
implicitHeight: root.horizontal ? indicatorThickness : indicatorLength
|
||||||
implicitWidth: indicatorLength
|
implicitWidth: root.horizontal ? indicatorLength : indicatorThickness
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
x: indicatorPosition
|
x: root.horizontal ? indicatorPosition : 0
|
||||||
|
y: root.horizontal ? 0 : indicatorPosition
|
||||||
|
|
||||||
AnimatedTabIndexPair {
|
AnimatedTabIndexPair {
|
||||||
id: idxPair
|
id: idxPair
|
||||||
@@ -114,7 +132,8 @@ Item {
|
|||||||
implicitWidth: grid.width
|
implicitWidth: grid.width
|
||||||
source: grid
|
source: grid
|
||||||
sourceColor: Colors.palette.m3onSurface
|
sourceColor: Colors.palette.m3onSurface
|
||||||
x: -indicator.x + 3
|
x: root.horizontal ? -indicator.x + 3 : 0
|
||||||
|
y: root.horizontal ? 0 : -indicator.y + 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,12 +15,13 @@ import qs.Services
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property int rounding: Tokens.rounding.small - Tokens.padding.small
|
readonly property int panelRadius: Tokens.rounding.largeIncreased + Tokens.padding.smaller
|
||||||
|
readonly property int rounding: panelRadius - Tokens.padding.smaller
|
||||||
readonly property int topMargin: 0
|
readonly property int topMargin: 0
|
||||||
required property var wrapper
|
required property var wrapper
|
||||||
|
|
||||||
implicitHeight: vol.implicitHeight + Tokens.padding.small * 2
|
implicitHeight: vol.implicitHeight + Tokens.padding.smaller * 2
|
||||||
implicitWidth: 500 + Tokens.padding.small * 2
|
implicitWidth: 500 + Tokens.padding.smaller * 2
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -28,7 +29,7 @@ Item {
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: parent.implicitHeight
|
implicitHeight: parent.implicitHeight
|
||||||
radius: Tokens.rounding.small
|
radius: root.rounding
|
||||||
y: parent.y
|
y: parent.y
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
@@ -41,7 +42,7 @@ Item {
|
|||||||
id: vol
|
id: vol
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.margins: Tokens.padding.small
|
anchors.margins: Tokens.padding.smaller
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -51,17 +52,17 @@ Item {
|
|||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2
|
Layout.preferredHeight: 65 + Tokens.spacing.small * 2
|
||||||
Layout.topMargin: root.topMargin
|
Layout.topMargin: root.topMargin
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
radius: root.rounding
|
radius: root.rounding - vol.anchors.margins
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.bottomMargin: Tokens.padding.smaller
|
anchors.bottomMargin: Tokens.padding.small
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Tokens.padding.larger
|
anchors.leftMargin: Tokens.padding.small
|
||||||
anchors.rightMargin: Tokens.padding.larger
|
anchors.rightMargin: Tokens.padding.small
|
||||||
anchors.topMargin: Tokens.padding.smaller
|
anchors.topMargin: Tokens.padding.small
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
@@ -82,12 +83,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
CustomMouseArea {
|
CustomMouseArea {
|
||||||
Layout.bottomMargin: Tokens.padding.normal
|
Layout.bottomMargin: Tokens.padding.small
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Tokens.padding.larger * 3
|
Layout.preferredHeight: Tokens.padding.medium * 3
|
||||||
|
|
||||||
CustomSlider {
|
CustomSlider {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -109,7 +110,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomSwitch {
|
CustomSwitch {
|
||||||
Layout.bottomMargin: Tokens.padding.normal
|
Layout.bottomMargin: Tokens.padding.small
|
||||||
checked: !Audio.muted
|
checked: !Audio.muted
|
||||||
|
|
||||||
onToggled: {
|
onToggled: {
|
||||||
@@ -124,10 +125,10 @@ Item {
|
|||||||
|
|
||||||
CustomClippingRect {
|
CustomClippingRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2
|
Layout.preferredHeight: 65 + Tokens.spacing.small * 2
|
||||||
Layout.topMargin: root.topMargin
|
Layout.topMargin: root.topMargin
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
radius: root.rounding
|
radius: root.rounding - vol.anchors.margins
|
||||||
|
|
||||||
PwNodePeakMonitor {
|
PwNodePeakMonitor {
|
||||||
id: sourcePeak
|
id: sourcePeak
|
||||||
@@ -151,11 +152,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.bottomMargin: Tokens.padding.smaller
|
anchors.bottomMargin: Tokens.padding.small
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Tokens.padding.larger
|
anchors.leftMargin: Tokens.padding.small
|
||||||
anchors.rightMargin: Tokens.padding.larger
|
anchors.rightMargin: Tokens.padding.small
|
||||||
anchors.topMargin: Tokens.padding.smaller
|
anchors.topMargin: Tokens.padding.small
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
@@ -176,12 +177,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
CustomMouseArea {
|
CustomMouseArea {
|
||||||
Layout.bottomMargin: Tokens.padding.normal
|
Layout.bottomMargin: Tokens.padding.small
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Tokens.padding.larger * 3
|
Layout.preferredHeight: Tokens.padding.medium * 3
|
||||||
|
|
||||||
CustomSlider {
|
CustomSlider {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -203,7 +204,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomSwitch {
|
CustomSwitch {
|
||||||
Layout.bottomMargin: Tokens.padding.normal
|
Layout.bottomMargin: Tokens.padding.small
|
||||||
checked: !Audio.sourceMuted
|
checked: !Audio.sourceMuted
|
||||||
|
|
||||||
onToggled: {
|
onToggled: {
|
||||||
@@ -236,10 +237,10 @@ Item {
|
|||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2
|
Layout.preferredHeight: 65 + Tokens.spacing.small * 2
|
||||||
Layout.topMargin: root.topMargin
|
Layout.topMargin: root.topMargin
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
radius: root.rounding
|
radius: root.rounding - vol.anchors.margins
|
||||||
|
|
||||||
PwNodePeakMonitor {
|
PwNodePeakMonitor {
|
||||||
id: peak
|
id: peak
|
||||||
@@ -271,11 +272,11 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.bottomMargin: Tokens.padding.smaller
|
anchors.bottomMargin: Tokens.padding.small
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Tokens.padding.larger
|
anchors.leftMargin: Tokens.padding.small
|
||||||
anchors.rightMargin: Tokens.padding.larger
|
anchors.rightMargin: Tokens.padding.small
|
||||||
anchors.topMargin: Tokens.padding.smaller
|
anchors.topMargin: Tokens.padding.small
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
@@ -297,12 +298,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Tokens.spacing.large
|
spacing: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
CustomMouseArea {
|
CustomMouseArea {
|
||||||
Layout.bottomMargin: Tokens.padding.normal
|
Layout.bottomMargin: Tokens.padding.small
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Tokens.padding.larger * 3
|
Layout.preferredHeight: Tokens.padding.medium * 3
|
||||||
|
|
||||||
CustomSlider {
|
CustomSlider {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -324,7 +325,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomSwitch {
|
CustomSwitch {
|
||||||
Layout.bottomMargin: Tokens.padding.normal
|
Layout.bottomMargin: Tokens.padding.small
|
||||||
checked: !appBox.modelData.audio.muted
|
checked: !appBox.modelData.audio.muted
|
||||||
|
|
||||||
onToggled: {
|
onToggled: {
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Components
|
||||||
|
import ZShell.Config
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property real borderThickness
|
||||||
|
readonly property alias content: content
|
||||||
|
readonly property bool horizontal: position !== "left"
|
||||||
|
// property real offsetScale: y > 0 || content.hasCurrent ? 0 : 1
|
||||||
|
property real offsetScale: {
|
||||||
|
if (content.hasCurrent)
|
||||||
|
return 0;
|
||||||
|
if (position === "top")
|
||||||
|
return y > 0 ? 0 : 1;
|
||||||
|
if (position === "bottom")
|
||||||
|
return 1;
|
||||||
|
return x > 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
required property string position
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
anchors.bottom: position === "bottom" ? parent.bottom : undefined
|
||||||
|
clip: true
|
||||||
|
implicitHeight: horizontal ? content.implicitHeight * (1 - offsetScale) : content.implicitHeight
|
||||||
|
implicitWidth: horizontal ? content.implicitWidth : content.implicitWidth * (1 - offsetScale)
|
||||||
|
visible: width > 0 && height > 0
|
||||||
|
x: {
|
||||||
|
if (!horizontal)
|
||||||
|
return 0;
|
||||||
|
const off = content.currentCenter - borderThickness - content.nonAnimWidth / 2;
|
||||||
|
const diff = parent.width - Math.floor(off + content.nonAnimWidth);
|
||||||
|
if (diff < 0)
|
||||||
|
return off + diff;
|
||||||
|
return Math.floor(Math.max(off, 0));
|
||||||
|
}
|
||||||
|
y: {
|
||||||
|
if (horizontal)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const off = content.currentCenter - borderThickness - content.nonAnimHeight / 2;
|
||||||
|
const diff = parent.height - Math.floor(off + content.nonAnimHeight);
|
||||||
|
if (diff < 0)
|
||||||
|
return off + diff;
|
||||||
|
return Math.max(off, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on offsetScale {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on x {
|
||||||
|
enabled: !root.horizontal || root.offsetScale < 1
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: content.animLength
|
||||||
|
easing: content.animCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on y {
|
||||||
|
enabled: root.horizontal || root.offsetScale < 1
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: content.animLength
|
||||||
|
easing: content.animCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Wrapper {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.bottom: root.position === "bottom" ? parent.bottom : undefined
|
||||||
|
anchors.bottomMargin: (-implicitHeight - 5) * root.offsetScale
|
||||||
|
anchors.horizontalCenter: root.horizontal ? parent.horizontalCenter : undefined
|
||||||
|
anchors.left: root.horizontal ? undefined : parent.left
|
||||||
|
anchors.leftMargin: (-implicitWidth - 5) * root.offsetScale
|
||||||
|
anchors.top: root.position === "top" ? parent.top : undefined
|
||||||
|
anchors.topMargin: (-implicitHeight - 5) * root.offsetScale
|
||||||
|
anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter
|
||||||
|
horizontal: root.horizontal
|
||||||
|
offsetScale: root.offsetScale
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,20 +5,17 @@ import Quickshell.Services.SystemTray
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Modules.WSOverview
|
|
||||||
import qs.Modules.Network
|
|
||||||
import qs.Modules.SysTray.Popouts
|
|
||||||
import qs.Modules.Updates
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property Item current: currentPopout?.item ?? null
|
readonly property Item current: currentPopout?.item ?? null
|
||||||
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
||||||
|
required property bool horizontal
|
||||||
required property PopoutState popouts
|
required property PopoutState popouts
|
||||||
|
|
||||||
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.small * 2
|
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.smaller * 2
|
||||||
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.small * 2
|
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.smaller * 2
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: content
|
id: content
|
||||||
@@ -73,6 +70,7 @@ Item {
|
|||||||
name: "upower"
|
name: "upower"
|
||||||
|
|
||||||
sourceComponent: UPowerPopout {
|
sourceComponent: UPowerPopout {
|
||||||
|
horizontal: root.horizontal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,10 +98,10 @@ Item {
|
|||||||
readonly property bool shouldBeActive: root.popouts.currentName === name
|
readonly property bool shouldBeActive: root.popouts.currentName === name
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
// anchors.horizontalCenter: parent.horizontalCenter
|
anchors.centerIn: opacity === 1 ? undefined : parent
|
||||||
// anchors.top: parent.top
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
// anchors.topMargin: 5
|
anchors.top: opacity === 1 ? parent.top : undefined
|
||||||
anchors.centerIn: parent
|
anchors.topMargin: Tokens.padding.smaller
|
||||||
opacity: 0
|
opacity: 0
|
||||||
scale: 0.8
|
scale: 0.8
|
||||||
|
|
||||||
+14
-14
@@ -15,7 +15,7 @@ StackView {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property int itemHeight: 30
|
readonly property int itemHeight: 30
|
||||||
readonly property int panelRadius: ((itemHeight / 2) + Tokens.padding.small) * Tokens.rounding.scale
|
readonly property int panelRadius: ((itemHeight / 2) + Tokens.padding.extraSmall) * Tokens.rounding.scale
|
||||||
required property PopoutState popouts
|
required property PopoutState popouts
|
||||||
property int rootWidth: 0
|
property int rootWidth: 0
|
||||||
required property QsMenuHandle trayItem
|
required property QsMenuHandle trayItem
|
||||||
@@ -88,10 +88,10 @@ StackView {
|
|||||||
required property QsMenuEntry modelData
|
required property QsMenuEntry modelData
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: modelData.isSeparator ? Tokens.padding.normal : 0
|
Layout.leftMargin: modelData?.isSeparator ?? false ? Tokens.padding.small : 0
|
||||||
Layout.rightMargin: modelData.isSeparator ? Tokens.padding.normal : 0
|
Layout.rightMargin: modelData?.isSeparator ?? false ? Tokens.padding.small : 0
|
||||||
color: modelData.isSeparator ? Colors.palette.m3outlineVariant : "transparent"
|
color: modelData?.isSeparator ?? false ? Colors.palette.m3outlineVariant : "transparent"
|
||||||
implicitHeight: modelData.isSeparator ? (visible ? 1 : 0) : childrenLoader.item.implicitHeight
|
implicitHeight: modelData?.isSeparator ?? false ? (visible ? 1 : 0) : childrenLoader.item?.implicitHeight ?? 0
|
||||||
implicitWidth: childrenLoader.item?.implicitWidth ?? 0
|
implicitWidth: childrenLoader.item?.implicitWidth ?? 0
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
visible: index !== (menuOpener.children.values.length - 1) ? true : (modelData.isSeparator ? false : true)
|
visible: index !== (menuOpener.children.values.length - 1) ? true : (modelData.isSeparator ? false : true)
|
||||||
@@ -99,18 +99,18 @@ StackView {
|
|||||||
Loader {
|
Loader {
|
||||||
id: childrenLoader
|
id: childrenLoader
|
||||||
|
|
||||||
active: !item.modelData.isSeparator
|
active: !item.modelData?.isSeparator ?? false
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
property int iconWidth: icon.active ? icon.width + Tokens.spacing.normal + icon.anchors.rightMargin : 0
|
property int iconWidth: icon.active ? icon.width + Tokens.spacing.medium + icon.anchors.rightMargin : 0
|
||||||
|
|
||||||
implicitHeight: root.itemHeight
|
implicitHeight: root.itemHeight
|
||||||
implicitWidth: label.width + label.anchors.leftMargin * 2 + iconWidth + (expand.item?.width ?? 0)
|
implicitWidth: label.width + label.anchors.leftMargin * 2 + iconWidth + (expand.item?.width ?? 0)
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
enabled: item.modelData.enabled
|
enabled: item.modelData?.enabled ?? false
|
||||||
radius: item.radius
|
radius: item.radius
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -130,7 +130,7 @@ StackView {
|
|||||||
Loader {
|
Loader {
|
||||||
id: icon
|
id: icon
|
||||||
|
|
||||||
active: item.modelData.icon !== ""
|
active: item.modelData?.icon ?? "" !== ""
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 10
|
anchors.rightMargin: 10
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -144,7 +144,7 @@ StackView {
|
|||||||
id: iconImage
|
id: iconImage
|
||||||
|
|
||||||
implicitSize: parent.implicitHeight
|
implicitSize: parent.implicitHeight
|
||||||
source: item.modelData.icon
|
source: item.modelData?.icon ?? Qt.url("")
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,20 +163,20 @@ StackView {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline
|
color: item.modelData?.enabled ?? false ? Colors.palette.m3onSurface : Colors.palette.m3outline
|
||||||
text: item.modelData.text
|
text: item.modelData?.text ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: expand
|
id: expand
|
||||||
|
|
||||||
active: item.modelData.hasChildren
|
active: item.modelData?.hasChildren ?? false
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: MaterialIcon {
|
sourceComponent: MaterialIcon {
|
||||||
color: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline
|
color: item.modelData?.enabled ?? false ? Colors.palette.m3onSurface : Colors.palette.m3outline
|
||||||
text: "chevron_right"
|
text: "chevron_right"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Modules.Bar.Components.Common
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Services
|
import qs.Services
|
||||||
@@ -10,9 +12,10 @@ import qs.Services
|
|||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property int panelRadius: ((profiles.height / 2) + Tokens.padding.small) * Tokens.rounding.scale
|
required property bool horizontal
|
||||||
|
readonly property int panelRadius: ((profiles.height / 2) + Tokens.padding.extraSmall) * Tokens.rounding.scale
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
active: Battery.isLaptop
|
active: Battery.isLaptop
|
||||||
@@ -22,6 +25,38 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: padding
|
||||||
|
|
||||||
|
implicitHeight: root.horizontal ? 0 : Tokens.padding.small
|
||||||
|
implicitWidth: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Battery.allPeripherals
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: layout
|
||||||
|
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Tokens.padding.small
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Tokens.padding.small
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: layout.modelData.model
|
||||||
|
}
|
||||||
|
|
||||||
|
BatteryIcon {
|
||||||
|
devState: layout.modelData.state
|
||||||
|
percentage: layout.modelData.percentage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
function formatSeconds(s: int, fallback: string): string {
|
function formatSeconds(s: int, fallback: string): string {
|
||||||
const day = Math.floor(s / 86400);
|
const day = Math.floor(s / 86400);
|
||||||
@@ -40,7 +75,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Tokens.padding.normal
|
anchors.leftMargin: Tokens.padding.small
|
||||||
text: Battery.isLaptop ? qsTr("Time %1: %2").arg(Battery.onBattery ? "remaining" : "until charged").arg(Battery.onBattery ? formatSeconds(Battery.timeToEmpty, "Calculating...") : formatSeconds(Battery.timeToFull, "Fully charged!")) : qsTr("Power profile: %1").arg(PowerProfile.toString(PowerProfiles.profile))
|
text: Battery.isLaptop ? qsTr("Time %1: %2").arg(Battery.onBattery ? "remaining" : "until charged").arg(Battery.onBattery ? formatSeconds(Battery.timeToEmpty, "Calculating...") : formatSeconds(Battery.timeToFull, "Fully charged!")) : qsTr("Power profile: %1").arg(PowerProfile.toString(PowerProfiles.profile))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +88,8 @@ Column {
|
|||||||
sourceComponent: CustomRect {
|
sourceComponent: CustomRect {
|
||||||
color: Colors.palette.m3error
|
color: Colors.palette.m3error
|
||||||
implicitHeight: child.implicitHeight + Tokens.padding.large
|
implicitHeight: child.implicitHeight + Tokens.padding.large
|
||||||
implicitWidth: child.implicitWidth + Tokens.padding.larger * 2
|
implicitWidth: child.implicitWidth + Tokens.padding.small * 2
|
||||||
radius: Tokens.rounding.large
|
radius: Tokens.rounding.largeIncreased
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: child
|
id: child
|
||||||
@@ -75,7 +110,7 @@ Column {
|
|||||||
CustomText {
|
CustomText {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: Colors.palette.m3onError
|
color: Colors.palette.m3onError
|
||||||
font.family: Appearance.font.family.mono
|
font.family: Config.appearance.font.family.mono
|
||||||
text: qsTr("Performance Degraded")
|
text: qsTr("Performance Degraded")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +146,7 @@ Column {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: indicator.height + Tokens.padding.extraSmall * 2
|
implicitHeight: indicator.height + Tokens.padding.extraSmall * 2
|
||||||
implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.larger * 2 + Tokens.spacing.small * 8
|
implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.small * 2 + Tokens.spacing.small * 8
|
||||||
radius: Tokens.rounding.full
|
radius: Tokens.rounding.full
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
@@ -192,8 +227,8 @@ Column {
|
|||||||
required property string icon
|
required property string icon
|
||||||
required property int profile
|
required property int profile
|
||||||
|
|
||||||
implicitHeight: icon.implicitHeight + Tokens.padding.small
|
implicitHeight: icon.implicitHeight + Tokens.padding.extraSmall
|
||||||
implicitWidth: icon.implicitHeight + Tokens.padding.small
|
implicitWidth: icon.implicitHeight + Tokens.padding.extraSmall
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
color: profiles.current === parent.icon ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
color: profiles.current === parent.icon ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
||||||
@@ -13,13 +13,13 @@ CustomClippingRect {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property bool hasUpdates: Object.keys(Updates.updates)?.length > 0
|
readonly property bool hasUpdates: Object.keys(Updates.updates)?.length > 0
|
||||||
readonly property int itemHeight: 50 + Tokens.padding.smaller * 2
|
readonly property int itemHeight: 50 + Tokens.padding.small * 2
|
||||||
required property var wrapper
|
required property var wrapper
|
||||||
|
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: hasUpdates ? updatesListLoader.item?.implicitHeight + Tokens.padding.small * 2 : noUpdatesLoader.item.height
|
implicitHeight: hasUpdates ? updatesListLoader.item?.implicitHeight + Tokens.padding.extraSmall * 2 : noUpdatesLoader.item.height
|
||||||
implicitWidth: hasUpdates ? updatesListLoader.item?.contentWidth + Tokens.padding.small * 2 : noUpdatesLoader.item.width
|
implicitWidth: hasUpdates ? updatesListLoader.item?.contentWidth + Tokens.padding.extraSmall * 2 : noUpdatesLoader.item.width
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.large - Tokens.padding.smaller
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: noUpdatesLoader
|
id: noUpdatesLoader
|
||||||
@@ -70,7 +70,7 @@ CustomClippingRect {
|
|||||||
displayMarginEnd: root.itemHeight
|
displayMarginEnd: root.itemHeight
|
||||||
implicitHeight: Math.min(contentHeight, (root.itemHeight + spacing) * 5 - spacing)
|
implicitHeight: Math.min(contentHeight, (root.itemHeight + spacing) * 5 - spacing)
|
||||||
implicitWidth: contentWidth
|
implicitWidth: contentWidth
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
delegate: CustomRect {
|
delegate: CustomRect {
|
||||||
id: update
|
id: update
|
||||||
@@ -78,17 +78,15 @@ CustomClippingRect {
|
|||||||
required property var modelData
|
required property var modelData
|
||||||
readonly property list<string> sections: modelData.update.split(" ")
|
readonly property list<string> sections: modelData.update.split(" ")
|
||||||
|
|
||||||
// anchors.left: parent.left
|
|
||||||
// anchors.right: parent.right
|
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: root.itemHeight
|
implicitHeight: root.itemHeight
|
||||||
implicitWidth: 600
|
implicitWidth: 600
|
||||||
radius: Tokens.rounding.small - Tokens.padding.small
|
radius: root.radius - Tokens.padding.extraSmall
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Tokens.padding.smaller
|
anchors.leftMargin: Tokens.padding.small
|
||||||
anchors.rightMargin: Tokens.padding.smaller
|
anchors.rightMargin: Tokens.padding.small
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
font.pointSize: Tokens.font.size.large * 2
|
font.pointSize: Tokens.font.size.large * 2
|
||||||
@@ -8,7 +8,7 @@ import ZShell.Config
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property list<real> animCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
property var animCurve: Tokens.anim.expressiveDefaultSpatial
|
||||||
property int animLength: Tokens.anim.durations.expressiveDefaultSpatial
|
property int animLength: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
readonly property alias content: content
|
readonly property alias content: content
|
||||||
readonly property Item current: (content.item as Content)?.current ?? null
|
readonly property Item current: (content.item as Content)?.current ?? null
|
||||||
@@ -16,6 +16,7 @@ Item {
|
|||||||
property alias currentName: popoutState.currentName
|
property alias currentName: popoutState.currentName
|
||||||
property string detachedMode
|
property string detachedMode
|
||||||
property alias hasCurrent: popoutState.hasCurrent
|
property alias hasCurrent: popoutState.hasCurrent
|
||||||
|
required property bool horizontal
|
||||||
readonly property real nonAnimHeight: content.implicitHeight || 150
|
readonly property real nonAnimHeight: content.implicitHeight || 150
|
||||||
readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth
|
readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth
|
||||||
required property real offsetScale
|
required property real offsetScale
|
||||||
@@ -35,7 +36,7 @@ Item {
|
|||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: root.animLength
|
duration: root.animLength
|
||||||
easing.bezierCurve: root.animCurve
|
easing: root.animCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Behavior on implicitWidth {
|
Behavior on implicitWidth {
|
||||||
@@ -43,7 +44,7 @@ Item {
|
|||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
duration: root.animLength
|
duration: root.animLength
|
||||||
easing.bezierCurve: root.animCurve
|
easing: root.animCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,10 +55,11 @@ Item {
|
|||||||
Comp {
|
Comp {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
shouldBeActive: root.hasCurrent
|
shouldBeActive: root.hasCurrent
|
||||||
|
|
||||||
sourceComponent: Content {
|
sourceComponent: Content {
|
||||||
|
horizontal: root.horizontal
|
||||||
popouts: popoutState
|
popouts: popoutState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import qs.Components
|
|
||||||
import ZShell.Config
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property real borderThickness
|
|
||||||
readonly property alias content: content
|
|
||||||
property real offsetScale: y > 0 || content.hasCurrent ? 0 : 1
|
|
||||||
required property ShellScreen screen
|
|
||||||
|
|
||||||
clip: true
|
|
||||||
implicitHeight: content.implicitHeight * (1 - offsetScale)
|
|
||||||
implicitWidth: content.implicitWidth
|
|
||||||
visible: width > 0 && height > 0
|
|
||||||
x: {
|
|
||||||
const off = content.currentCenter - borderThickness - content.nonAnimWidth / 2;
|
|
||||||
const diff = parent.width - Math.floor(off + content.nonAnimWidth);
|
|
||||||
if (diff < 0)
|
|
||||||
return off + diff;
|
|
||||||
return Math.floor(Math.max(off, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on offsetScale {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Behavior on x {
|
|
||||||
enabled: root.offsetScale < 1
|
|
||||||
|
|
||||||
Anim {
|
|
||||||
duration: content.animLength
|
|
||||||
easing.bezierCurve: content.animCurve
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Behavior on y {
|
|
||||||
Anim {
|
|
||||||
duration: content.animLength
|
|
||||||
easing.bezierCurve: content.animCurve
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Wrapper {
|
|
||||||
id: content
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: (-implicitHeight - 5) * root.offsetScale
|
|
||||||
offsetScale: root.offsetScale
|
|
||||||
screen: root.screen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -59,7 +59,7 @@ Item {
|
|||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: entries.right
|
anchors.left: entries.right
|
||||||
anchors.leftMargin: Tokens.spacing.normal
|
anchors.leftMargin: Tokens.spacing.medium
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
color: Colors.tPalette.m3surfaceContainer
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Tokens.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth)
|
implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Tokens.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth)
|
||||||
@@ -75,7 +75,7 @@ Item {
|
|||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 0
|
anchors.leftMargin: 0
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.small
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
visible: !ClipHistory.previewIsImage
|
visible: !ClipHistory.previewIsImage
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ Item {
|
|||||||
required property int index
|
required property int index
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
color: lineRow.index % 2 ? Colors.tPalette.m3surfaceContainer : "transparent"
|
color: lineRow.index % 2 ? Colors.tPalette.m3surfaceContainer : "transparent"
|
||||||
@@ -192,7 +192,7 @@ Item {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: search.bottom
|
anchors.top: search.bottom
|
||||||
anchors.topMargin: Tokens.spacing.normal
|
anchors.topMargin: Tokens.spacing.medium
|
||||||
implicitWidth: Config.clipboard.sizes.width
|
implicitWidth: Config.clipboard.sizes.width
|
||||||
|
|
||||||
CustomListView {
|
CustomListView {
|
||||||
@@ -204,7 +204,7 @@ Item {
|
|||||||
highlightRangeMode: ListView.ApplyRange
|
highlightRangeMode: ListView.ApplyRange
|
||||||
preferredHighlightBegin: 0
|
preferredHighlightBegin: 0
|
||||||
preferredHighlightEnd: height
|
preferredHighlightEnd: height
|
||||||
spacing: Tokens.spacing.normal
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
CustomScrollBar.vertical: CustomScrollBar {
|
CustomScrollBar.vertical: CustomScrollBar {
|
||||||
flickable: view
|
flickable: view
|
||||||
@@ -250,7 +250,7 @@ Item {
|
|||||||
id: icon
|
id: icon
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.margins: Tokens.padding.normal
|
anchors.margins: Tokens.padding.small
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.pointSize: Tokens.font.size.large
|
font.pointSize: Tokens.font.size.large
|
||||||
text: clipItem.isImage ? "image" : "text_fields"
|
text: clipItem.isImage ? "image" : "text_fields"
|
||||||
@@ -260,7 +260,7 @@ Item {
|
|||||||
id: text
|
id: text
|
||||||
|
|
||||||
anchors.left: icon.right
|
anchors.left: icon.right
|
||||||
anchors.margins: Tokens.spacing.normal
|
anchors.margins: Tokens.spacing.medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: clipItem.isImage ? qsTr("Image") : ClipHistory.displayText(clipItem.modelData)
|
text: clipItem.isImage ? qsTr("Image") : ClipHistory.displayText(clipItem.modelData)
|
||||||
@@ -292,7 +292,7 @@ Item {
|
|||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.margins: Tokens.padding.normal
|
Layout.margins: Tokens.padding.small
|
||||||
Layout.preferredWidth: height
|
Layout.preferredWidth: height
|
||||||
icon: "delete"
|
icon: "delete"
|
||||||
inactiveColor: Qt.alpha(Colors.palette.m3error, 0.8)
|
inactiveColor: Qt.alpha(Colors.palette.m3error, 0.8)
|
||||||
@@ -320,7 +320,7 @@ Item {
|
|||||||
Behavior on y {
|
Behavior on y {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.small
|
duration: Tokens.anim.durations.small
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
|
easing: Tokens.anim.expressiveDefaultEffects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ Item {
|
|||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
anchors.bottomMargin: (-implicitHeight - 5) * offsetScale
|
anchors.bottomMargin: (-implicitHeight - 5) * offsetScale
|
||||||
implicitHeight: content.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: content.implicitHeight + Tokens.padding.small * 2
|
||||||
implicitWidth: content.implicitWidth + Tokens.padding.normal * 2 || 400
|
implicitWidth: content.implicitWidth + Tokens.padding.small * 2 || 400
|
||||||
opacity: 1 - offsetScale
|
opacity: 1 - offsetScale
|
||||||
visible: offsetScale < 1
|
visible: offsetScale < 1
|
||||||
|
|
||||||
Behavior on offsetScale {
|
Behavior on offsetScale {
|
||||||
Anim {
|
Anim {
|
||||||
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
|
easing: Tokens.anim.expressiveDefaultSpatial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import Quickshell
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import ZShell.Config
|
|
||||||
import qs.Modules
|
|
||||||
import qs.Helpers
|
|
||||||
import qs.Components
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property RowLayout loader
|
|
||||||
required property Wrapper popouts
|
|
||||||
required property PersistentProperties visibilities
|
|
||||||
|
|
||||||
color: visibilities.dashboard ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
|
|
||||||
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
|
|
||||||
implicitWidth: timeText.contentWidth + Tokens.padding.normal * 2
|
|
||||||
radius: Tokens.rounding.full
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: timeText
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: root.visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
|
||||||
font: Config.appearance.font.family.mono
|
|
||||||
text: Time.dateStr
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
CAnim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
color: root.visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
root.visibilities.dashboard = !root.visibilities.dashboard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,16 +32,16 @@ Item {
|
|||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.margins: Tokens.padding.smaller
|
anchors.margins: Tokens.padding.small
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
radius: Tokens.rounding.normal - anchors.margins
|
radius: Tokens.rounding.extraLarge - anchors.margins
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: view
|
id: view
|
||||||
|
|
||||||
readonly property int currentIndex: root.state.currentTab
|
readonly property int currentIndex: root.dashState?.currentTab
|
||||||
readonly property Item currentItem: row.children[currentIndex]
|
readonly property Item currentItem: row.children[currentIndex]
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ GridLayout {
|
|||||||
|
|
||||||
required property PersistentProperties dashState
|
required property PersistentProperties dashState
|
||||||
readonly property bool dashboardVisible: visibilities.dashboard
|
readonly property bool dashboardVisible: visibilities.dashboard
|
||||||
property int radius: Tokens.rounding.smallest
|
property int radius: Tokens.rounding.medium
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
columnSpacing: Tokens.spacing.smaller
|
columnSpacing: Tokens.spacing.small
|
||||||
rowSpacing: Tokens.spacing.smaller
|
rowSpacing: Tokens.spacing.small
|
||||||
|
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
id: openAnim
|
id: openAnim
|
||||||
@@ -104,12 +104,13 @@ GridLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect {
|
CustomClippingRect {
|
||||||
Layout.column: 0
|
Layout.column: 0
|
||||||
Layout.columnSpan: 5
|
Layout.columnSpan: 5
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: media.implicitHeight
|
Layout.preferredHeight: media.implicitHeight
|
||||||
Layout.row: 2
|
Layout.row: 2
|
||||||
|
color: Colors.tPalette.m3surfaceContainer
|
||||||
radius: root.radius
|
radius: root.radius
|
||||||
|
|
||||||
Media {
|
Media {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ CustomMouseArea {
|
|||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
icon: "chevron_left"
|
icon: "chevron_left"
|
||||||
padding: Tokens.padding.small
|
padding: Tokens.padding.extraSmall
|
||||||
type: IconButton.Text
|
type: IconButton.Text
|
||||||
|
|
||||||
onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth - 1, 1)
|
onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth - 1, 1)
|
||||||
@@ -150,7 +150,7 @@ CustomMouseArea {
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
return root.realCurrMonth !== now.getMonth() || root.realCurrYear !== now.getFullYear();
|
return root.realCurrMonth !== now.getMonth() || root.realCurrYear !== now.getFullYear();
|
||||||
}
|
}
|
||||||
radius: pressed ? Tokens.rounding.small : Tokens.rounding.large
|
radius: pressed ? Tokens.rounding.small : Tokens.rounding.largeIncreased
|
||||||
|
|
||||||
Behavior on radius {
|
Behavior on radius {
|
||||||
Anim {
|
Anim {
|
||||||
@@ -203,7 +203,7 @@ CustomMouseArea {
|
|||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
icon: "chevron_right"
|
icon: "chevron_right"
|
||||||
padding: Tokens.padding.small
|
padding: Tokens.padding.extraSmall
|
||||||
type: IconButton.Text
|
type: IconButton.Text
|
||||||
|
|
||||||
onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth + 1, 1)
|
onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth + 1, 1)
|
||||||
@@ -259,7 +259,7 @@ CustomMouseArea {
|
|||||||
|
|
||||||
required property var model
|
required property var model
|
||||||
|
|
||||||
implicitHeight: text.implicitHeight + Tokens.padding.normal * 2
|
implicitHeight: text.implicitHeight + Tokens.padding.small * 2
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
|
|||||||
+158
-186
@@ -1,12 +1,15 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Services.Mpris
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
|
import ZShell.Components
|
||||||
import ZShell.Services
|
import ZShell.Services
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Modules.Dashboard.Dash.Media
|
||||||
import qs.Daemons
|
import qs.Daemons
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
@@ -14,7 +17,7 @@ import qs.Services
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
readonly property bool hasUnknownLength: (Players.active?.length ?? 0) > 2147483647
|
||||||
property real playerProgress: {
|
property real playerProgress: {
|
||||||
const active = Players.active;
|
const active = Players.active;
|
||||||
return active?.length ? (active.position % active.length) / active.length : 0;
|
return active?.length ? (active.position % active.length) / active.length : 0;
|
||||||
@@ -23,7 +26,19 @@ Item {
|
|||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
implicitHeight: cover.height + rowHeight * 2
|
implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
|
||||||
|
function lengthStr(length: int): string {
|
||||||
|
if (length < 0)
|
||||||
|
return "-1:-1";
|
||||||
|
|
||||||
|
const hours = Math.floor(length / 3600);
|
||||||
|
const mins = Math.floor((length % 3600) / 60);
|
||||||
|
const secs = Math.floor(length % 60).toString().padStart(2, "0");
|
||||||
|
|
||||||
|
if (hours > 0)
|
||||||
|
return `${hours}:${mins.toString().padStart(2, "0")}:${secs}`;
|
||||||
|
return `${mins}:${secs}`;
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on playerProgress {
|
Behavior on playerProgress {
|
||||||
Anim {
|
Anim {
|
||||||
@@ -32,11 +47,10 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
interval: Config.dashboard.mediaUpdateInterval
|
|
||||||
repeat: true
|
|
||||||
running: Players.active?.isPlaying ?? false
|
running: Players.active?.isPlaying ?? false
|
||||||
|
interval: Config.dashboard.mediaUpdateInterval
|
||||||
triggeredOnStart: true
|
triggeredOnStart: true
|
||||||
|
repeat: true
|
||||||
onTriggered: Players.active?.positionChanged()
|
onTriggered: Players.active?.positionChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,14 +58,18 @@ Item {
|
|||||||
service: Audio.cava
|
service: Audio.cava
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BackgroundShapes {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
id: visualizer
|
id: visualizer
|
||||||
|
|
||||||
readonly property int bars: Config.services.visualizerBars
|
readonly property int bars: Config.services.visualizerBars
|
||||||
property color color: Colors.palette.m3tertiary
|
property color color: Qt.alpha(Colors.palette.m3primary, 0.5)
|
||||||
property color fillColor: Qt.alpha(color, 0.25)
|
property color fillColor: Qt.alpha(color, 0.1)
|
||||||
|
|
||||||
anchors.fill: layout
|
anchors.fill: parent
|
||||||
anchors.leftMargin: -(shape.strokeWidth / 2)
|
anchors.leftMargin: -(shape.strokeWidth / 2)
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
@@ -72,17 +90,17 @@ Item {
|
|||||||
const n = values.length;
|
const n = values.length;
|
||||||
|
|
||||||
if (n < 2)
|
if (n < 2)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
const h = layout.height + shape.strokeWidth / 2;
|
const h = root.height + shape.strokeWidth / 2;
|
||||||
const w = layout.width + shape.strokeWidth;
|
const w = root.width + shape.strokeWidth;
|
||||||
|
|
||||||
function x(i) {
|
function x(i) {
|
||||||
return i * w / (n - 1);
|
return i * w / (n - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function y(i) {
|
function y(i) {
|
||||||
return h - values[i] * Config.dashboard.sizes.mediaVisualizerSize;
|
return h - (values[i] * Config.dashboard.sizes.mediaVisualizerSize) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
let d = `M 0 ${h} `;
|
let d = `M 0 ${h} `;
|
||||||
@@ -126,232 +144,186 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape {
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
|
||||||
fillColor: "transparent"
|
|
||||||
strokeColor: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
|
|
||||||
strokeWidth: Config.dashboard.sizes.mediaProgressThickness
|
|
||||||
|
|
||||||
Behavior on strokeColor {
|
|
||||||
CAnim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PathAngleArc {
|
|
||||||
centerX: cover.x + cover.width / 2
|
|
||||||
centerY: cover.y + cover.height / 2
|
|
||||||
radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
|
|
||||||
radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
|
|
||||||
startAngle: -90 - Config.dashboard.sizes.mediaProgressSweep / 2
|
|
||||||
sweepAngle: Config.dashboard.sizes.mediaProgressSweep
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
|
|
||||||
fillColor: "transparent"
|
|
||||||
strokeColor: Colors.palette.m3primary
|
|
||||||
strokeWidth: Config.dashboard.sizes.mediaProgressThickness
|
|
||||||
|
|
||||||
Behavior on strokeColor {
|
|
||||||
CAnim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PathAngleArc {
|
|
||||||
centerX: cover.x + cover.width / 2
|
|
||||||
centerY: cover.y + cover.height / 2
|
|
||||||
radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
|
|
||||||
radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
|
|
||||||
startAngle: -90 - Config.dashboard.sizes.mediaProgressSweep / 2
|
|
||||||
sweepAngle: Config.dashboard.sizes.mediaProgressSweep * root.playerProgress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: layout
|
id: layout
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.fill: parent
|
||||||
anchors.right: parent.right
|
anchors.margins: Tokens.padding.large
|
||||||
implicitHeight: root.implicitHeight
|
anchors.leftMargin: Tokens.padding.extraLarge
|
||||||
|
|
||||||
CustomClippingRect {
|
CoverVisualizer {
|
||||||
id: cover
|
Layout.fillHeight: true
|
||||||
|
implicitWidth: Config.dashboard.sizes.mediaCoverArtSize
|
||||||
Layout.alignment: Qt.AlignLeft
|
|
||||||
Layout.bottomMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small
|
|
||||||
Layout.leftMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small
|
|
||||||
Layout.preferredHeight: Config.dashboard.sizes.mediaCoverArtSize
|
|
||||||
Layout.preferredWidth: Config.dashboard.sizes.mediaCoverArtSize
|
|
||||||
Layout.topMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small
|
|
||||||
color: Colors.tPalette.m3surfaceContainerHigh
|
|
||||||
radius: Infinity
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: Colors.palette.m3onSurfaceVariant
|
|
||||||
font.pointSize: (parent.width * 0.4) || 1
|
|
||||||
grade: 200
|
|
||||||
text: "art_track"
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: image
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
asynchronous: true
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
source: Players.active?.trackArtUrl ?? ""
|
|
||||||
sourceSize.height: Math.floor(height)
|
|
||||||
sourceSize.width: Math.floor(width)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomRect {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: childrenRect.height
|
Layout.leftMargin: Tokens.spacing.largeIncreased
|
||||||
|
Layout.rightMargin: Tokens.spacing.largeIncreased
|
||||||
|
|
||||||
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
MarqueeText {
|
MarqueeText {
|
||||||
id: title
|
id: title
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
anchors.top: parent.top
|
|
||||||
color: Colors.palette.m3primary
|
color: Colors.palette.m3primary
|
||||||
font.pointSize: Tokens.font.size.normal
|
font.pointSize: Tokens.font.size.normal
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
pauseMs: 4000
|
pauseMs: 4000
|
||||||
text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
|
text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
|
||||||
width: parent.width - Tokens.padding.large * 4
|
implicitWidth: parent.width - Tokens.padding.large * 4
|
||||||
}
|
}
|
||||||
|
|
||||||
MarqueeText {
|
MarqueeText {
|
||||||
id: album
|
id: album
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
anchors.top: title.bottom
|
|
||||||
anchors.topMargin: Tokens.spacing.small
|
|
||||||
color: Colors.palette.m3outline
|
color: Colors.palette.m3outline
|
||||||
font.pointSize: Tokens.font.size.small
|
font.pointSize: Tokens.font.size.small
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
pauseMs: 4000
|
pauseMs: 4000
|
||||||
text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album")
|
text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album")
|
||||||
width: parent.width - Tokens.padding.large * 4
|
implicitWidth: parent.width - Tokens.padding.large * 4
|
||||||
}
|
}
|
||||||
|
|
||||||
MarqueeText {
|
MarqueeText {
|
||||||
id: artist
|
id: artist
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
anchors.top: album.bottom
|
|
||||||
anchors.topMargin: Tokens.spacing.small
|
|
||||||
color: Colors.palette.m3secondary
|
color: Colors.palette.m3secondary
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
pauseMs: 4000
|
pauseMs: 4000
|
||||||
text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist")
|
text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist")
|
||||||
width: parent.width - Tokens.padding.large * 4
|
implicitWidth: parent.width - Tokens.padding.large * 4
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: controls
|
id: positionSliderLayout
|
||||||
|
Layout.topMargin: Tokens.spacing.large
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.fillWidth: true
|
||||||
anchors.top: artist.bottom
|
|
||||||
anchors.topMargin: Tokens.spacing.smaller
|
|
||||||
spacing: Tokens.spacing.small
|
spacing: Tokens.spacing.small
|
||||||
|
|
||||||
Control {
|
TextMetrics {
|
||||||
function onClicked(): void {
|
id: timeMetrics
|
||||||
Players.active?.previous();
|
|
||||||
}
|
|
||||||
|
|
||||||
canUse: Players.active?.canGoPrevious ?? false
|
text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00"
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: positionLabel
|
||||||
|
|
||||||
|
Layout.preferredWidth: timeMetrics.width
|
||||||
|
text: root.lengthStr(Players.active?.position ?? -1)
|
||||||
|
color: Colors.palette.m3onSurfaceVariant
|
||||||
|
font: timeMetrics.font
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomSlider {
|
||||||
|
id: positionSlider
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
value: Players.active ? Players.active.position / (Players.active.length || 1) : 0
|
||||||
|
enabled: (Players.active?.canSeek ?? false) && !root.hasUnknownLength
|
||||||
|
wavy: true
|
||||||
|
animateWave: Players.active?.isPlaying ?? false
|
||||||
|
waveFrequency: 5
|
||||||
|
waveDuration: 2000
|
||||||
|
interactionOnMove: false
|
||||||
|
onInteraction: value => {
|
||||||
|
const active = Players.active;
|
||||||
|
if (active?.canSeek && active?.positionSupported)
|
||||||
|
active.position = value * active.length;
|
||||||
|
}
|
||||||
|
Binding {
|
||||||
|
target: positionLabel
|
||||||
|
property: "text"
|
||||||
|
value: root.lengthStr(positionSlider.pos * (Players.active?.length ?? 0))
|
||||||
|
when: positionSlider.dragging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.preferredWidth: timeMetrics.width
|
||||||
|
text: root.hasUnknownLength ? "--:--" : root.lengthStr(Players.active?.length ?? -1)
|
||||||
|
color: Colors.palette.m3onSurfaceVariant
|
||||||
|
font: timeMetrics.font
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonRow {
|
||||||
|
Layout.topMargin: Tokens.spacing.largeIncreased
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
Layout.leftMargin: positionSliderLayout.implicitWidth / 4
|
||||||
|
Layout.rightMargin: positionSliderLayout.implicitWidth / 4
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
type: IconButton.Tonal
|
||||||
|
icon: "shuffle"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
checked: Players.active?.shuffle ?? false
|
||||||
|
enabled: Players.active?.shuffleSupported
|
||||||
|
onClicked: Players.active.shuffle = !Players.active?.shuffle
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
id: previousBtn
|
||||||
|
|
||||||
|
type: IconButton.Tonal
|
||||||
icon: "skip_previous"
|
icon: "skip_previous"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
enabled: Players.active?.canGoPrevious
|
||||||
|
onClicked: Players.active?.previous()
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
}
|
}
|
||||||
|
|
||||||
Control {
|
IconButton {
|
||||||
function onClicked(): void {
|
id: playPauseBtn
|
||||||
Players.active?.togglePlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
canUse: Players.active?.canTogglePlaying ?? false
|
|
||||||
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
|
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
fillWidth: true
|
||||||
|
checked: Players.active?.isPlaying ?? false
|
||||||
|
enabled: Players.active?.canTogglePlaying
|
||||||
|
onClicked: Players.active?.togglePlaying()
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
}
|
}
|
||||||
|
|
||||||
Control {
|
IconButton {
|
||||||
function onClicked(): void {
|
id: nextBtn
|
||||||
Players.active?.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
canUse: Players.active?.canGoNext ?? false
|
type: IconButton.Tonal
|
||||||
icon: "skip_next"
|
icon: "skip_next"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
enabled: Players.active?.canGoNext
|
||||||
|
onClicked: Players.active?.next()
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
type: IconButton.Tonal
|
||||||
|
icon: Players.active?.loopState === MprisLoopState.Track ? "repeat_one" : "repeat"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
checked: Players.active?.loopState === MprisLoopState.Track || Players.active?.loopState === MprisLoopState.Playlist
|
||||||
|
enabled: Players.active?.loopSupported
|
||||||
|
onClicked: {
|
||||||
|
const state = Players.active.loopState;
|
||||||
|
if (state === MprisLoopState.None)
|
||||||
|
Players.active.loopState = MprisLoopState.Track;
|
||||||
|
else if (state === MprisLoopState.Track)
|
||||||
|
Players.active.loopState = MprisLoopState.Playlist;
|
||||||
|
else
|
||||||
|
Players.active.loopState = MprisLoopState.None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component Control: CustomRect {
|
|
||||||
id: control
|
|
||||||
|
|
||||||
required property bool canUse
|
|
||||||
required property string icon
|
|
||||||
property int level: 1
|
|
||||||
property string set_color: "Secondary"
|
|
||||||
|
|
||||||
function onClicked(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
Layout.preferredWidth: implicitWidth + (controlState.pressed ? Tokens.padding.normal * 2 : 0)
|
|
||||||
color: canUse ? Colors.palette[`m3${set_color.toLowerCase()}`] : Colors.palette[`m3${set_color.toLowerCase()}Container`]
|
|
||||||
implicitHeight: implicitWidth
|
|
||||||
implicitWidth: Math.max(icon.implicitHeight, icon.implicitHeight) + Tokens.padding.small
|
|
||||||
radius: Tokens.rounding.full
|
|
||||||
|
|
||||||
Behavior on Layout.preferredWidth {
|
|
||||||
Anim {
|
|
||||||
duration: Tokens.anim.durations.expressiveFastSpatial
|
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {
|
|
||||||
duration: Tokens.anim.durations.expressiveFastSpatial
|
|
||||||
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Elevation {
|
|
||||||
anchors.fill: parent
|
|
||||||
level: controlState.containsMouse && !controlState.pressed ? control.level + 1 : control.level
|
|
||||||
radius: parent.radius
|
|
||||||
z: -1
|
|
||||||
}
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: controlState
|
|
||||||
|
|
||||||
color: control.canUse ? Colors.palette[`m3on${control.set_color}`] : Colors.palette[`m3on${control.set_color}Container`]
|
|
||||||
enabled: control.canUse
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
control.onClicked();
|
|
||||||
}
|
|
||||||
// radius: Tokens.rounding.full
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.verticalCenterOffset: font.pointSize * 0.05
|
|
||||||
animate: true
|
|
||||||
color: control.canUse ? Colors.palette[`m3on${control.set_color}`] : Colors.palette[`m3on${control.set_color}Container`]
|
|
||||||
fill: control.canUse ? 1 : 0
|
|
||||||
font.pointSize: Tokens.font.size.large
|
|
||||||
text: control.icon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import M3Shapes
|
||||||
|
import qs.Components
|
||||||
|
import qs.Services
|
||||||
|
import qs.Helpers
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int count: 14
|
||||||
|
property list<real> darkOpacities: [0.10, 0.20, 0.10, 0.20]
|
||||||
|
property list<real> lightOpacities: [0.34, 0.34, 0.08, 0.2]
|
||||||
|
property real maxRotSpeed: 12
|
||||||
|
property real maxSize: 124
|
||||||
|
property real maxSpeed: 18
|
||||||
|
property real minRotSpeed: -12
|
||||||
|
property real minSize: 36
|
||||||
|
property real minSpeed: 4
|
||||||
|
readonly property list<int> shapePool: [MaterialShape.Circle, MaterialShape.Cookie4Sided, MaterialShape.Cookie6Sided, MaterialShape.Cookie7Sided, MaterialShape.Cookie9Sided, MaterialShape.Cookie12Sided, MaterialShape.Sunny, MaterialShape.VerySunny, MaterialShape.SoftBurst, MaterialShape.Pentagon, MaterialShape.Gem, MaterialShape.Arch, MaterialShape.Arrow, MaterialShape.Pill, MaterialShape.Triangle, MaterialShape.Fan, MaterialShape.Oval]
|
||||||
|
|
||||||
|
function rand(min: real, max: real): real {
|
||||||
|
return min + Math.random() * (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
function signedRand(min: real, max: real): real {
|
||||||
|
return rand(min, max) * (Math.random() < 0.5 ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: shapes.model = count
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: shapes
|
||||||
|
|
||||||
|
DriftingShape {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameAnimation {
|
||||||
|
running: root.visible && root.width > 0 && root.height > 0 && (Players.active?.isPlaying ?? false)
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
const dt = frameTime;
|
||||||
|
for (let i = 0; i < shapes.count; i++) {
|
||||||
|
const s = shapes.itemAt(i) as DriftingShape;
|
||||||
|
if (!s)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s.x += s.vx * dt;
|
||||||
|
s.y += s.vy * dt;
|
||||||
|
s.rotation += s.vr * dt;
|
||||||
|
|
||||||
|
if (s.x + s.width < 0)
|
||||||
|
s.x = root.width;
|
||||||
|
else if (s.x > root.width)
|
||||||
|
s.x = -s.width;
|
||||||
|
|
||||||
|
if (s.y + s.height < 0)
|
||||||
|
s.y = root.height;
|
||||||
|
else if (s.y > root.height)
|
||||||
|
s.y = -s.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component DriftingShape: MaterialShape {
|
||||||
|
id: shapeItem
|
||||||
|
|
||||||
|
readonly property int colorIdx: Math.floor(Math.random() * 4)
|
||||||
|
required property int index
|
||||||
|
property real vr: root.rand(root.minRotSpeed, root.maxRotSpeed)
|
||||||
|
property real vx: root.signedRand(root.minSpeed, root.maxSpeed)
|
||||||
|
property real vy: root.signedRand(root.minSpeed, root.maxSpeed)
|
||||||
|
|
||||||
|
color: [Colors.palette.m3primaryContainer, Colors.palette.m3secondaryContainer, Colors.palette.m3tertiaryContainer, Colors.palette.m3outlineVariant][colorIdx]
|
||||||
|
implicitSize: root.minSize + (index / root.count) * (root.maxSize - root.minSize)
|
||||||
|
opacity: Colors.light ? root.lightOpacities[colorIdx] : root.darkOpacities[colorIdx]
|
||||||
|
rotation: root.rand(0, 360)
|
||||||
|
shape: root.shapePool[Math.floor(Math.random() * root.shapePool.length)]
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.SlowEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
x = root.rand(0, root.width - implicitSize);
|
||||||
|
y = root.rand(0, root.height - implicitSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
import M3Shapes
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Effects
|
||||||
|
import qs.Components
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property color fallbackColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2)
|
||||||
|
property bool hadPrevious
|
||||||
|
readonly property alias shape: shape
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
|
||||||
|
Behavior on fallbackColor {
|
||||||
|
CAnim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
blurMax: 1
|
||||||
|
shadowColor: Colors.palette.m3outline
|
||||||
|
shadowEnabled: true
|
||||||
|
shadowOpacity: 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: shapeWrapper
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
opacity: root.fallbackColor.a
|
||||||
|
|
||||||
|
MaterialShape {
|
||||||
|
id: shape
|
||||||
|
|
||||||
|
color: Qt.alpha(root.fallbackColor, 1)
|
||||||
|
implicitSize: root.width
|
||||||
|
shape: MaterialShape.Cookie12Sided
|
||||||
|
|
||||||
|
Anim on rotation {
|
||||||
|
duration: 23500
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
from: 360
|
||||||
|
loops: Animation.Infinite
|
||||||
|
paused: !Players.active?.isPlaying
|
||||||
|
running: true
|
||||||
|
to: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
animate: true
|
||||||
|
color: Colors.palette.m3onSurfaceVariant
|
||||||
|
grade: 200
|
||||||
|
opacity: image.status === Image.Null || image.status === Image.Error ? 1 : 0
|
||||||
|
text: image.status === Image.Error ? "broken_image" : "art_track"
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: opacity > 0
|
||||||
|
anchors.centerIn: parent
|
||||||
|
asynchronous: true
|
||||||
|
opacity: image.status === Image.Loading ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceComponent: LoadingIndicator {
|
||||||
|
color: Colors.palette.m3primaryContainer
|
||||||
|
implicitSize: root.width * 0.3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FadeImage {
|
||||||
|
id: image
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
source: Players.getArtUrl(Players.active)
|
||||||
|
|
||||||
|
layer.effect: Mask {
|
||||||
|
maskSource: shapeWrapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import M3Shapes
|
||||||
|
import ZShell.Config
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
CoverArt {
|
||||||
|
id: cover
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitHeight: Config.dashboard.sizes.mediaCoverArtSize
|
||||||
|
implicitWidth: Config.dashboard.sizes.mediaCoverArtSize
|
||||||
|
shape.shape: MaterialShape.Cookie9Sided
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user