NFilePicker: renamed NFileManager to NFilePicker, update grid hover

This commit is contained in:
Ly-sec
2025-09-21 19:44:04 +02:00
parent dfe3aed46e
commit 3bbf26a18e
5 changed files with 110 additions and 108 deletions
+11 -11
View File
@@ -42,17 +42,17 @@ ColumnLayout {
Settings.data.general.avatarImage = text Settings.data.general.avatarImage = text
} }
onButtonClicked: { onButtonClicked: {
FileManagerService.open({ FilePickerService.open({
"title": "Select Avatar Image", "title": "Select Avatar Image",
"initialPath": Settings.data.general.avatarImage || Quickshell.env("HOME"), "initialPath": Settings.data.general.avatarImage || Quickshell.env("HOME"),
"selectFiles": true, "selectFiles": true,
"scaling": scaling, "scaling": scaling,
"onSelected": function (path) { "onSelected": function (path) {
Settings.data.general.avatarImage = path Settings.data.general.avatarImage = path
text = path text = path
}, },
"parent": root "parent": root
}) })
} }
} }
} }
@@ -32,17 +32,17 @@ ColumnLayout {
Settings.data.screenRecorder.directory = text Settings.data.screenRecorder.directory = text
} }
onButtonClicked: { onButtonClicked: {
FileManagerService.open({ FilePickerService.open({
"title": "Select Output Folder", "title": "Select Output Folder",
"initialPath": Settings.data.screenRecorder.directory || Quickshell.env("HOME") + "/Videos", "initialPath": Settings.data.screenRecorder.directory || Quickshell.env("HOME") + "/Videos",
"selectFiles": false, "selectFiles": false,
"scaling": scaling, "scaling": scaling,
"onSelected": function (path) { "onSelected": function (path) {
Settings.data.screenRecorder.directory = path Settings.data.screenRecorder.directory = path
text = path text = path
}, },
"parent": root "parent": root
}) })
} }
} }
+21 -21
View File
@@ -345,29 +345,29 @@ ColumnLayout {
// File manager functions // File manager functions
function openFileManager() { function openFileManager() {
FileManagerService.open({ FilePickerService.open({
"title": "Select Wallpaper Folder", "title": "Select Wallpaper Folder",
"initialPath": Settings.data.wallpaper.directory || Quickshell.env("HOME"), "initialPath": Settings.data.wallpaper.directory || Quickshell.env("HOME"),
"selectFiles": false, "selectFiles": false,
"scaling": scaling, "scaling": scaling,
"onSelected": function (path) { "onSelected": function (path) {
Settings.data.wallpaper.directory = path Settings.data.wallpaper.directory = path
wallpaperPathInput.text = path wallpaperPathInput.text = path
}, },
"parent": root "parent": root
}) })
} }
function openMonitorFileManager(monitorName) { function openMonitorFileManager(monitorName) {
FileManagerService.open({ FilePickerService.open({
"title": "Select Monitor Wallpaper Folder", "title": "Select Monitor Wallpaper Folder",
"initialPath": WallpaperService.getMonitorDirectory(monitorName), "initialPath": WallpaperService.getMonitorDirectory(monitorName),
"selectFiles": false, "selectFiles": false,
"scaling": scaling, "scaling": scaling,
"onSelected": function (path) { "onSelected": function (path) {
WallpaperService.setMonitorDirectory(monitorName, path) WallpaperService.setMonitorDirectory(monitorName, path)
}, },
"parent": root "parent": root
}) })
} }
} }
@@ -8,7 +8,7 @@ QtObject {
// Function to open a file manager dialog // Function to open a file manager dialog
function open(options) { function open(options) {
var component = Qt.createComponent(Qt.resolvedUrl(Quickshell.shellDir + "/Widgets/NFileManager.qml")) var component = Qt.createComponent(Qt.resolvedUrl(Quickshell.shellDir + "/Widgets/NFilePicker.qml"))
if (component.status === Component.Ready) { if (component.status === Component.Ready) {
// Extract directory from file path if it's a file // Extract directory from file path if it's a file
var initialPath = options.initialPath || Quickshell.env("HOME") var initialPath = options.initialPath || Quickshell.env("HOME")
@@ -13,7 +13,7 @@ Popup {
id: root id: root
// Public properties // Public properties
property string title: "File Manager" property string title: "File Picker"
property string initialPath: Quickshell.env("HOME") || "/home" property string initialPath: Quickshell.env("HOME") || "/home"
property bool selectFiles: true property bool selectFiles: true
property bool selectFolders: true property bool selectFolders: true
@@ -112,14 +112,14 @@ Popup {
} }
function confirmSelection() { function confirmSelection() {
if (fileManagerPanel.currentSelection.length === 0) { if (filePickerPanel.currentSelection.length === 0) {
return return
} }
root.selectedPaths = fileManagerPanel.currentSelection root.selectedPaths = filePickerPanel.currentSelection
if (fileManagerPanel.currentSelection.length === 1) { if (filePickerPanel.currentSelection.length === 1) {
var path = fileManagerPanel.currentSelection[0] var path = filePickerPanel.currentSelection[0]
if (root.selectFiles && !root.selectFolders) { if (root.selectFiles && !root.selectFolders) {
root.fileSelected(path) root.fileSelected(path)
} else if (root.selectFolders && !root.selectFiles) { } else if (root.selectFolders && !root.selectFiles) {
@@ -134,7 +134,7 @@ Popup {
} }
} }
} else { } else {
root.filesSelected(fileManagerPanel.currentSelection) root.filesSelected(filePickerPanel.currentSelection)
} }
root.close() root.close()
@@ -143,7 +143,7 @@ Popup {
// Function to update the filtered model // Function to update the filtered model
function updateFilteredModel() { function updateFilteredModel() {
filteredModel.clear() filteredModel.clear()
var searchText = fileManagerPanel.filterText.toLowerCase() var searchText = filePickerPanel.filterText.toLowerCase()
for (var i = 0; i < folderModel.count; i++) { for (var i = 0; i < folderModel.count; i++) {
var fileName = folderModel.get(i, "fileName") var fileName = folderModel.get(i, "fileName")
@@ -205,7 +205,7 @@ Popup {
} }
Rectangle { Rectangle {
id: fileManagerPanel id: filePickerPanel
anchors.fill: parent anchors.fill: parent
anchors.margins: Style.marginL * scaling anchors.margins: Style.marginL * scaling
color: Color.transparent color: Color.transparent
@@ -221,20 +221,20 @@ Popup {
// Keyboard shortcuts // Keyboard shortcuts
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.modifiers & Qt.ControlModifier && event.key === Qt.Key_F) { if (event.modifiers & Qt.ControlModifier && event.key === Qt.Key_F) {
fileManagerPanel.showSearchBar = !fileManagerPanel.showSearchBar filePickerPanel.showSearchBar = !filePickerPanel.showSearchBar
if (fileManagerPanel.showSearchBar) { if (filePickerPanel.showSearchBar) {
// Focus the search input when opening // Focus the search input when opening
Qt.callLater(() => { Qt.callLater(() => {
searchInput.forceActiveFocus() searchInput.forceActiveFocus()
}) })
} }
event.accepted = true event.accepted = true
} else if (event.key === Qt.Key_Escape && fileManagerPanel.showSearchBar) { } else if (event.key === Qt.Key_Escape && filePickerPanel.showSearchBar) {
// Close search bar on Escape // Close search bar on Escape
fileManagerPanel.showSearchBar = false filePickerPanel.showSearchBar = false
fileManagerPanel.searchText = "" filePickerPanel.searchText = ""
fileManagerPanel.isSearching = false filePickerPanel.isSearching = false
fileManagerPanel.filterText = "" filePickerPanel.filterText = ""
root.updateFilteredModel() root.updateFilteredModel()
event.accepted = true event.accepted = true
} }
@@ -351,26 +351,26 @@ Popup {
// View mode toggle // View mode toggle
NIconButton { NIconButton {
icon: fileManagerPanel.viewMode ? "layout-grid" : "list" icon: filePickerPanel.viewMode ? "layout-grid" : "list"
tooltipText: fileManagerPanel.viewMode ? "List View" : "Grid View" tooltipText: filePickerPanel.viewMode ? "List View" : "Grid View"
baseSize: Style.baseWidgetSize * 0.8 baseSize: Style.baseWidgetSize * 0.8
onClicked: { onClicked: {
fileManagerPanel.viewMode = !fileManagerPanel.viewMode filePickerPanel.viewMode = !filePickerPanel.viewMode
} }
} }
// Search toggle // Search toggle
NIconButton { NIconButton {
icon: fileManagerPanel.showSearchBar ? "x" : "search" icon: filePickerPanel.showSearchBar ? "x" : "search"
tooltipText: fileManagerPanel.showSearchBar ? "Close Search" : "Search" tooltipText: filePickerPanel.showSearchBar ? "Close Search" : "Search"
baseSize: Style.baseWidgetSize * 0.8 baseSize: Style.baseWidgetSize * 0.8
onClicked: { onClicked: {
fileManagerPanel.showSearchBar = !fileManagerPanel.showSearchBar filePickerPanel.showSearchBar = !filePickerPanel.showSearchBar
if (!fileManagerPanel.showSearchBar) { if (!filePickerPanel.showSearchBar) {
// Clear search when closing // Clear search when closing
fileManagerPanel.searchText = "" filePickerPanel.searchText = ""
fileManagerPanel.isSearching = false filePickerPanel.isSearching = false
fileManagerPanel.filterText = "" filePickerPanel.filterText = ""
root.updateFilteredModel() root.updateFilteredModel()
} }
} }
@@ -416,7 +416,7 @@ Popup {
radius: Style.radiusS * scaling radius: Style.radiusS * scaling
border.color: Color.mOutline border.color: Color.mOutline
border.width: Math.max(1, Style.borderS * scaling) border.width: Math.max(1, Style.borderS * scaling)
visible: fileManagerPanel.showSearchBar visible: filePickerPanel.showSearchBar
RowLayout { RowLayout {
anchors.left: parent.left anchors.left: parent.left
@@ -435,20 +435,20 @@ Popup {
id: searchInput id: searchInput
placeholderText: "Search files and folders..." placeholderText: "Search files and folders..."
Layout.fillWidth: true Layout.fillWidth: true
text: fileManagerPanel.searchText text: filePickerPanel.searchText
onTextChanged: { onTextChanged: {
fileManagerPanel.searchText = text filePickerPanel.searchText = text
fileManagerPanel.isSearching = text.length > 0 filePickerPanel.isSearching = text.length > 0
fileManagerPanel.filterText = text filePickerPanel.filterText = text
root.updateFilteredModel() root.updateFilteredModel()
} }
Keys.onEscapePressed: { Keys.onEscapePressed: {
fileManagerPanel.showSearchBar = false filePickerPanel.showSearchBar = false
fileManagerPanel.searchText = "" filePickerPanel.searchText = ""
fileManagerPanel.isSearching = false filePickerPanel.isSearching = false
fileManagerPanel.filterText = "" filePickerPanel.filterText = ""
root.updateFilteredModel() root.updateFilteredModel()
} }
} }
@@ -457,12 +457,12 @@ Popup {
icon: "x" icon: "x"
tooltipText: "Clear" tooltipText: "Clear"
baseSize: Style.baseWidgetSize * 0.6 baseSize: Style.baseWidgetSize * 0.6
visible: fileManagerPanel.searchText.length > 0 visible: filePickerPanel.searchText.length > 0
onClicked: { onClicked: {
searchInput.text = "" searchInput.text = ""
fileManagerPanel.searchText = "" filePickerPanel.searchText = ""
fileManagerPanel.isSearching = false filePickerPanel.isSearching = false
fileManagerPanel.filterText = "" filePickerPanel.filterText = ""
root.updateFilteredModel() root.updateFilteredModel()
} }
} }
@@ -490,7 +490,7 @@ Popup {
onFolderChanged: { onFolderChanged: {
root.currentPath = folder.toString().replace("file://", "") root.currentPath = folder.toString().replace("file://", "")
fileManagerPanel.currentSelection = [] filePickerPanel.currentSelection = []
} }
onStatusChanged: { onStatusChanged: {
@@ -518,7 +518,7 @@ Popup {
anchors.fill: parent anchors.fill: parent
anchors.margins: Style.marginM * scaling anchors.margins: Style.marginM * scaling
model: filteredModel model: filteredModel
visible: fileManagerPanel.viewMode visible: filePickerPanel.viewMode
clip: true clip: true
property int columns: Math.max(1, Math.floor(width / (120 * scaling))) property int columns: Math.max(1, Math.floor(width / (120 * scaling)))
@@ -584,7 +584,7 @@ Popup {
property string fileName: model.fileName property string fileName: model.fileName
property string filePath: model.filePath property string filePath: model.filePath
property bool isDirectory: model.fileIsDir property bool isDirectory: model.fileIsDir
property bool isSelected: fileManagerPanel.currentSelection.includes(filePath) property bool isSelected: filePickerPanel.currentSelection.includes(filePath)
// Selection background (covers entire item) // Selection background (covers entire item)
Rectangle { Rectangle {
@@ -604,9 +604,11 @@ Popup {
// Hover overlay // Hover overlay
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: Color.mSurface color: Qt.alpha(Color.mPrimary, 0.1)
opacity: (mouseArea.containsMouse && !isSelected) ? 0.1 : 0 opacity: (mouseArea.containsMouse && !isSelected) ? 1.0 : 0
radius: parent.radius radius: parent.radius
border.color: Qt.alpha(Color.mPrimary, 0.3)
border.width: Math.max(1, Style.borderS * scaling)
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: Style.animationFast duration: Style.animationFast
@@ -724,14 +726,14 @@ Popup {
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
if (isDirectory) { if (isDirectory) {
if (root.selectFolders && !root.selectFiles) { if (root.selectFolders && !root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
} else { } else {
folderModel.folder = "file://" + filePath folderModel.folder = "file://" + filePath
root.currentPath = filePath root.currentPath = filePath
} }
} else { } else {
if (root.selectFiles) { if (root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
} }
} }
} }
@@ -741,7 +743,7 @@ Popup {
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
if (isDirectory) { if (isDirectory) {
if (root.selectFolders && !root.selectFiles) { if (root.selectFolders && !root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
root.confirmSelection() root.confirmSelection()
} else { } else {
folderModel.folder = "file://" + filePath folderModel.folder = "file://" + filePath
@@ -749,7 +751,7 @@ Popup {
} }
} else { } else {
if (root.selectFiles) { if (root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
root.confirmSelection() root.confirmSelection()
} }
} }
@@ -765,7 +767,7 @@ Popup {
anchors.fill: parent anchors.fill: parent
anchors.margins: Style.marginS * scaling anchors.margins: Style.marginS * scaling
model: filteredModel model: filteredModel
visible: !fileManagerPanel.viewMode visible: !filePickerPanel.viewMode
clip: true clip: true
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
@@ -815,7 +817,7 @@ Popup {
width: listView.width width: listView.width
height: 40 * scaling height: 40 * scaling
color: { color: {
if (fileManagerPanel.currentSelection.includes(filePath)) { if (filePickerPanel.currentSelection.includes(filePath)) {
return Color.mSecondary return Color.mSecondary
} }
if (mouseArea.containsMouse) { if (mouseArea.containsMouse) {
@@ -844,21 +846,21 @@ Popup {
NIcon { NIcon {
icon: isDirectory ? "folder" : root.getFileIcon(fileName) icon: isDirectory ? "folder" : root.getFileIcon(fileName)
font.pointSize: Style.fontSizeL * scaling font.pointSize: Style.fontSizeL * scaling
color: isDirectory ? (fileManagerPanel.currentSelection.includes(filePath) ? Color.mOnSecondary : Color.mPrimary) : Color.mOnSurfaceVariant color: isDirectory ? (filePickerPanel.currentSelection.includes(filePath) ? Color.mOnSecondary : Color.mPrimary) : Color.mOnSurfaceVariant
} }
NText { NText {
text: fileName text: fileName
color: fileManagerPanel.currentSelection.includes(filePath) ? Color.mOnSecondary : Color.mOnSurface color: filePickerPanel.currentSelection.includes(filePath) ? Color.mOnSecondary : Color.mOnSurface
font.pointSize: Style.fontSizeM * scaling font.pointSize: Style.fontSizeM * scaling
font.weight: fileManagerPanel.currentSelection.includes(filePath) ? Style.fontWeightBold : Style.fontWeightRegular font.weight: filePickerPanel.currentSelection.includes(filePath) ? Style.fontWeightBold : Style.fontWeightRegular
Layout.fillWidth: true Layout.fillWidth: true
elide: Text.ElideRight elide: Text.ElideRight
} }
NText { NText {
text: isDirectory ? "" : root.formatFileSize(model.fileSize) text: isDirectory ? "" : root.formatFileSize(model.fileSize)
color: fileManagerPanel.currentSelection.includes(filePath) ? Color.mOnSecondary : Color.mOnSurfaceVariant color: filePickerPanel.currentSelection.includes(filePath) ? Color.mOnSecondary : Color.mOnSurfaceVariant
font.pointSize: Style.fontSizeS * scaling font.pointSize: Style.fontSizeS * scaling
visible: !isDirectory visible: !isDirectory
Layout.preferredWidth: implicitWidth Layout.preferredWidth: implicitWidth
@@ -875,14 +877,14 @@ Popup {
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
if (isDirectory) { if (isDirectory) {
if (root.selectFolders && !root.selectFiles) { if (root.selectFolders && !root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
} else { } else {
folderModel.folder = "file://" + filePath folderModel.folder = "file://" + filePath
root.currentPath = filePath root.currentPath = filePath
} }
} else { } else {
if (root.selectFiles) { if (root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
} }
} }
} }
@@ -892,7 +894,7 @@ Popup {
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
if (isDirectory) { if (isDirectory) {
if (root.selectFolders && !root.selectFiles) { if (root.selectFolders && !root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
root.confirmSelection() root.confirmSelection()
} else { } else {
folderModel.folder = "file://" + filePath folderModel.folder = "file://" + filePath
@@ -900,7 +902,7 @@ Popup {
} }
} else { } else {
if (root.selectFiles) { if (root.selectFiles) {
fileManagerPanel.currentSelection = [filePath] filePickerPanel.currentSelection = [filePath]
root.confirmSelection() root.confirmSelection()
} }
} }
@@ -919,15 +921,15 @@ Popup {
// Status text // Status text
NText { NText {
text: { text: {
if (fileManagerPanel.isSearching) { if (filePickerPanel.isSearching) {
return "Searching for: \"" + fileManagerPanel.searchText + "\" (" + filteredModel.count + " matches)" return "Searching for: \"" + filePickerPanel.searchText + "\" (" + filteredModel.count + " matches)"
} else if (fileManagerPanel.currentSelection.length > 0) { } else if (filePickerPanel.currentSelection.length > 0) {
return fileManagerPanel.currentSelection.length + " item(s) selected" return filePickerPanel.currentSelection.length + " item(s) selected"
} else { } else {
return filteredModel.count + " items" return filteredModel.count + " items"
} }
} }
color: fileManagerPanel.isSearching ? Color.mPrimary : Color.mOnSurfaceVariant color: filePickerPanel.isSearching ? Color.mPrimary : Color.mOnSurfaceVariant
font.pointSize: Style.fontSizeS * scaling font.pointSize: Style.fontSizeS * scaling
Layout.fillWidth: true Layout.fillWidth: true
} }
@@ -953,7 +955,7 @@ Popup {
} }
} }
icon: "check" icon: "check"
enabled: fileManagerPanel.currentSelection.length > 0 enabled: filePickerPanel.currentSelection.length > 0
onClicked: root.confirmSelection() onClicked: root.confirmSelection()
} }
} }
@@ -964,7 +966,7 @@ Popup {
target: root target: root
function onShouldResetSelectionChanged() { function onShouldResetSelectionChanged() {
if (root.shouldResetSelection) { if (root.shouldResetSelection) {
fileManagerPanel.currentSelection = [] filePickerPanel.currentSelection = []
root.shouldResetSelection = false root.shouldResetSelection = false
} }
} }