diff --git a/.config/quickshell/modules/common/widgets/MenuButton.qml b/.config/quickshell/modules/common/widgets/MenuButton.qml new file mode 100644 index 000000000..957c2229d --- /dev/null +++ b/.config/quickshell/modules/common/widgets/MenuButton.qml @@ -0,0 +1,51 @@ +import "root:/modules/common" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Io + +Button { + id: button + + property string buttonText + implicitHeight: 36 + implicitWidth: buttonTextWidget.implicitWidth + 14 * 2 + + PointingHandInteraction {} + + background: Rectangle { + anchors.fill: parent + color: (button.down && button.enabled) ? Appearance.transparentize(Appearance.m3colors.m3onSurface, 0.84) : + ((button.hovered && button.enabled) ? Appearance.transparentize(Appearance.m3colors.m3onSurface, 0.92) : + Appearance.transparentize(Appearance.m3colors.m3onSurface, 1)) + + Behavior on color { + ColorAnimation { + duration: Appearance.animation.elementDecel.duration + easing.type: Appearance.animation.elementDecel.type + } + + } + + } + + contentItem: StyledText { + id: buttonTextWidget + anchors.fill: parent + anchors.leftMargin: 14 + anchors.rightMargin: 14 + text: buttonText + horizontalAlignment: Text.AlignLeft + font.pixelSize: Appearance.font.pixelSize.small + color: button.enabled ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3outline + + Behavior on color { + ColorAnimation { + duration: Appearance.animation.elementDecel.duration + easing.type: Appearance.animation.elementDecel.type + } + } + } + +} diff --git a/.config/quickshell/modules/sidebarLeft/Anime.qml b/.config/quickshell/modules/sidebarLeft/Anime.qml index ec070f261..ed2f26237 100644 --- a/.config/quickshell/modules/sidebarLeft/Anime.qml +++ b/.config/quickshell/modules/sidebarLeft/Anime.qml @@ -112,10 +112,7 @@ Item { spacing: 10 model: ScriptModel { - values: { - console.log(JSON.stringify(Booru.responses)) - return Booru.responses - } + values: Booru.responses } delegate: BooruResponse { responseData: modelData diff --git a/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml b/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml index 71f7713f1..9652bf01d 100644 --- a/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml +++ b/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml @@ -229,4 +229,18 @@ Scope { // Scope } } + GlobalShortcut { + name: "sidebarLeftClose" + description: "Closes left sidebar on press" + + onPressed: { + for (let i = 0; i < sidebarVariants.instances.length; i++) { + let panelWindow = sidebarVariants.instances[i]; + if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) { + panelWindow.visible = false; + } + } + } + } + } diff --git a/.config/quickshell/modules/sidebarLeft/anime/BooruImage.qml b/.config/quickshell/modules/sidebarLeft/anime/BooruImage.qml index f869d059d..cbd2acbbb 100644 --- a/.config/quickshell/modules/sidebarLeft/anime/BooruImage.qml +++ b/.config/quickshell/modules/sidebarLeft/anime/BooruImage.qml @@ -19,6 +19,8 @@ Button { property string nsfwPath property string fileName: decodeURIComponent((imageData.file_url).substring((imageData.file_url).lastIndexOf('/') + 1)) + property bool showActions: false + Process { id: downloadProcess running: false @@ -46,11 +48,7 @@ Button { implicitWidth: imageObject.width implicitHeight: imageObject.height - PointingHandInteraction {} - - onClicked: { - Hyprland.dispatch(`exec xdg-open ${imageData.source}`) - } + // PointingHandInteraction {} background: Rectangle { implicitWidth: imageObject.width @@ -59,23 +57,107 @@ Button { color: Appearance.colors.colLayer2 } - contentItem: Image { - id: imageObject + contentItem: Item { anchors.fill: parent - sourceSize.width: root.rowHeight * modelData.aspect_ratio - sourceSize.height: root.rowHeight - fillMode: Image.PreserveAspectFit - source: modelData.preview_url - width: root.rowHeight * modelData.aspect_ratio - height: root.rowHeight - layer.enabled: true - layer.effect: OpacityMask { - maskSource: Rectangle { - width: imageObject.width - height: imageObject.height - radius: Appearance.rounding.small + Image { + id: imageObject + anchors.fill: parent + sourceSize.width: root.rowHeight * modelData.aspect_ratio + sourceSize.height: root.rowHeight + fillMode: Image.PreserveAspectFit + source: modelData.preview_url + width: root.rowHeight * modelData.aspect_ratio + height: root.rowHeight + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: imageObject.width + height: imageObject.height + radius: Appearance.rounding.small + } } } + + Button { + id: menuButton + anchors.top: parent.top + anchors.right: parent.right + anchors.margins: 8 + implicitHeight: 30 + implicitWidth: 30 + + PointingHandInteraction {} + + background: Rectangle { + color: menuButton.down ? Appearance.mix(Appearance.colors.colScrim, Appearance.m3colors.m3onSurface, 0.6) : + menuButton.hovered ? Appearance.mix(Appearance.colors.colScrim, Appearance.m3colors.m3onSurface, 0.8) : + Appearance.colors.colScrim + radius: Appearance.rounding.full + } + + contentItem: MaterialSymbol { + horizontalAlignment: Text.AlignHCenter + font.pixelSize: Appearance.font.pixelSize.large + color: Appearance.m3colors.m3onSurface + text: "more_vert" + } + + onClicked: { + root.showActions = !root.showActions + } + } + + Rectangle { + id: contextMenu + visible: root.showActions + radius: Appearance.rounding.small + color: Appearance.m3colors.m3surfaceContainer + anchors.top: menuButton.bottom + anchors.right: parent.right + anchors.margins: 8 + implicitHeight: contextMenuColumnLayout.implicitHeight + radius * 2 + implicitWidth: contextMenuColumnLayout.implicitWidth + + ColumnLayout { + id: contextMenuColumnLayout + anchors.centerIn: parent + spacing: 0 + + MenuButton { + id: openFileLinkButton + Layout.fillWidth: true + buttonText: "Open file link" + onClicked: { + root.showActions = false + Hyprland.dispatch("global quickshell:sidebarLeftClose") + Hyprland.dispatch(`exec xdg-open '${root.imageData.file_url}'`) + } + } + MenuButton { + id: sourceButton + Layout.fillWidth: true + buttonText: "Go to source" + enabled: root.imageData.source && root.imageData.source.length > 0 + onClicked: { + root.showActions = false + Hyprland.dispatch("global quickshell:sidebarLeftClose") + Hyprland.dispatch(`exec xdg-open '${root.imageData.source}'`) + } + } + MenuButton { + id: downloadButton + Layout.fillWidth: true + buttonText: "Download" + onClicked: { + root.showActions = false + Hyprland.dispatch("global quickshell:sidebarLeftClose") + Hyprland.dispatch(`exec curl '${root.imageData.file_url}' -o '${root.imageData.is_nsfw ? root.nsfwPath : root.downloadPath}/${root.fileName}' && notify-send 'Download complete' '${root.downloadPath}/${root.fileName}'`) + } + } + } + } + } } \ No newline at end of file diff --git a/.config/quickshell/modules/sidebarLeft/anime/BooruResponse.qml b/.config/quickshell/modules/sidebarLeft/anime/BooruResponse.qml index 780e3fe9a..64cb757fc 100644 --- a/.config/quickshell/modules/sidebarLeft/anime/BooruResponse.qml +++ b/.config/quickshell/modules/sidebarLeft/anime/BooruResponse.qml @@ -26,7 +26,7 @@ Rectangle { } property real availableWidth: parent.width ?? 0 - property real rowTooShortThreshold: 100 + property real rowTooShortThreshold: 185 property real imageSpacing: 5 property real responsePadding: 5 @@ -190,9 +190,9 @@ Rectangle { } } // Otherwise, put only one image in the row - const rowHeight = availableImageWidth / responseList[i].aspect_ratio; + const rowHeight = (availableWidth - (responsePadding * 2)) / responseList[i].aspect_ratio; rows.push({ - height: availableWidth / responseList[i].aspect_ratio, + height: rowHeight, images: [responseList[i]], }); i += 1;