forked from Shinonome/dots-hyprland
wallpaper selector: directory validation, common file browser keybinds
This commit is contained in:
@@ -17,6 +17,11 @@ Rectangle {
|
|||||||
implicitHeight: mainLayout.implicitHeight + padding * 2
|
implicitHeight: mainLayout.implicitHeight + padding * 2
|
||||||
color: Appearance.colors.colLayer2
|
color: Appearance.colors.colLayer2
|
||||||
|
|
||||||
|
function focusBreadcrumb() {
|
||||||
|
root.showBreadcrumb = false;
|
||||||
|
addressInput.forceActiveFocus();
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors {
|
anchors {
|
||||||
@@ -38,43 +43,54 @@ Rectangle {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
Loader {
|
Rectangle {
|
||||||
active: !root.showBreadcrumb
|
id: directoryEntry
|
||||||
visible: !root.showBreadcrumb
|
visible: !root.showBreadcrumb
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceComponent: Rectangle {
|
color: Appearance.colors.colLayer1
|
||||||
color: Appearance.colors.colLayer1
|
radius: Appearance.rounding.full
|
||||||
radius: Appearance.rounding.full
|
implicitWidth: addressInput.implicitWidth
|
||||||
implicitWidth: addressInput.implicitWidth
|
implicitHeight: addressInput.implicitHeight
|
||||||
implicitHeight: addressInput.implicitHeight
|
|
||||||
|
|
||||||
StyledTextInput {
|
Keys.onPressed: event => {
|
||||||
id: addressInput
|
if (directoryEntry.visible && event.key === Qt.Key_Escape) {
|
||||||
|
root.showBreadcrumb = true;
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.accepted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledTextInput {
|
||||||
|
id: addressInput
|
||||||
|
anchors.fill: parent
|
||||||
|
padding: 10
|
||||||
|
text: root.directory
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
root.navigateToDirectory(text);
|
||||||
|
root.showBreadcrumb = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
// I-beam cursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
padding: 10
|
acceptedButtons: Qt.NoButton
|
||||||
text: root.directory
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
onAccepted: root.navigateToDirectory(text)
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
// I-beam cursor
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: breadcrumbLoader
|
||||||
active: root.showBreadcrumb
|
active: root.showBreadcrumb
|
||||||
visible: root.showBreadcrumb
|
visible: root.showBreadcrumb
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceComponent: AddressBreadcrumb {
|
sourceComponent: AddressBreadcrumb {
|
||||||
directory: root.directory
|
directory: root.directory
|
||||||
onNavigateToDirectory: (dir) => {
|
onNavigateToDirectory: dir => {
|
||||||
root.navigateToDirectory(dir)
|
root.navigateToDirectory(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import QtQuick.Controls
|
|||||||
* Does not include visual layout, but includes the easily neglected colors.
|
* Does not include visual layout, but includes the easily neglected colors.
|
||||||
*/
|
*/
|
||||||
TextInput {
|
TextInput {
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
||||||
selectionColor: Appearance.colors.colSecondaryContainer
|
selectionColor: Appearance.colors.colSecondaryContainer
|
||||||
|
|||||||
@@ -20,11 +20,15 @@ Item {
|
|||||||
implicitWidth: columnLayout.implicitWidth
|
implicitWidth: columnLayout.implicitWidth
|
||||||
property var wallpapers: Wallpapers.wallpapers
|
property var wallpapers: Wallpapers.wallpapers
|
||||||
property string filterQuery: ""
|
property string filterQuery: ""
|
||||||
|
property bool useDarkMode: Appearance.m3colors.darkmode
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
Keys.onPressed: event => {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
GlobalStates.wallpaperSelectorOpen = false;
|
GlobalStates.wallpaperSelectorOpen = false;
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
|
} else if (event.modifiers & Qt.AltModifier && event.key === Qt.Key_Up) {
|
||||||
|
Wallpapers.setDirectory(FileUtils.parentDirectory(Wallpapers.directory));
|
||||||
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Left) {
|
} else if (event.key === Qt.Key_Left) {
|
||||||
grid.moveSelection(-1);
|
grid.moveSelection(-1);
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
@@ -32,11 +36,7 @@ Item {
|
|||||||
grid.moveSelection(1);
|
grid.moveSelection(1);
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Up) {
|
} else if (event.key === Qt.Key_Up) {
|
||||||
if (grid.currentIndex < grid.columns) {
|
grid.moveSelection(-grid.columns);
|
||||||
filterField.forceActiveFocus();
|
|
||||||
} else {
|
|
||||||
grid.moveSelection(-grid.columns);
|
|
||||||
}
|
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Down) {
|
} else if (event.key === Qt.Key_Down) {
|
||||||
grid.moveSelection(grid.columns);
|
grid.moveSelection(grid.columns);
|
||||||
@@ -50,6 +50,9 @@ Item {
|
|||||||
}
|
}
|
||||||
filterField.forceActiveFocus();
|
filterField.forceActiveFocus();
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
|
} else if (event.modifiers & Qt.ControlModifier && event.key === Qt.Key_L) {
|
||||||
|
addressBar.focusBreadcrumb();
|
||||||
|
event.accepted = true;
|
||||||
} else {
|
} else {
|
||||||
filterField.forceActiveFocus();
|
filterField.forceActiveFocus();
|
||||||
if (event.text.length > 0) {
|
if (event.text.length > 0) {
|
||||||
@@ -103,7 +106,7 @@ Item {
|
|||||||
Layout.fillHeight: false
|
Layout.fillHeight: false
|
||||||
directory: Wallpapers.directory
|
directory: Wallpapers.directory
|
||||||
onNavigateToDirectory: path => {
|
onNavigateToDirectory: path => {
|
||||||
Wallpapers.directory = path;
|
Wallpapers.setDirectory(path);
|
||||||
}
|
}
|
||||||
radius: wallpaperGridBackground.radius - Layout.margins
|
radius: wallpaperGridBackground.radius - Layout.margins
|
||||||
}
|
}
|
||||||
@@ -154,12 +157,13 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function activateCurrent() {
|
function activateCurrent() {
|
||||||
const path = model[currentIndex];
|
print("ACTIVATE");
|
||||||
|
const path = grid.model.values[currentIndex];
|
||||||
if (!path)
|
if (!path)
|
||||||
return;
|
return;
|
||||||
GlobalStates.wallpaperSelectorOpen = false;
|
GlobalStates.wallpaperSelectorOpen = false;
|
||||||
filterField.text = "";
|
filterField.text = "";
|
||||||
Wallpapers.apply(path);
|
Wallpapers.apply(path, root.useDarkMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
@@ -284,7 +288,7 @@ Item {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
GlobalStates.wallpaperSelectorOpen = false;
|
GlobalStates.wallpaperSelectorOpen = false;
|
||||||
filterField.text = "";
|
filterField.text = "";
|
||||||
Wallpapers.apply(wallpaperItem.modelData);
|
Wallpapers.apply(wallpaperItem.modelData, root.useDarkMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,22 +330,34 @@ Item {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.topMargin: 2
|
Layout.topMargin: 2
|
||||||
Layout.bottomMargin: 2
|
Layout.bottomMargin: 2
|
||||||
|
implicitWidth: height
|
||||||
buttonRadius: Appearance.rounding.full
|
buttonRadius: Appearance.rounding.full
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Wallpapers.openFallbackPicker();
|
Wallpapers.openFallbackPicker();
|
||||||
GlobalStates.wallpaperSelectorOpen = false;
|
GlobalStates.wallpaperSelectorOpen = false;
|
||||||
}
|
}
|
||||||
contentItem: RowLayout {
|
contentItem: MaterialSymbol {
|
||||||
MaterialSymbol {
|
text: "files"
|
||||||
text: "files"
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
iconSize: Appearance.font.pixelSize.larger
|
|
||||||
}
|
|
||||||
StyledText {
|
|
||||||
text: Translation.tr("System")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
content: "Use the system file picker instead"
|
content: Translation.tr("Use the system file picker instead")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RippleButton {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.topMargin: 2
|
||||||
|
Layout.bottomMargin: 2
|
||||||
|
implicitWidth: height
|
||||||
|
buttonRadius: Appearance.rounding.full
|
||||||
|
onClicked: root.useDarkMode = !root.useDarkMode
|
||||||
|
contentItem: MaterialSymbol {
|
||||||
|
text: root.useDarkMode ? "dark_mode" : "light_mode"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
}
|
||||||
|
StyledToolTip {
|
||||||
|
content: Translation.tr("Click to toggle light/dark mode (applied when wallpaper is chosen)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,35 +385,20 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
Keys.onPressed: event => {
|
||||||
if (text.length === 0) {
|
if (text.length !== 0) {
|
||||||
if (event.key === Qt.Key_Down || event.key === Qt.Key_Left || event.key === Qt.Key_Right) {
|
// No filtering, just navigate grid
|
||||||
wallpaperGrid.forceActiveFocus();
|
|
||||||
if (event.key === Qt.Key_Down)
|
|
||||||
grid.moveSelection(grid.columns);
|
|
||||||
else if (event.key === Qt.Key_Left)
|
|
||||||
grid.moveSelection(-1);
|
|
||||||
else if (event.key === Qt.Key_Right)
|
|
||||||
grid.moveSelection(1);
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (event.key === Qt.Key_Down) {
|
if (event.key === Qt.Key_Down) {
|
||||||
grid.moveSelection(grid.columns);
|
grid.moveSelection(grid.columns);
|
||||||
event.accepted = true;
|
|
||||||
wallpaperGrid.forceActiveFocus();
|
wallpaperGrid.forceActiveFocus();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
if (event.key === Qt.Key_Up) {
|
||||||
|
grid.moveSelection(-grid.columns);
|
||||||
|
wallpaperGrid.forceActiveFocus();
|
||||||
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
event.accepted = false;
|
||||||
grid.activateCurrent();
|
|
||||||
event.accepted = true;
|
|
||||||
} else if (event.key === Qt.Key_Escape) {
|
|
||||||
if (filterField.text.length > 0) {
|
|
||||||
filterField.text = "";
|
|
||||||
} else {
|
|
||||||
GlobalStates.wallpaperSelectorOpen = false;
|
|
||||||
}
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,15 +410,9 @@ Item {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
GlobalStates.wallpaperSelectorOpen = false;
|
GlobalStates.wallpaperSelectorOpen = false;
|
||||||
}
|
}
|
||||||
implicitWidth: height
|
|
||||||
|
|
||||||
contentItem: MaterialSymbol {
|
contentItem: StyledText {
|
||||||
text: "close"
|
text: "Cancel"
|
||||||
iconSize: Appearance.font.pixelSize.larger
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledToolTip {
|
|
||||||
content: "Cancel"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,15 +30,32 @@ Singleton {
|
|||||||
applyProc.exec([Directories.wallpaperSwitchScriptPath])
|
applyProc.exec([Directories.wallpaperSwitchScriptPath])
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply(path) {
|
function apply(path, darkMode = Appearance.m3colors.darkmode) {
|
||||||
if (!path || path.length === 0) return
|
if (!path || path.length === 0) return
|
||||||
applyProc.exec([
|
applyProc.exec([
|
||||||
"bash", "-c",
|
Directories.wallpaperSwitchScriptPath,
|
||||||
`${StringUtils.shellSingleQuoteEscape(Directories.wallpaperSwitchScriptPath)} ` +
|
"--image", path,
|
||||||
`--image ${StringUtils.shellSingleQuoteEscape(path)}`
|
"--mode", (darkMode ? "dark" : "light")
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: validateDirProc
|
||||||
|
property string nicePath: ""
|
||||||
|
function setDirectoryIfValid(path) {
|
||||||
|
validateDirProc.nicePath = FileUtils.trimFileProtocol(path).replace(/\/+$/, "")
|
||||||
|
validateDirProc.exec(["test", "-d", nicePath])
|
||||||
|
}
|
||||||
|
onExited: (exitCode, exitStatus) => {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
root.directory = validateDirProc.nicePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function setDirectory(path) {
|
||||||
|
validateDirProc.setDirectoryIfValid(path)
|
||||||
|
}
|
||||||
|
|
||||||
// Folder model
|
// Folder model
|
||||||
FolderListModel {
|
FolderListModel {
|
||||||
id: files
|
id: files
|
||||||
|
|||||||
Reference in New Issue
Block a user