Add native macOS folder picker for staging directory
Uses AWT FileDialog with apple.awt.fileDialogForDirectories=true to open the native macOS folder chooser. Falls back gracefully (dialog cancelled) with no change to the text field.
This commit is contained in:
@@ -3,12 +3,16 @@ package com.bolenpad.photophetch.ui
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.FolderOpen
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import java.awt.FileDialog
|
||||
import java.awt.Frame
|
||||
import java.io.File
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(state: AppState) {
|
||||
@@ -33,14 +37,30 @@ fun SettingsScreen(state: AppState) {
|
||||
|
||||
// Staging directory
|
||||
Text("Staging Directory", style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.SemiBold)
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = stagingRoot,
|
||||
onValueChange = { stagingRoot = it },
|
||||
label = { Text("Path to _staging/ directory") },
|
||||
placeholder = { Text("/Volumes/delphi/_staging") },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true,
|
||||
)
|
||||
OutlinedIconButton(
|
||||
onClick = {
|
||||
val chosen = pickFolder(
|
||||
title = "Select _staging directory",
|
||||
initialDir = stagingRoot.ifBlank { "/Volumes" },
|
||||
)
|
||||
if (chosen != null) stagingRoot = chosen
|
||||
},
|
||||
) {
|
||||
Icon(Icons.Default.FolderOpen, contentDescription = "Browse…")
|
||||
}
|
||||
}
|
||||
Text(
|
||||
"This should be the _staging directory on your NAS (must be mounted).",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
@@ -78,7 +98,6 @@ fun SettingsScreen(state: AppState) {
|
||||
Button(
|
||||
onClick = {
|
||||
state.updateStagingRoot(stagingRoot)
|
||||
// Also save template update
|
||||
state.saveConfig()
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().height(52.dp),
|
||||
@@ -87,3 +106,24 @@ fun SettingsScreen(state: AppState) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the native macOS folder picker (System.setProperty trick to make
|
||||
* AWT FileDialog show directories instead of files).
|
||||
* Returns the chosen absolute path, or null if cancelled.
|
||||
*/
|
||||
private fun pickFolder(title: String, initialDir: String): String? {
|
||||
// On macOS, this system property switches FileDialog to directory-selection mode
|
||||
System.setProperty("apple.awt.fileDialogForDirectories", "true")
|
||||
return try {
|
||||
val dialog = FileDialog(null as Frame?, title, FileDialog.LOAD).apply {
|
||||
directory = initialDir
|
||||
isVisible = true
|
||||
}
|
||||
val dir = dialog.directory
|
||||
val file = dialog.file
|
||||
if (file != null) File(dir, file).absolutePath else null
|
||||
} finally {
|
||||
System.setProperty("apple.awt.fileDialogForDirectories", "false")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user