summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrustable-code <krauter.simon@arcor.de>2019-11-03 20:06:04 +0100
committertrustable-code <krauter.simon@arcor.de>2019-11-03 20:06:04 +0100
commitfe3db61a8c890ebbd8661ee2eaabfdd6f2121c95 (patch)
tree5aafef584a645be29592ccd54d178ed54d2df0b9
parent2ec9ad141413d79e3221161d52adb74f34f193e9 (diff)
downloadNiGui-fe3db61a8c890ebbd8661ee2eaabfdd6f2121c95.tar.gz
NiGui-fe3db61a8c890ebbd8661ee2eaabfdd6f2121c95.zip
Add SelectDirectoryDialog
Fixes #67
-rw-r--r--examples/example_12_file_dialogs.nim18
-rwxr-xr-xsrc/nigui.nim14
-rwxr-xr-xsrc/nigui/private/gtk3/platform_impl.nim11
-rwxr-xr-xsrc/nigui/private/windows/platform_impl.nim15
-rwxr-xr-xsrc/nigui/private/windows/windows.nim15
5 files changed, 67 insertions, 6 deletions
diff --git a/examples/example_12_file_dialogs.nim b/examples/example_12_file_dialogs.nim
index b1647c3..7e1e2e3 100644
--- a/examples/example_12_file_dialogs.nim
+++ b/examples/example_12_file_dialogs.nim
@@ -20,7 +20,7 @@ button1.onClick = proc(event: ClickEvent) =
var dialog = newOpenFileDialog()
dialog.title = "Test Open"
dialog.multiple = true
- dialog.directory = "/run/media/user/Data/Temp/Downloads/"
+ # dialog.directory = ""
dialog.run()
textArea.addLine($dialog.files.len & " files selected")
if dialog.files.len > 0:
@@ -32,13 +32,25 @@ buttons.add(button2)
button2.onClick = proc(event: ClickEvent) =
var dialog = SaveFileDialog()
dialog.title = "Test Save"
- dialog.directory = "/run/media/user/Data/Temp/Downloads/"
+ # dialog.directory = ""
dialog.defaultName = "default.txt"
dialog.run()
if dialog.file == "":
- textArea.addLine("No path selected")
+ textArea.addLine("No file selected")
else:
textArea.addLine(dialog.file)
+var button3 = newButton("Select Directory ...")
+buttons.add(button3)
+button3.onClick = proc(event: ClickEvent) =
+ var dialog = SelectDirectoryDialog()
+ dialog.title = "Test Select Directory"
+ # dialog.startDirectory = ""
+ dialog.run()
+ if dialog.selectedDirectory == "":
+ textArea.addLine("No directory selected")
+ else:
+ textArea.addLine(dialog.selectedDirectory)
+
window.show()
app.run()
diff --git a/src/nigui.nim b/src/nigui.nim
index 2787126..814e860 100755
--- a/src/nigui.nim
+++ b/src/nigui.nim
@@ -489,6 +489,15 @@ proc newSaveFileDialog*(): SaveFileDialog
method run*(dialog: SaveFileDialog) {.base.}
+type SelectDirectoryDialog* = ref object
+ title*: string
+ startDirectory*: string
+ selectedDirectory*: string
+
+proc newSelectDirectoryDialog*(): SelectDirectoryDialog
+
+method run*(dialog: SelectDirectoryDialog) {.base.}
+
# ----------------------------------------------------------------------------------------
# Timers
@@ -1167,6 +1176,11 @@ proc newSaveFileDialog(): SaveFileDialog =
result.title = "Save File"
result.directory = getCurrentDir()
+proc newSelectDirectoryDialog(): SelectDirectoryDialog =
+ result = new SelectDirectoryDialog
+ result.title = "Select a Folder"
+ result.startDirectory = getCurrentDir()
+
proc isDown(key: Key): bool = fDownKeys.contains(key)
proc downKeys(): seq[Key] = fDownKeys
diff --git a/src/nigui/private/gtk3/platform_impl.nim b/src/nigui/private/gtk3/platform_impl.nim
index bf4b1ab..c5a7fdb 100755
--- a/src/nigui/private/gtk3/platform_impl.nim
+++ b/src/nigui/private/gtk3/platform_impl.nim
@@ -402,7 +402,6 @@ proc alert(window: Window, message: string, title = "Message") =
method run*(dialog: OpenFileDialog) =
dialog.files = @[]
var chooser = gtk_file_chooser_dialog_new(dialog.title, nil, GTK_FILE_CHOOSER_ACTION_OPEN, "Cancel", GTK_RESPONSE_CANCEL, "Open", GTK_RESPONSE_ACCEPT, nil)
- # Issue: When a title is passed, the dialog is shown without a title
discard gtk_file_chooser_set_current_folder(chooser, dialog.directory)
gtk_file_chooser_set_select_multiple(chooser, dialog.multiple)
let res = gtk_dialog_run(chooser)
@@ -415,7 +414,6 @@ method run*(dialog: OpenFileDialog) =
method run(dialog: SaveFileDialog) =
var chooser = gtk_file_chooser_dialog_new(dialog.title, nil, GTK_FILE_CHOOSER_ACTION_SAVE, "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, nil)
- # Issue: When a title is passed, the dialog is shown without a title
let res = gtk_dialog_run(chooser)
discard gtk_file_chooser_set_current_folder(chooser, dialog.directory)
if dialog.defaultName.len > 0:
@@ -426,6 +424,15 @@ method run(dialog: SaveFileDialog) =
dialog.file = ""
gtk_widget_destroy(chooser)
+method run*(dialog: SelectDirectoryDialog) =
+ dialog.selectedDirectory = ""
+ var chooser = gtk_file_chooser_dialog_new(dialog.title, nil, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, "Cancel", GTK_RESPONSE_CANCEL, "Select", GTK_RESPONSE_ACCEPT, nil)
+ discard gtk_file_chooser_set_current_folder(chooser, dialog.startDirectory)
+ let res = gtk_dialog_run(chooser)
+ if res == GTK_RESPONSE_ACCEPT:
+ dialog.selectedDirectory = $gtk_file_chooser_get_filename(chooser)
+ gtk_widget_destroy(chooser)
+
# ----------------------------------------------------------------------------------------
# Timers
diff --git a/src/nigui/private/windows/platform_impl.nim b/src/nigui/private/windows/platform_impl.nim
index f110722..05b0f8b 100755
--- a/src/nigui/private/windows/platform_impl.nim
+++ b/src/nigui/private/windows/platform_impl.nim
@@ -499,6 +499,7 @@ method run*(dialog: OpenFileDialog) =
method run(dialog: SaveFileDialog) =
const maxCharacters = 500
+ dialog.file = ""
var ofn: OpenFileName
ofn.lStructSize = OpenFileName.sizeOf.int32
ofn.lpstrTitle = dialog.title.pUtf8ToUtf16()
@@ -517,11 +518,23 @@ method run(dialog: SaveFileDialog) =
if ret:
dialog.file = pUtf16ToUtf8(s, true)
else:
- dialog.file = ""
let e = CommDlgExtendedError()
if e != 0:
raiseError("CommDlg Error Code: " & $e)
+method run*(dialog: SelectDirectoryDialog) =
+ ## Notes: `dialog.startDirectory` is not supported.
+ const maxCharacters = 5000
+ dialog.selectedDirectory = ""
+ var bi: BrowseInfo
+ bi.lpszTitle = dialog.title.pUtf8ToUtf16()
+ bi.ulFlags = BIF_RETURNONLYFSDIRS or BIF_NEWDIALOGSTYLE
+ let pidl = SHBrowseForFolderW(bi)
+ if pidl != nil:
+ var s = newString(maxCharacters * 2)
+ SHGetPathFromIDListW(pidl, s)
+ dialog.selectedDirectory = pUtf16ToUtf8(s, true)
+
# ----------------------------------------------------------------------------------------
# Timers
diff --git a/src/nigui/private/windows/windows.nim b/src/nigui/private/windows/windows.nim
index 0cd0add..a9b275d 100755
--- a/src/nigui/private/windows/windows.nim
+++ b/src/nigui/private/windows/windows.nim
@@ -34,6 +34,8 @@ const
ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID* = 4
ACTCTX_FLAG_RESOURCE_NAME_VALID* = 8
ACTCTX_FLAG_SET_PROCESS_DEFAULT* = 16
+ BIF_RETURNONLYFSDIRS* = 0x00000001
+ BIF_NEWDIALOGSTYLE* = 0x00000040
BN_CLICKED* = 0
BM_SETSTYLE* = 244
BM_SETIMAGE* = 247
@@ -348,6 +350,17 @@ type
Scan0*: ptr UncheckedArray[byte]
Reserved: pointer
+ BrowseInfo* = object
+ hwndOwner*: pointer
+ pidlRoot*: pointer
+ pszDisplayName*: cstring
+ lpszTitle*: cstring
+ ulFlags*: uint
+ lpfn*: pointer
+ lParam*: pointer
+ iImage*: int32
+
+
# ----------------------------------------------------------------------------------------
# Replacement for Windows Macros
@@ -529,6 +542,8 @@ proc GdipBitmapUnlockBits*(bitmap: pointer, lockedBitmapData: var BitmapData): i
proc DragAcceptFiles*(hWnd: pointer, fAccept: bool) {.importc: "DragAcceptFiles", libShell32.}
proc DragQueryFileW*(hDrop: pointer, iFile: uint32, lpszFile: cstring, cch: int32): int32 {.importc: "DragQueryFileW", libShell32.}
proc DragFinish*(hDrop: pointer) {.importc: "DragFinish", libShell32.}
+proc SHBrowseForFolderW*(lpbi: var BrowseInfo): pointer {.importc: "SHBrowseForFolderW", libShell32.}
+proc SHGetPathFromIDListW*(pidl: pointer, pszPath: cstring) {.importc: "SHGetPathFromIDListW", libShell32.}
# ----------------------------------------------------------------------------------------