mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
[v3] send dialog results over channels
This commit is contained in:
parent
7c98ee329a
commit
757a4383e6
5 changed files with 88 additions and 58 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package application
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
|
@ -159,7 +160,7 @@ func (d *MessageDialog) SetMessage(message string) *MessageDialog {
|
|||
}
|
||||
|
||||
type openFileDialogImpl interface {
|
||||
show() ([]string, error)
|
||||
show() (chan string, error)
|
||||
}
|
||||
|
||||
type FileFilter struct {
|
||||
|
|
@ -265,10 +266,11 @@ func (d *OpenFileDialogStruct) PromptForSingleSelection() (string, error) {
|
|||
if d.impl == nil {
|
||||
d.impl = newOpenFileDialogImpl(d)
|
||||
}
|
||||
selection, err := InvokeSyncWithResultAndError(d.impl.show)
|
||||
|
||||
var result string
|
||||
if len(selection) > 0 {
|
||||
result = selection[0]
|
||||
selections, err := InvokeSyncWithResultAndError(d.impl.show)
|
||||
if err == nil {
|
||||
result = <-selections
|
||||
}
|
||||
|
||||
return result, err
|
||||
|
|
@ -289,7 +291,17 @@ func (d *OpenFileDialogStruct) PromptForMultipleSelection() ([]string, error) {
|
|||
if d.impl == nil {
|
||||
d.impl = newOpenFileDialogImpl(d)
|
||||
}
|
||||
return InvokeSyncWithResultAndError(d.impl.show)
|
||||
|
||||
selections, err := InvokeSyncWithResultAndError(d.impl.show)
|
||||
|
||||
var result []string
|
||||
fmt.Println("Waiting for results:")
|
||||
for filename := range selections {
|
||||
fmt.Println(filename)
|
||||
result = append(result, filename)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (d *OpenFileDialogStruct) SetMessage(message string) *OpenFileDialogStruct {
|
||||
|
|
@ -385,7 +397,7 @@ type SaveFileDialogStruct struct {
|
|||
}
|
||||
|
||||
type saveFileDialogImpl interface {
|
||||
show() (string, error)
|
||||
show() (chan string, error)
|
||||
}
|
||||
|
||||
func (d *SaveFileDialogStruct) SetOptions(options *SaveFileDialogOptions) {
|
||||
|
|
@ -448,7 +460,13 @@ func (d *SaveFileDialogStruct) PromptForSingleSelection() (string, error) {
|
|||
if d.impl == nil {
|
||||
d.impl = newSaveFileDialogImpl(d)
|
||||
}
|
||||
return InvokeSyncWithResultAndError(d.impl.show)
|
||||
|
||||
var result string
|
||||
selections, err := InvokeSyncWithResultAndError(d.impl.show)
|
||||
if err == nil {
|
||||
result = <-selections
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (d *SaveFileDialogStruct) SetButtonText(text string) *SaveFileDialogStruct {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ extern void saveFileDialogCallback(uint id, char* path);
|
|||
static void showAboutBox(char* title, char *message, void *icon, int length) {
|
||||
|
||||
// run on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
if (title != NULL) {
|
||||
[alert setMessageText:[NSString stringWithUTF8String:title]];
|
||||
|
|
@ -34,7 +34,7 @@ static void showAboutBox(char* title, char *message, void *icon, int length) {
|
|||
}
|
||||
[alert setAlertStyle:NSAlertStyleInformational];
|
||||
[alert runModal];
|
||||
});
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ static void showOpenFileDialog(unsigned int dialogID,
|
|||
void *window) {
|
||||
|
||||
// run on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ static void showOpenFileDialog(unsigned int dialogID,
|
|||
processOpenFileDialogResults(panel, result, dialogID);
|
||||
}];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static void showSaveFileDialog(unsigned int dialogID,
|
||||
|
|
@ -246,7 +246,7 @@ static void showSaveFileDialog(unsigned int dialogID,
|
|||
void *window) {
|
||||
|
||||
// run on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
|
||||
if (message != NULL) {
|
||||
|
|
@ -280,8 +280,8 @@ static void showSaveFileDialog(unsigned int dialogID,
|
|||
[panel beginSheetModalForWindow:(__bridge NSWindow *)window completionHandler:^(NSInteger result) {
|
||||
const char *path = NULL;
|
||||
if (result == NSModalResponseOK) {
|
||||
NSURL *url = [panel URL];
|
||||
const char *path = [[url path] UTF8String];
|
||||
NSURL *url = [panel URL];
|
||||
path = [[url path] UTF8String];
|
||||
}
|
||||
saveFileDialogCallback(dialogID, (char *)path);
|
||||
}];
|
||||
|
|
@ -290,12 +290,12 @@ static void showSaveFileDialog(unsigned int dialogID,
|
|||
const char *path = NULL;
|
||||
if (result == NSModalResponseOK) {
|
||||
NSURL *url = [panel URL];
|
||||
const char *path = [[url path] UTF8String];
|
||||
path = [[url path] UTF8String];
|
||||
}
|
||||
saveFileDialogCallback(dialogID, (char *)path);
|
||||
}];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
@ -321,7 +321,9 @@ func (m *macosApp) showAboutDialog(title string, message string, icon []byte) {
|
|||
if icon != nil {
|
||||
iconData = unsafe.Pointer(&icon[0])
|
||||
}
|
||||
C.showAboutBox(C.CString(title), C.CString(message), iconData, C.int(len(icon)))
|
||||
InvokeAsync(func() {
|
||||
C.showAboutBox(C.CString(title), C.CString(message), iconData, C.int(len(icon)))
|
||||
})
|
||||
}
|
||||
|
||||
type macosDialog struct {
|
||||
|
|
@ -331,7 +333,7 @@ type macosDialog struct {
|
|||
}
|
||||
|
||||
func (m *macosDialog) show() {
|
||||
globalApplication.dispatchOnMainThread(func() {
|
||||
InvokeAsync(func() {
|
||||
|
||||
// Mac can only have 4 Buttons on a dialog
|
||||
if len(m.dialog.Buttons) > 4 {
|
||||
|
|
@ -419,7 +421,7 @@ func toCString(s string) *C.char {
|
|||
return C.CString(s)
|
||||
}
|
||||
|
||||
func (m *macosOpenFileDialog) show() ([]string, error) {
|
||||
func (m *macosOpenFileDialog) show() (chan string, error) {
|
||||
openFileResponses[m.dialog.id] = make(chan string)
|
||||
nsWindow := unsafe.Pointer(nil)
|
||||
if m.dialog.window != nil {
|
||||
|
|
@ -445,7 +447,6 @@ func (m *macosOpenFileDialog) show() ([]string, error) {
|
|||
}
|
||||
filterPatterns = strings.Join(allPatterns, ";")
|
||||
}
|
||||
|
||||
C.showOpenFileDialog(C.uint(m.dialog.id),
|
||||
C.bool(m.dialog.canChooseFiles),
|
||||
C.bool(m.dialog.canChooseDirectories),
|
||||
|
|
@ -462,11 +463,8 @@ func (m *macosOpenFileDialog) show() ([]string, error) {
|
|||
toCString(m.dialog.directory),
|
||||
toCString(m.dialog.buttonText),
|
||||
nsWindow)
|
||||
var result []string
|
||||
for filename := range openFileResponses[m.dialog.id] {
|
||||
result = append(result, filename)
|
||||
}
|
||||
return result, nil
|
||||
|
||||
return openFileResponses[m.dialog.id], nil
|
||||
}
|
||||
|
||||
//export openFileDialogCallback
|
||||
|
|
@ -504,7 +502,7 @@ func newSaveFileDialogImpl(d *SaveFileDialogStruct) *macosSaveFileDialog {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *macosSaveFileDialog) show() (string, error) {
|
||||
func (m *macosSaveFileDialog) show() (chan string, error) {
|
||||
saveFileResponses[m.dialog.id] = make(chan string)
|
||||
nsWindow := unsafe.Pointer(nil)
|
||||
if m.dialog.window != nil {
|
||||
|
|
@ -524,7 +522,7 @@ func (m *macosSaveFileDialog) show() (string, error) {
|
|||
toCString(m.dialog.buttonText),
|
||||
toCString(m.dialog.filename),
|
||||
nsWindow)
|
||||
return <-saveFileResponses[m.dialog.id], nil
|
||||
return saveFileResponses[m.dialog.id], nil
|
||||
}
|
||||
|
||||
//export saveFileDialogCallback
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func newOpenFileDialogImpl(d *OpenFileDialogStruct) *linuxOpenFileDialog {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *linuxOpenFileDialog) show() ([]string, error) {
|
||||
func (m *linuxOpenFileDialog) show() (chan string, error) {
|
||||
return runOpenFileDialog(m.dialog)
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +67,6 @@ func newSaveFileDialogImpl(d *SaveFileDialogStruct) *linuxSaveFileDialog {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *linuxSaveFileDialog) show() (string, error) {
|
||||
func (m *linuxSaveFileDialog) show() (chan string, error) {
|
||||
return runSaveFileDialog(m.dialog)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ func getDefaultFolder(folder string) (string, error) {
|
|||
return filepath.Abs(folder)
|
||||
}
|
||||
|
||||
func (m *windowOpenFileDialog) show() ([]string, error) {
|
||||
func (m *windowOpenFileDialog) show() (chan string, error) {
|
||||
|
||||
defaultFolder, err := getDefaultFolder(m.dialog.directory)
|
||||
if err != nil {
|
||||
|
|
@ -133,7 +133,14 @@ func (m *windowOpenFileDialog) show() ([]string, error) {
|
|||
result = []string{temp.(string)}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
files := make(chan string)
|
||||
go func() {
|
||||
for _, file := range result {
|
||||
files <- file
|
||||
}
|
||||
close(files)
|
||||
}()
|
||||
return files, nil
|
||||
}
|
||||
|
||||
type windowSaveFileDialog struct {
|
||||
|
|
@ -146,10 +153,12 @@ func newSaveFileDialogImpl(d *SaveFileDialogStruct) *windowSaveFileDialog {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *windowSaveFileDialog) show() (string, error) {
|
||||
func (m *windowSaveFileDialog) show() (chan string, error) {
|
||||
files := make(chan string)
|
||||
defaultFolder, err := getDefaultFolder(m.dialog.directory)
|
||||
if err != nil {
|
||||
return "", err
|
||||
close(files)
|
||||
return files, err
|
||||
}
|
||||
|
||||
config := cfd.DialogConfig{
|
||||
|
|
@ -164,7 +173,11 @@ func (m *windowSaveFileDialog) show() (string, error) {
|
|||
func() (cfd.Dialog, error) {
|
||||
return cfd.NewSaveFileDialog(config)
|
||||
}, false)
|
||||
return result.(string), nil
|
||||
go func() {
|
||||
files <- result.(string)
|
||||
close(files)
|
||||
}()
|
||||
return files, err
|
||||
}
|
||||
|
||||
func calculateMessageDialogFlags(options MessageDialogOptions) uint32 {
|
||||
|
|
|
|||
|
|
@ -973,7 +973,7 @@ func messageDialogCB(button C.int) {
|
|||
|
||||
}
|
||||
|
||||
func runChooserDialog(window pointer, allowMultiple, createFolders, showHidden bool, currentFolder, title string, action int, acceptLabel string, filters []FileFilter) ([]string, error) {
|
||||
func runChooserDialog(window pointer, allowMultiple, createFolders, showHidden bool, currentFolder, title string, action int, acceptLabel string, filters []FileFilter) (chan string, error) {
|
||||
titleStr := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(titleStr))
|
||||
cancelStr := C.CString("_Cancel")
|
||||
|
|
@ -1036,27 +1036,32 @@ func runChooserDialog(window pointer, allowMultiple, createFolders, showHidden b
|
|||
return string(bytes)
|
||||
}
|
||||
|
||||
response := C.gtk_dialog_run((*C.GtkDialog)(fc))
|
||||
selections := []string{}
|
||||
if response == C.GTK_RESPONSE_ACCEPT {
|
||||
filenames := C.gtk_file_chooser_get_filenames((*C.GtkFileChooser)(fc))
|
||||
iter := filenames
|
||||
count := 0
|
||||
for {
|
||||
selections = append(selections, buildStringAndFree(C.gpointer(iter.data)))
|
||||
iter = iter.next
|
||||
if iter == nil || count == 1024 {
|
||||
break
|
||||
selections := make(chan string)
|
||||
// run this on the gtk thread
|
||||
InvokeAsync(func() {
|
||||
go func() {
|
||||
response := C.gtk_dialog_run((*C.GtkDialog)(fc))
|
||||
if response == C.GTK_RESPONSE_ACCEPT {
|
||||
filenames := C.gtk_file_chooser_get_filenames((*C.GtkFileChooser)(fc))
|
||||
iter := filenames
|
||||
count := 0
|
||||
for {
|
||||
selections <- buildStringAndFree(C.gpointer(iter.data))
|
||||
iter = iter.next
|
||||
if iter == nil || count == 1024 {
|
||||
break
|
||||
}
|
||||
count++
|
||||
}
|
||||
close(selections)
|
||||
C.gtk_widget_destroy((*C.GtkWidget)(unsafe.Pointer(fc)))
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
defer C.gtk_widget_destroy((*C.GtkWidget)(unsafe.Pointer(fc)))
|
||||
}()
|
||||
})
|
||||
return selections, nil
|
||||
}
|
||||
|
||||
func runOpenFileDialog(dialog *OpenFileDialogStruct) ([]string, error) {
|
||||
func runOpenFileDialog(dialog *OpenFileDialogStruct) (chan string, error) {
|
||||
const GtkFileChooserActionOpen = C.GTK_FILE_CHOOSER_ACTION_OPEN
|
||||
|
||||
window := nilPointer
|
||||
|
|
@ -1145,7 +1150,7 @@ func runQuestionDialog(parent pointer, options *MessageDialog) int {
|
|||
return int(C.gtk_dialog_run((*C.GtkDialog)(unsafe.Pointer(dialog))))
|
||||
}
|
||||
|
||||
func runSaveFileDialog(dialog *SaveFileDialogStruct) (string, error) {
|
||||
func runSaveFileDialog(dialog *SaveFileDialogStruct) (chan string, error) {
|
||||
window := nilPointer
|
||||
buttonText := dialog.buttonText
|
||||
if buttonText == "" {
|
||||
|
|
@ -1162,11 +1167,7 @@ func runSaveFileDialog(dialog *SaveFileDialogStruct) (string, error) {
|
|||
buttonText,
|
||||
dialog.filters)
|
||||
|
||||
if err != nil || len(results) == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return results[0], nil
|
||||
return results, err
|
||||
}
|
||||
|
||||
// systray
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue