refactor toolbar fab

This commit is contained in:
end-4
2026-04-03 18:53:33 +02:00
parent eef2b691e7
commit 59398595a5
4 changed files with 164 additions and 121 deletions
@@ -0,0 +1,35 @@
pragma ComponentBehavior: Bound
import QtQuick
import qs.modules.common
Item {
id: root
signal clicked(event: var)
property alias iconText: fabWidget.iconText
default property alias fabData: fabWidget.data
property bool enableShadow: true
anchors {
verticalCenter: parent.verticalCenter
}
implicitWidth: fabWidget.implicitWidth
implicitHeight: fabWidget.implicitHeight
Loader {
active: root.enableShadow
anchors.fill: parent
sourceComponent: StyledRectangularShadow {
target: fabWidget
radius: fabWidget.buttonRadius
}
}
FloatingActionButton {
id: fabWidget
onClicked: e => root.clicked(e)
baseSize: 48
colBackground: Appearance.colors.colTertiaryContainer
colBackgroundHover: Appearance.colors.colTertiaryContainerHover
colRipple: Appearance.colors.colTertiaryContainerActive
colOnBackground: Appearance.colors.colOnTertiaryContainer
}
}
@@ -528,28 +528,12 @@ PanelWindow {
} }
onDismiss: root.dismiss(); onDismiss: root.dismiss();
} }
Item { ToolbarPairedFab {
anchors { anchors.verticalCenter: parent.verticalCenter
verticalCenter: parent.verticalCenter iconText: "close"
} onClicked: root.dismiss();
implicitWidth: closeFab.implicitWidth StyledToolTip {
implicitHeight: closeFab.implicitHeight text: Translation.tr("Close")
StyledRectangularShadow {
target: closeFab
radius: closeFab.buttonRadius
}
FloatingActionButton {
id: closeFab
baseSize: 48
iconText: "close"
onClicked: root.dismiss();
StyledToolTip {
text: Translation.tr("Close")
}
colBackground: Appearance.colors.colTertiaryContainer
colBackgroundHover: Appearance.colors.colTertiaryContainerHover
colRipple: Appearance.colors.colTertiaryContainerActive
colOnBackground: Appearance.colors.colOnTertiaryContainer
} }
} }
} }
@@ -1,17 +1,9 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import qs import qs
import qs.modules.common import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
import qs.services
import QtQuick import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Widgets
import Quickshell.Hyprland import Quickshell.Hyprland
Scope { Scope {
@@ -17,20 +17,20 @@ MouseArea {
property bool useDarkMode: Appearance.m3colors.darkmode property bool useDarkMode: Appearance.m3colors.darkmode
function updateThumbnails() { function updateThumbnails() {
const totalImageMargin = (Appearance.sizes.wallpaperSelectorItemMargins + Appearance.sizes.wallpaperSelectorItemPadding) * 2 const totalImageMargin = (Appearance.sizes.wallpaperSelectorItemMargins + Appearance.sizes.wallpaperSelectorItemPadding) * 2;
const thumbnailSizeName = Images.thumbnailSizeNameForDimensions(grid.cellWidth - totalImageMargin, grid.cellHeight - totalImageMargin) const thumbnailSizeName = Images.thumbnailSizeNameForDimensions(grid.cellWidth - totalImageMargin, grid.cellHeight - totalImageMargin);
Wallpapers.generateThumbnail(thumbnailSizeName) Wallpapers.generateThumbnail(thumbnailSizeName);
} }
Connections { Connections {
target: Wallpapers target: Wallpapers
function onDirectoryChanged() { function onDirectoryChanged() {
root.updateThumbnails() root.updateThumbnails();
} }
} }
function handleFilePasting(event) { function handleFilePasting(event) {
const currentClipboardEntry = Cliphist.entries[0] const currentClipboardEntry = Cliphist.entries[0];
if (/^\d+\tfile:\/\/\S+/.test(currentClipboardEntry)) { if (/^\d+\tfile:\/\/\S+/.test(currentClipboardEntry)) {
const url = StringUtils.cleanCliphistEntry(currentClipboardEntry); const url = StringUtils.cleanCliphistEntry(currentClipboardEntry);
Wallpapers.setDirectory(FileUtils.trimFileProtocol(decodeURIComponent(url))); Wallpapers.setDirectory(FileUtils.trimFileProtocol(decodeURIComponent(url)));
@@ -164,15 +164,48 @@ MouseArea {
implicitWidth: 140 implicitWidth: 140
clip: true clip: true
model: [ model: [
{ icon: "home", name: "Home", path: Directories.home }, {
{ icon: "docs", name: "Documents", path: Directories.documents }, icon: "home",
{ icon: "download", name: "Downloads", path: Directories.downloads }, name: "Home",
{ icon: "image", name: "Pictures", path: Directories.pictures }, path: Directories.home
{ icon: "movie", name: "Videos", path: Directories.videos }, },
{ icon: "", name: "---", path: "INTENTIONALLY_INVALID_DIR" }, {
{ icon: "wallpaper", name: "Wallpapers", path: `${Directories.pictures}/Wallpapers` }, icon: "docs",
...(Config.options.policies.weeb === 1 ? [{ icon: "favorite", name: "Homework", path: `${Directories.pictures}/homework` }] : []), name: "Documents",
] path: Directories.documents
},
{
icon: "download",
name: "Downloads",
path: Directories.downloads
},
{
icon: "image",
name: "Pictures",
path: Directories.pictures
},
{
icon: "movie",
name: "Videos",
path: Directories.videos
},
{
icon: "",
name: "---",
path: "INTENTIONALLY_INVALID_DIR"
},
{
icon: "wallpaper",
name: "Wallpapers",
path: `${Directories.pictures}/Wallpapers`
},
...(Config.options.policies.weeb === 1 ? [
{
icon: "favorite",
name: "Homework",
path: `${Directories.pictures}/homework`
}
] : []),]
delegate: RippleButton { delegate: RippleButton {
id: quickDirButton id: quickDirButton
required property var modelData required property var modelData
@@ -267,7 +300,7 @@ MouseArea {
ScrollBar.vertical: StyledScrollBar {} ScrollBar.vertical: StyledScrollBar {}
Component.onCompleted: { Component.onCompleted: {
root.updateThumbnails() root.updateThumbnails();
} }
function moveSelection(delta) { function moveSelection(delta) {
@@ -276,7 +309,7 @@ MouseArea {
} }
function activateCurrent() { function activateCurrent() {
const filePath = grid.model.get(currentIndex, "filePath") const filePath = grid.model.get(currentIndex, "filePath");
root.selectWallpaperPath(filePath); root.selectWallpaperPath(filePath);
} }
@@ -310,92 +343,91 @@ MouseArea {
} }
} }
Toolbar { Row {
id: extraOptions id: extraOptions
anchors { anchors {
bottom: parent.bottom bottom: parent.bottom
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
bottomMargin: 8 bottomMargin: 8
} }
spacing: 6
Toolbar {
IconToolbarButton { IconToolbarButton {
implicitWidth: height implicitWidth: height
onClicked: { onClicked: {
Wallpapers.openFallbackPicker(root.useDarkMode); Wallpapers.openFallbackPicker(root.useDarkMode);
GlobalStates.wallpaperSelectorOpen = false; GlobalStates.wallpaperSelectorOpen = false;
}
altAction: () => {
Wallpapers.openFallbackPicker(root.useDarkMode);
GlobalStates.wallpaperSelectorOpen = false;
Config.options.wallpaperSelector.useSystemFileDialog = true
}
text: "open_in_new"
StyledToolTip {
text: Translation.tr("Use the system file picker instead\nRight-click to make this the default behavior")
}
}
IconToolbarButton {
implicitWidth: height
onClicked: {
Wallpapers.randomFromCurrentFolder();
}
text: "ifl"
StyledToolTip {
text: Translation.tr("Pick random from this folder")
}
}
IconToolbarButton {
implicitWidth: height
onClicked: root.useDarkMode = !root.useDarkMode
text: root.useDarkMode ? "dark_mode" : "light_mode"
StyledToolTip {
text: Translation.tr("Click to toggle light/dark mode\n(applied when wallpaper is chosen)")
}
}
ToolbarTextField {
id: filterField
placeholderText: focus ? Translation.tr("Search wallpapers") : Translation.tr("Hit \"/\" to search")
// Style
clip: true
font.pixelSize: Appearance.font.pixelSize.small
// Search
onTextChanged: {
Wallpapers.searchQuery = text;
}
Keys.onPressed: event => {
if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_V) { // Intercept Ctrl+V to handle "paste to go to" in pickers
root.handleFilePasting(event);
return;
} }
else if (text.length !== 0) { altAction: () => {
// No filtering, just navigate grid Wallpapers.openFallbackPicker(root.useDarkMode);
if (event.key === Qt.Key_Down) { GlobalStates.wallpaperSelectorOpen = false;
grid.moveSelection(grid.columns); Config.options.wallpaperSelector.useSystemFileDialog = true;
event.accepted = true; }
return; text: "open_in_new"
} StyledToolTip {
if (event.key === Qt.Key_Up) { text: Translation.tr("Use the system file picker instead\nRight-click to make this the default behavior")
grid.moveSelection(-grid.columns); }
event.accepted = true; }
return;
} IconToolbarButton {
implicitWidth: height
onClicked: {
Wallpapers.randomFromCurrentFolder();
}
text: "ifl"
StyledToolTip {
text: Translation.tr("Pick random from this folder")
}
}
IconToolbarButton {
implicitWidth: height
onClicked: root.useDarkMode = !root.useDarkMode
text: root.useDarkMode ? "dark_mode" : "light_mode"
StyledToolTip {
text: Translation.tr("Click to toggle light/dark mode\n(applied when wallpaper is chosen)")
}
}
ToolbarTextField {
id: filterField
placeholderText: focus ? Translation.tr("Search wallpapers") : Translation.tr("Hit \"/\" to search")
// Style
clip: true
font.pixelSize: Appearance.font.pixelSize.small
// Search
onTextChanged: {
Wallpapers.searchQuery = text;
}
Keys.onPressed: event => {
if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_V) { // Intercept Ctrl+V to handle "paste to go to" in pickers
root.handleFilePasting(event);
return;
} else if (text.length !== 0) {
// No filtering, just navigate grid
if (event.key === Qt.Key_Down) {
grid.moveSelection(grid.columns);
event.accepted = true;
return;
}
if (event.key === Qt.Key_Up) {
grid.moveSelection(-grid.columns);
event.accepted = true;
return;
}
}
event.accepted = false;
} }
event.accepted = false;
} }
} }
IconToolbarButton { ToolbarPairedFab {
implicitWidth: height iconText: "close"
onClicked: { onClicked: GlobalStates.wallpaperSelectorOpen = false;
GlobalStates.wallpaperSelectorOpen = false;
}
text: "close"
StyledToolTip { StyledToolTip {
text: Translation.tr("Cancel wallpaper selection") text: Translation.tr("Cancel wallpaper selection")
} }