1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-04 21:02:06 -04:00

animations/ripple: clean up effect and apply more universally

This commit is contained in:
bbedward
2026-02-10 12:48:12 -05:00
parent 5a0bb260b4
commit 3d0ee9d72b
49 changed files with 980 additions and 805 deletions

View File

@@ -101,12 +101,18 @@ Rectangle {
}
}
DankRipple {
id: ripple
cornerRadius: root.radius
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
enabled: root.enabled
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
onClicked: root.clicked()
}

View File

@@ -11,19 +11,11 @@ Rectangle {
property string iconName: ""
property string text: ""
signal pressed()
signal pressed
height: 34
radius: Theme.cornerRadius
color: mouseArea.containsMouse ? Qt.rgba(
Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
0.12) : Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.5)
color: mouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
Row {
anchors.centerIn: parent
@@ -44,12 +36,20 @@ Rectangle {
}
}
DankRipple {
id: ripple
cornerRadius: root.radius
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: root.pressed()
onPressed: mouse => {
ripple.trigger(mouse.x, mouse.y);
root.pressed();
}
}
}

View File

@@ -61,11 +61,17 @@ Rectangle {
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
DankRipple {
id: iconRipple
cornerRadius: parent.radius
}
MouseArea {
id: iconArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (AudioService.source && AudioService.source.audio) {
AudioService.source.audio.muted = !AudioService.source.audio.muted;
@@ -126,15 +132,15 @@ Rectangle {
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
return value.filter(v => v);
if (typeof value === "string" && value.length > 0)
return [value]
return []
return [value];
return [];
}
function getPinnedInputs() {
const pins = SettingsData.audioInputDevicePins || {}
return normalizePinList(pins["preferredInput"])
const pins = SettingsData.audioInputDevicePins || {};
return normalizePinList(pins["preferredInput"]);
}
Column {
@@ -153,14 +159,14 @@ Rectangle {
let sorted = [...nodes];
sorted.sort((a, b) => {
// Pinned device first
const aPinnedIndex = pinnedList.indexOf(a.name)
const bPinnedIndex = pinnedList.indexOf(b.name)
const aPinnedIndex = pinnedList.indexOf(a.name);
const bPinnedIndex = pinnedList.indexOf(b.name);
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
if (aPinnedIndex === -1)
return 1
return 1;
if (bPinnedIndex === -1)
return -1
return aPinnedIndex - bPinnedIndex
return -1;
return aPinnedIndex - bPinnedIndex;
}
// Then active device
if (a === AudioService.source && b !== AudioService.source)
@@ -276,38 +282,53 @@ Rectangle {
}
}
DankRipple {
id: pinRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y)
onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}))
let pinnedList = audioContent.normalizePinList(pins["preferredInput"])
const pinIndex = pinnedList.indexOf(modelData.name)
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}));
let pinnedList = audioContent.normalizePinList(pins["preferredInput"]);
const pinIndex = pinnedList.indexOf(modelData.name);
if (pinIndex !== -1) {
pinnedList.splice(pinIndex, 1)
pinnedList.splice(pinIndex, 1);
} else {
pinnedList.unshift(modelData.name)
pinnedList.unshift(modelData.name);
if (pinnedList.length > audioContent.maxPinnedInputs)
pinnedList = pinnedList.slice(0, audioContent.maxPinnedInputs)
pinnedList = pinnedList.slice(0, audioContent.maxPinnedInputs);
}
if (pinnedList.length > 0)
pins["preferredInput"] = pinnedList
pins["preferredInput"] = pinnedList;
else
delete pins["preferredInput"]
delete pins["preferredInput"];
SettingsData.set("audioInputDevicePins", pins)
SettingsData.set("audioInputDevicePins", pins);
}
}
}
DankRipple {
id: deviceRipple
cornerRadius: parent.radius
}
MouseArea {
id: deviceMouseArea
anchors.fill: parent
anchors.rightMargin: pinInputRow.width + Theme.spacingS * 4
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => {
let mapped = mapToItem(parent, mouse.x, mouse.y);
deviceRipple.trigger(mapped.x, mapped.y);
}
onClicked: {
if (modelData) {
Pipewire.preferredDefaultAudioSource = modelData;

View File

@@ -61,11 +61,17 @@ Rectangle {
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
DankRipple {
id: muteRipple
cornerRadius: parent.radius
}
MouseArea {
id: iconArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => muteRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (AudioService.sink && AudioService.sink.audio) {
AudioService.sink.audio.muted = !AudioService.sink.audio.muted;
@@ -184,6 +190,7 @@ Rectangle {
}
delegate: Rectangle {
id: outputDelegate
required property var modelData
required property int index
@@ -194,6 +201,11 @@ Rectangle {
border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0
DankRipple {
id: deviceRipple
cornerRadius: outputDelegate.radius
}
Row {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
@@ -288,9 +300,15 @@ Rectangle {
}
}
DankRipple {
id: pinRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y)
onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}));
let pinnedList = audioContent.normalizePinList(pins["preferredOutput"]);
@@ -320,6 +338,10 @@ Rectangle {
anchors.rightMargin: pinOutputRow.width + Theme.spacingS * 4
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => {
let mapped = deviceMouseArea.mapToItem(outputDelegate, mouse.x, mouse.y);
deviceRipple.trigger(mapped.x, mapped.y);
}
onClicked: {
if (modelData) {
Pipewire.preferredDefaultAudioSink = modelData;
@@ -428,12 +450,18 @@ Rectangle {
radius: Theme.cornerRadius
color: appIconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
DankRipple {
id: appMuteRipple
cornerRadius: parent.radius
}
MouseArea {
id: appIconArea
anchors.fill: parent
visible: modelData !== null
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => appMuteRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (modelData) {
SessionData.suppressOSDTemporarily();

View File

@@ -293,6 +293,11 @@ Item {
visible: modelData.name === currentCodec
}
DankRipple {
id: codecRipple
cornerRadius: parent.radius
}
MouseArea {
id: codecMouseArea
@@ -300,6 +305,7 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
enabled: modelData.name !== currentCodec && !isLoading
onPressed: mouse => codecRipple.trigger(mouse.x, mouse.y)
onClicked: {
selectCodec(modelData.profile);
}

View File

@@ -139,12 +139,18 @@ Rectangle {
}
}
DankRipple {
id: scanRipple
cornerRadius: scanButton.radius
}
MouseArea {
id: scanMouseArea
anchors.fill: parent
hoverEnabled: true
enabled: scanButton.adapterEnabled
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onPressed: mouse => scanRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (!BluetoothService.adapter)
return;
@@ -399,12 +405,21 @@ Rectangle {
}
}
DankRipple {
id: deviceRipple
cornerRadius: pairedDelegate.radius
}
MouseArea {
id: deviceMouseArea
anchors.fill: parent
anchors.rightMargin: pairedOptionsButton.width + Theme.spacingM + pinBluetoothRow.width + Theme.spacingS * 4
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => {
const pos = mapToItem(pairedDelegate, mouse.x, mouse.y);
deviceRipple.trigger(pos.x, pos.y);
}
onClicked: {
if (pairedDelegate.isConnected) {
pairedDelegate.modelData.disconnect();
@@ -547,12 +562,18 @@ Rectangle {
font.weight: Font.Medium
}
DankRipple {
id: availableRipple
cornerRadius: availableDelegate.radius
}
MouseArea {
id: availableMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: availableDelegate.isInteractive ? Qt.PointingHandCursor : Qt.ArrowCursor
enabled: availableDelegate.isInteractive
onPressed: mouse => availableRipple.trigger(mouse.x, mouse.y)
onClicked: root.handlePairDevice(availableDelegate.modelData)
}
}

View File

@@ -211,9 +211,15 @@ Rectangle {
}
}
DankRipple {
id: pinRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y)
onClicked: root.togglePinToScreen()
}
}
@@ -443,9 +449,15 @@ Rectangle {
}
}
DankRipple {
id: expToggleRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => expToggleRipple.trigger(mouse.x, mouse.y)
onClicked: {
const currentState = SessionData.getBrightnessExponential(modelData.name);
SessionData.setBrightnessExponential(modelData.name, !currentState);
@@ -454,12 +466,18 @@ Rectangle {
}
}
DankRipple {
id: deviceRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
anchors.bottomMargin: 28
anchors.rightMargin: SessionData.getBrightnessExponential(modelData.name) ? 145 : 0
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => deviceRipple.trigger(mouse.x, mouse.y)
onClicked: {
const pinKey = root.getScreenPinKey();
if (pinKey.length > 0 && modelData.name !== currentDeviceName) {

View File

@@ -155,10 +155,16 @@ Rectangle {
}
}
DankRipple {
id: mountRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => mountRipple.trigger(mouse.x, mouse.y)
onClicked: {
currentMountPath = modelData.mount;
mountPathChanged(modelData.mount);

View File

@@ -344,12 +344,18 @@ Rectangle {
}
}
DankRipple {
id: wiredRipple
cornerRadius: parent.radius
}
MouseArea {
id: wiredNetworkMouseArea
anchors.fill: parent
anchors.rightMargin: wiredOptionsButton.width + Theme.spacingS
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => wiredRipple.trigger(mouse.x, mouse.y)
onClicked: function (event) {
if (modelData.uuid !== NetworkService.ethernetConnectionUuid) {
NetworkService.connectToSpecificWiredConfig(modelData.uuid);
@@ -467,15 +473,15 @@ Rectangle {
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
return value.filter(v => v);
if (typeof value === "string" && value.length > 0)
return [value]
return []
return [value];
return [];
}
function getPinnedNetworks() {
const pins = SettingsData.wifiNetworkPins || {}
return normalizePinList(pins["preferredWifi"])
const pins = SettingsData.wifiNetworkPins || {};
return normalizePinList(pins["preferredWifi"]);
}
property var frozenNetworks: []
@@ -483,18 +489,18 @@ Rectangle {
property var sortedNetworks: {
const ssid = NetworkService.currentWifiSSID;
const networks = NetworkService.wifiNetworks;
const pinnedList = getPinnedNetworks()
const pinnedList = getPinnedNetworks();
let sorted = [...networks];
sorted.sort((a, b) => {
const aPinnedIndex = pinnedList.indexOf(a.ssid)
const bPinnedIndex = pinnedList.indexOf(b.ssid)
const aPinnedIndex = pinnedList.indexOf(a.ssid);
const bPinnedIndex = pinnedList.indexOf(b.ssid);
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
if (aPinnedIndex === -1)
return 1
return 1;
if (bPinnedIndex === -1)
return -1
return aPinnedIndex - bPinnedIndex
return -1;
return aPinnedIndex - bPinnedIndex;
}
if (a.ssid === ssid)
return -1;
@@ -677,38 +683,50 @@ Rectangle {
}
}
DankRipple {
id: pinRipple
cornerRadius: parent.radius
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y)
onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}))
let pinnedList = wifiContent.normalizePinList(pins["preferredWifi"])
const pinIndex = pinnedList.indexOf(modelData.ssid)
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}));
let pinnedList = wifiContent.normalizePinList(pins["preferredWifi"]);
const pinIndex = pinnedList.indexOf(modelData.ssid);
if (pinIndex !== -1) {
pinnedList.splice(pinIndex, 1)
pinnedList.splice(pinIndex, 1);
} else {
pinnedList.unshift(modelData.ssid)
pinnedList.unshift(modelData.ssid);
if (pinnedList.length > wifiContent.maxPinnedNetworks)
pinnedList = pinnedList.slice(0, wifiContent.maxPinnedNetworks)
pinnedList = pinnedList.slice(0, wifiContent.maxPinnedNetworks);
}
if (pinnedList.length > 0)
pins["preferredWifi"] = pinnedList
pins["preferredWifi"] = pinnedList;
else
delete pins["preferredWifi"]
delete pins["preferredWifi"];
SettingsData.set("wifiNetworkPins", pins)
SettingsData.set("wifiNetworkPins", pins);
}
}
}
DankRipple {
id: wifiRipple
cornerRadius: parent.radius
}
MouseArea {
id: networkMouseArea
anchors.fill: parent
anchors.rightMargin: optionsButton.width + Theme.spacingM + Theme.spacingS + pinWifiRow.width + Theme.spacingS * 4
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => wifiRipple.trigger(mouse.x, mouse.y)
onClicked: function (event) {
if (modelData.ssid !== NetworkService.currentWifiSSID) {
if (modelData.secured && !modelData.saved) {

View File

@@ -22,12 +22,18 @@ Row {
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
DankRipple {
id: iconRipple
cornerRadius: parent.radius
}
MouseArea {
id: iconArea
anchors.fill: parent
visible: defaultSink !== null
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (defaultSink) {
SessionData.suppressOSDTemporarily();

View File

@@ -91,12 +91,18 @@ Row {
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
DankRipple {
id: iconRipple
cornerRadius: parent.radius
}
MouseArea {
id: iconArea
anchors.fill: parent
hoverEnabled: true
cursorShape: DisplayService.devices && DisplayService.devices.length > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor
onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (DisplayService.devices && DisplayService.devices.length > 1) {
root.iconClicked();

View File

@@ -72,6 +72,11 @@ Rectangle {
}
}
DankRipple {
id: bodyRipple
cornerRadius: root.radius
}
Row {
id: row
anchors.fill: parent
@@ -112,11 +117,17 @@ Rectangle {
color: isActive ? _tileIconActive : _tileIconInactive
}
DankRipple {
id: tileRipple
cornerRadius: _tileRadius
}
MouseArea {
id: tileMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => tileRipple.trigger(mouse.x, mouse.y)
onClicked: root.toggled()
}
}
@@ -167,7 +178,11 @@ Rectangle {
rightHoverOverlay.opacity = 0.0;
rightHoverOverlay.visible = false;
}
onPressed: rightHoverOverlay.opacity = 0.16
onPressed: mouse => {
const pos = mapToItem(root, mouse.x, mouse.y);
bodyRipple.trigger(pos.x, pos.y);
rightHoverOverlay.opacity = 0.16;
}
onReleased: rightHoverOverlay.opacity = containsMouse ? 0.08 : 0.0
onClicked: root.expandClicked()
onWheel: function (ev) {

View File

@@ -22,12 +22,18 @@ Row {
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
DankRipple {
id: iconRipple
cornerRadius: parent.radius
}
MouseArea {
id: iconArea
anchors.fill: parent
visible: defaultSource !== null
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y)
onClicked: {
if (defaultSource) {
SessionData.suppressOSDTemporarily();

View File

@@ -89,12 +89,18 @@ Rectangle {
}
}
DankRipple {
id: ripple
cornerRadius: root.radius
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
enabled: root.enabled
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
onClicked: root.clicked()
}

View File

@@ -105,12 +105,18 @@ Rectangle {
}
}
DankRipple {
id: ripple
cornerRadius: root.radius
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
enabled: root.enabled
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
onClicked: root.clicked()
}

View File

@@ -66,12 +66,18 @@ Rectangle {
onRotationCompleted: root.iconRotationCompleted()
}
DankRipple {
id: ripple
cornerRadius: root.radius
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
enabled: root.enabled
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
onClicked: root.clicked()
}

View File

@@ -110,12 +110,18 @@ Rectangle {
}
}
DankRipple {
id: ripple
cornerRadius: root.radius
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
enabled: root.enabled
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
onClicked: root.clicked()
}