mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-15 07:44:01 -04:00
- The island is now a bar widget so any bar can host one alongside the island layout and dot - Routing got simpler: pick which shortcuts open here, the rest follow the shared rules - IPC close/hide take down every surface showing the activity - Qt 6.11 pointer prune workaround so the expanded island stays clickable
192 lines
8.5 KiB
QML
192 lines
8.5 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
|
|
QtObject {
|
|
id: root
|
|
|
|
property bool enabled: true
|
|
property bool running: false
|
|
property bool reducedMotion: false
|
|
|
|
property real stiffness: 560
|
|
property real damping: 37
|
|
property real mass: 1
|
|
property real positionEpsilon: 0.035
|
|
property real velocityEpsilon: 0.035
|
|
property real maximumFrameTime: 1 / 30
|
|
property real integrationStep: 1 / 240
|
|
readonly property real timeConstantMs: reducedMotion ? 0 : 2000 * mass / Math.max(1, damping)
|
|
|
|
property real currentWidth: 176
|
|
property real currentHeight: 42
|
|
property real currentOffsetAlong: 0
|
|
property real currentOffsetCross: 8
|
|
property real currentTopLeftRadius: 21
|
|
property real currentTopRightRadius: 21
|
|
property real currentBottomLeftRadius: 21
|
|
property real currentBottomRightRadius: 21
|
|
|
|
property real targetWidth: currentWidth
|
|
property real targetHeight: currentHeight
|
|
property real targetOffsetAlong: currentOffsetAlong
|
|
property real targetOffsetCross: currentOffsetCross
|
|
property real targetTopLeftRadius: currentTopLeftRadius
|
|
property real targetTopRightRadius: currentTopRightRadius
|
|
property real targetBottomLeftRadius: currentBottomLeftRadius
|
|
property real targetBottomRightRadius: currentBottomRightRadius
|
|
|
|
property real velocityWidth: 0
|
|
property real velocityHeight: 0
|
|
property real velocityOffsetAlong: 0
|
|
property real velocityOffsetCross: 0
|
|
property real velocityTopLeftRadius: 0
|
|
property real velocityTopRightRadius: 0
|
|
property real velocityBottomLeftRadius: 0
|
|
property real velocityBottomRightRadius: 0
|
|
|
|
// One per integration step, so consumers copy the body once instead of binding to eight currents.
|
|
signal stepped()
|
|
|
|
function matchesTarget(target) {
|
|
return targetWidth === target.width && targetHeight === target.height && targetOffsetAlong === target.offsetAlong && targetOffsetCross === target.offsetCross && targetTopLeftRadius === target.topLeftRadius && targetTopRightRadius === target.topRightRadius && targetBottomLeftRadius === target.bottomLeftRadius && targetBottomRightRadius === target.bottomRightRadius;
|
|
}
|
|
|
|
function setTarget(target, seedVelocity) {
|
|
if (matchesTarget(target) && !seedVelocity)
|
|
return;
|
|
targetWidth = target.width;
|
|
targetHeight = target.height;
|
|
targetOffsetAlong = target.offsetAlong;
|
|
targetOffsetCross = target.offsetCross;
|
|
targetTopLeftRadius = target.topLeftRadius;
|
|
targetTopRightRadius = target.topRightRadius;
|
|
targetBottomLeftRadius = target.bottomLeftRadius;
|
|
targetBottomRightRadius = target.bottomRightRadius;
|
|
|
|
if (seedVelocity) {
|
|
velocityOffsetAlong = seedVelocity.offsetAlong ?? velocityOffsetAlong;
|
|
velocityOffsetCross = seedVelocity.offsetCross ?? velocityOffsetCross;
|
|
}
|
|
|
|
if (reducedMotion) {
|
|
settle();
|
|
return;
|
|
}
|
|
|
|
if (!isSettled())
|
|
running = true;
|
|
}
|
|
|
|
function snapTo(target) {
|
|
targetWidth = target.width;
|
|
targetHeight = target.height;
|
|
targetOffsetAlong = target.offsetAlong;
|
|
targetOffsetCross = target.offsetCross;
|
|
targetTopLeftRadius = target.topLeftRadius;
|
|
targetTopRightRadius = target.topRightRadius;
|
|
targetBottomLeftRadius = target.bottomLeftRadius;
|
|
targetBottomRightRadius = target.bottomRightRadius;
|
|
|
|
currentWidth = target.width;
|
|
currentHeight = target.height;
|
|
currentOffsetAlong = target.offsetAlong;
|
|
currentOffsetCross = target.offsetCross;
|
|
currentTopLeftRadius = target.topLeftRadius;
|
|
currentTopRightRadius = target.topRightRadius;
|
|
currentBottomLeftRadius = target.bottomLeftRadius;
|
|
currentBottomRightRadius = target.bottomRightRadius;
|
|
|
|
velocityWidth = 0;
|
|
velocityHeight = 0;
|
|
velocityOffsetAlong = 0;
|
|
velocityOffsetCross = 0;
|
|
velocityTopLeftRadius = 0;
|
|
velocityTopRightRadius = 0;
|
|
velocityBottomLeftRadius = 0;
|
|
velocityBottomRightRadius = 0;
|
|
running = false;
|
|
stepped();
|
|
}
|
|
|
|
function isSettled() {
|
|
const positionSettled = Math.abs(targetWidth - currentWidth) <= positionEpsilon && Math.abs(targetHeight - currentHeight) <= positionEpsilon && Math.abs(targetOffsetAlong - currentOffsetAlong) <= positionEpsilon && Math.abs(targetOffsetCross - currentOffsetCross) <= positionEpsilon && Math.abs(targetTopLeftRadius - currentTopLeftRadius) <= positionEpsilon && Math.abs(targetTopRightRadius - currentTopRightRadius) <= positionEpsilon && Math.abs(targetBottomLeftRadius - currentBottomLeftRadius) <= positionEpsilon && Math.abs(targetBottomRightRadius - currentBottomRightRadius) <= positionEpsilon;
|
|
const velocitySettled = Math.abs(velocityWidth) <= velocityEpsilon && Math.abs(velocityHeight) <= velocityEpsilon && Math.abs(velocityOffsetAlong) <= velocityEpsilon && Math.abs(velocityOffsetCross) <= velocityEpsilon && Math.abs(velocityTopLeftRadius) <= velocityEpsilon && Math.abs(velocityTopRightRadius) <= velocityEpsilon && Math.abs(velocityBottomLeftRadius) <= velocityEpsilon && Math.abs(velocityBottomRightRadius) <= velocityEpsilon;
|
|
return positionSettled && velocitySettled;
|
|
}
|
|
|
|
function settle() {
|
|
currentWidth = targetWidth;
|
|
currentHeight = targetHeight;
|
|
currentOffsetAlong = targetOffsetAlong;
|
|
currentOffsetCross = targetOffsetCross;
|
|
currentTopLeftRadius = targetTopLeftRadius;
|
|
currentTopRightRadius = targetTopRightRadius;
|
|
currentBottomLeftRadius = targetBottomLeftRadius;
|
|
currentBottomRightRadius = targetBottomRightRadius;
|
|
|
|
velocityWidth = 0;
|
|
velocityHeight = 0;
|
|
velocityOffsetAlong = 0;
|
|
velocityOffsetCross = 0;
|
|
velocityTopLeftRadius = 0;
|
|
velocityTopRightRadius = 0;
|
|
velocityBottomLeftRadius = 0;
|
|
velocityBottomRightRadius = 0;
|
|
running = false;
|
|
stepped();
|
|
}
|
|
|
|
function advance(rawFrameTime) {
|
|
if (!enabled || !running || reducedMotion)
|
|
return;
|
|
|
|
const frameTime = Math.min(Math.max(rawFrameTime, 0), maximumFrameTime);
|
|
if (frameTime <= 0)
|
|
return;
|
|
|
|
const steps = Math.max(1, Math.ceil(frameTime / integrationStep));
|
|
const step = frameTime / steps;
|
|
const inverseMass = 1 / Math.max(0.001, mass);
|
|
|
|
for (let i = 0; i < steps; i++) {
|
|
velocityWidth += (stiffness * (targetWidth - currentWidth) - damping * velocityWidth) * inverseMass * step;
|
|
velocityHeight += (stiffness * (targetHeight - currentHeight) - damping * velocityHeight) * inverseMass * step;
|
|
velocityOffsetAlong += (stiffness * (targetOffsetAlong - currentOffsetAlong) - damping * velocityOffsetAlong) * inverseMass * step;
|
|
velocityOffsetCross += (stiffness * (targetOffsetCross - currentOffsetCross) - damping * velocityOffsetCross) * inverseMass * step;
|
|
velocityTopLeftRadius += (stiffness * (targetTopLeftRadius - currentTopLeftRadius) - damping * velocityTopLeftRadius) * inverseMass * step;
|
|
velocityTopRightRadius += (stiffness * (targetTopRightRadius - currentTopRightRadius) - damping * velocityTopRightRadius) * inverseMass * step;
|
|
velocityBottomLeftRadius += (stiffness * (targetBottomLeftRadius - currentBottomLeftRadius) - damping * velocityBottomLeftRadius) * inverseMass * step;
|
|
velocityBottomRightRadius += (stiffness * (targetBottomRightRadius - currentBottomRightRadius) - damping * velocityBottomRightRadius) * inverseMass * step;
|
|
|
|
currentWidth += velocityWidth * step;
|
|
currentHeight += velocityHeight * step;
|
|
currentOffsetAlong += velocityOffsetAlong * step;
|
|
currentOffsetCross += velocityOffsetCross * step;
|
|
currentTopLeftRadius += velocityTopLeftRadius * step;
|
|
currentTopRightRadius += velocityTopRightRadius * step;
|
|
currentBottomLeftRadius += velocityBottomLeftRadius * step;
|
|
currentBottomRightRadius += velocityBottomRightRadius * step;
|
|
}
|
|
|
|
if (isSettled())
|
|
settle();
|
|
else
|
|
stepped();
|
|
}
|
|
|
|
onEnabledChanged: {
|
|
if (!enabled) settle();
|
|
}
|
|
|
|
onReducedMotionChanged: {
|
|
if (reducedMotion)
|
|
settle();
|
|
}
|
|
|
|
property FrameAnimation frameAnimation: FrameAnimation {
|
|
running: root.enabled && root.running && !root.reducedMotion
|
|
onTriggered: root.advance(frameTime)
|
|
}
|
|
}
|