mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 19:50:15 +08:00
[mac] dialog support
This commit is contained in:
parent
35ebbdfa12
commit
bea0c1446a
@ -115,8 +115,6 @@ github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQ
|
|||||||
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
|
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
|
||||||
github.com/leaanthony/go-common-file-dialog v1.0.3 h1:O0uGjKnWtdEADGrkg+TyAAbZylykMwwx/MNEXn9fp+Y=
|
github.com/leaanthony/go-common-file-dialog v1.0.3 h1:O0uGjKnWtdEADGrkg+TyAAbZylykMwwx/MNEXn9fp+Y=
|
||||||
github.com/leaanthony/go-common-file-dialog v1.0.3/go.mod h1:TGhEc9eSJgRsupZ+iH1ZgAOnEo9zp05cRH2j08RPrF0=
|
github.com/leaanthony/go-common-file-dialog v1.0.3/go.mod h1:TGhEc9eSJgRsupZ+iH1ZgAOnEo9zp05cRH2j08RPrF0=
|
||||||
github.com/leaanthony/go-webview2 v0.0.0-20210928094513-a94a08b538bd h1:6m4zZ/esiByaDbzgdvDxjsOaIDgtuG1q2cyhjAi6uAg=
|
|
||||||
github.com/leaanthony/go-webview2 v0.0.0-20210928094513-a94a08b538bd/go.mod h1:lS5ds4bruPk9d7lzdF/OH31Z0YCerI6MmHNFGsWoUnM=
|
|
||||||
github.com/leaanthony/go-webview2 v0.0.0-20211007095229-b1759d2e4ec7 h1:qw9f/UqPp2GQ318n8G0Ikawe8GRkdPpUNJMuYeeafGA=
|
github.com/leaanthony/go-webview2 v0.0.0-20211007095229-b1759d2e4ec7 h1:qw9f/UqPp2GQ318n8G0Ikawe8GRkdPpUNJMuYeeafGA=
|
||||||
github.com/leaanthony/go-webview2 v0.0.0-20211007095229-b1759d2e4ec7/go.mod h1:lS5ds4bruPk9d7lzdF/OH31Z0YCerI6MmHNFGsWoUnM=
|
github.com/leaanthony/go-webview2 v0.0.0-20211007095229-b1759d2e4ec7/go.mod h1:lS5ds4bruPk9d7lzdF/OH31Z0YCerI6MmHNFGsWoUnM=
|
||||||
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
|
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
|
||||||
|
@ -38,4 +38,7 @@ const char* GetPos(void *ctx);
|
|||||||
|
|
||||||
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, const char *data, int datalength);
|
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, const char *data, int datalength);
|
||||||
|
|
||||||
|
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton);
|
||||||
|
void OpenFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int allowDirectories, int allowFiles, int canCreateDirectories, int treatPackagesAsDirectories, int resolveAliases, int showHiddenFiles, int allowMultipleSelection, const char* filters);
|
||||||
|
void SaveFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int canCreateDirectories, int treatPackagesAsDirectories, int showHiddenFiles, const char* filters);
|
||||||
#endif /* Application_h */
|
#endif /* Application_h */
|
||||||
|
@ -173,6 +173,29 @@ void Show(void *inctx) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton) {
|
||||||
|
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||||
|
ON_MAIN_THREAD(
|
||||||
|
[ctx MessageDialog:dialogType :title :message :button1 :button2 :button3 :button4 :defaultButton :cancelButton];
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int allowDirectories, int allowFiles, int canCreateDirectories, int treatPackagesAsDirectories, int resolveAliases, int showHiddenFiles, int allowMultipleSelection, const char* filters) {
|
||||||
|
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||||
|
ON_MAIN_THREAD(
|
||||||
|
[ctx OpenFileDialog:title :defaultFilename :defaultDirectory :allowDirectories :allowFiles :canCreateDirectories :treatPackagesAsDirectories :resolveAliases :showHiddenFiles :allowMultipleSelection :filters];
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int canCreateDirectories, int treatPackagesAsDirectories, int showHiddenFiles, const char* filters) {
|
||||||
|
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||||
|
ON_MAIN_THREAD(
|
||||||
|
[ctx SaveFileDialog:title :defaultFilename :defaultDirectory :canCreateDirectories :treatPackagesAsDirectories :showHiddenFiles :filters];
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Run(void *inctx) {
|
void Run(void *inctx) {
|
||||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||||
|
18
v2/internal/frontend/desktop/darwin/WailsAlert.h
Normal file
18
v2/internal/frontend/desktop/darwin/WailsAlert.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// WailsAlert.h
|
||||||
|
// test
|
||||||
|
//
|
||||||
|
// Created by Lea Anthony on 20/10/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef WailsAlert_h
|
||||||
|
#define WailsAlert_h
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface WailsAlert : NSAlert
|
||||||
|
- (void)addButton:(const char*)text :(const char*)defaultButton :(const char*)cancelButton;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WailsAlert_h */
|
30
v2/internal/frontend/desktop/darwin/WailsAlert.m
Normal file
30
v2/internal/frontend/desktop/darwin/WailsAlert.m
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// WailsAlert.m
|
||||||
|
// test
|
||||||
|
//
|
||||||
|
// Created by Lea Anthony on 20/10/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "WailsAlert.h"
|
||||||
|
|
||||||
|
@implementation WailsAlert
|
||||||
|
|
||||||
|
- (void)addButton:(const char*)text :(const char*)defaultButton :(const char*)cancelButton {
|
||||||
|
if( text == nil ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NSButton *button = [self addButtonWithTitle:[NSString stringWithUTF8String:text]];
|
||||||
|
if( defaultButton != nil && strcmp(text, defaultButton) == 0) {
|
||||||
|
[button setKeyEquivalent:@"\r"];
|
||||||
|
} else if( cancelButton != nil && strcmp(text, cancelButton) == 0) {
|
||||||
|
[button setKeyEquivalent:@"\033"];
|
||||||
|
} else {
|
||||||
|
[button setKeyEquivalent:@""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
@ -59,6 +59,9 @@
|
|||||||
- (void) Hide;
|
- (void) Hide;
|
||||||
- (void) Show;
|
- (void) Show;
|
||||||
|
|
||||||
|
-(void) MessageDialog :(const char*)dialogType :(const char*)title :(const char*)message :(const char*)button1 :(const char*)button2 :(const char*)button3 :(const char*)button4 :(const char*)defaultButton :(const char*)cancelButton;
|
||||||
|
-(void) OpenFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(const char*)filters;
|
||||||
|
-(void) SaveFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(const char*)filters;
|
||||||
|
|
||||||
- (void) loadRequest:(NSString*)url;
|
- (void) loadRequest:(NSString*)url;
|
||||||
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData*)data;
|
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData*)data;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <WebKit/WebKit.h>
|
#import <WebKit/WebKit.h>
|
||||||
#import "WailsContext.h"
|
#import "WailsContext.h"
|
||||||
|
#import "WailsAlert.h"
|
||||||
#import "WindowDelegate.h"
|
#import "WindowDelegate.h"
|
||||||
#import "message.h"
|
#import "message.h"
|
||||||
|
|
||||||
@ -368,5 +369,159 @@
|
|||||||
processMessage(_m);
|
processMessage(_m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***** Dialogs ******/
|
||||||
|
-(void) MessageDialog :(const char*)dialogType :(const char*)title :(const char*)message :(const char*)button1 :(const char*)button2 :(const char*)button3 :(const char*)button4 :(const char*)defaultButton :(const char*)cancelButton {
|
||||||
|
|
||||||
|
WailsAlert *alert = [WailsAlert new];
|
||||||
|
|
||||||
|
int style = NSAlertStyleInformational;
|
||||||
|
if (dialogType != nil ) {
|
||||||
|
if( strcmp(dialogType, "warning") == 0 ) {
|
||||||
|
style = NSAlertStyleWarning;
|
||||||
|
}
|
||||||
|
if( strcmp(dialogType, "error") == 0) {
|
||||||
|
style = NSAlertStyleCritical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[alert setAlertStyle:style];
|
||||||
|
if( strlen(title) > 0 ) {
|
||||||
|
[alert setMessageText:[NSString stringWithUTF8String:title]];
|
||||||
|
}
|
||||||
|
if( strlen(message) > 0 ) {
|
||||||
|
[alert setInformativeText:[NSString stringWithUTF8String:message]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[alert addButton:button1 :defaultButton :cancelButton];
|
||||||
|
[alert addButton:button2 :defaultButton :cancelButton];
|
||||||
|
[alert addButton:button3 :defaultButton :cancelButton];
|
||||||
|
[alert addButton:button4 :defaultButton :cancelButton];
|
||||||
|
|
||||||
|
long response = [alert runModal];
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if( response == NSAlertFirstButtonReturn ) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else if( response == NSAlertSecondButtonReturn ) {
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else if( response == NSAlertThirdButtonReturn ) {
|
||||||
|
result = 2;
|
||||||
|
} else {
|
||||||
|
result = 3;
|
||||||
|
}
|
||||||
|
processMessageDialogResponse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) OpenFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(const char*)filters {
|
||||||
|
|
||||||
|
|
||||||
|
// Create the dialog
|
||||||
|
NSOpenPanel *dialog = [NSOpenPanel openPanel];
|
||||||
|
|
||||||
|
// Valid but appears to do nothing.... :/
|
||||||
|
if( strlen(title) > 0 ) {
|
||||||
|
[dialog setTitle:[NSString stringWithUTF8String:title]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters - semicolon delimited list of file extensions
|
||||||
|
if( allowFiles ) {
|
||||||
|
if( filters != nil && strlen(filters) > 0) {
|
||||||
|
NSString *filterString = [[NSString stringWithUTF8String:filters] stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||||
|
filterString = [filterString stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||||
|
NSArray *filterList = [filterString componentsSeparatedByString:@";"];
|
||||||
|
[dialog setAllowedFileTypes:filterList];
|
||||||
|
} else {
|
||||||
|
[dialog setAllowsOtherFileTypes:true];
|
||||||
|
}
|
||||||
|
// Default Filename
|
||||||
|
if( defaultFilename != NULL && strlen(defaultFilename) > 0 ) {
|
||||||
|
[dialog setNameFieldStringValue:[NSString stringWithUTF8String:defaultFilename]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[dialog setAllowsMultipleSelection: allowMultipleSelection];
|
||||||
|
[dialog setShowsHiddenFiles: showHiddenFiles];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Directory
|
||||||
|
if( defaultDirectory != NULL && strlen(defaultDirectory) > 0 ) {
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:defaultDirectory]];
|
||||||
|
[dialog setDirectoryURL:url];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Setup Options
|
||||||
|
[dialog setCanChooseFiles: allowFiles];
|
||||||
|
[dialog setCanChooseDirectories: allowDirectories];
|
||||||
|
[dialog setCanCreateDirectories: canCreateDirectories];
|
||||||
|
[dialog setResolvesAliases: resolveAliases];
|
||||||
|
[dialog setTreatsFilePackagesAsDirectories: treatPackagesAsDirectories];
|
||||||
|
|
||||||
|
// Setup callback handler
|
||||||
|
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
|
||||||
|
NSMutableArray *arr = [NSMutableArray new];
|
||||||
|
for (NSURL *url in [dialog URLs]) {
|
||||||
|
[arr addObject:[url path]];
|
||||||
|
}
|
||||||
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:0 error:nil];
|
||||||
|
NSString *nsjson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||||
|
processOpenFileDialogResponse([nsjson UTF8String]);
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
[dialog runModal];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(void) SaveFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(const char*)filters; {
|
||||||
|
|
||||||
|
|
||||||
|
// Create the dialog
|
||||||
|
NSSavePanel *dialog = [NSOpenPanel savePanel];
|
||||||
|
|
||||||
|
// Valid but appears to do nothing.... :/
|
||||||
|
if( strlen(title) > 0 ) {
|
||||||
|
[dialog setTitle:[NSString stringWithUTF8String:title]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters - semicolon delimited list of file extensions
|
||||||
|
if( filters != nil && strlen(filters) > 0) {
|
||||||
|
NSString *filterString = [[NSString stringWithUTF8String:filters] stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||||
|
filterString = [filterString stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||||
|
NSArray *filterList = [filterString componentsSeparatedByString:@";"];
|
||||||
|
[dialog setAllowedFileTypes:filterList];
|
||||||
|
} else {
|
||||||
|
[dialog setAllowsOtherFileTypes:true];
|
||||||
|
}
|
||||||
|
// Default Filename
|
||||||
|
if( defaultFilename != NULL && strlen(defaultFilename) > 0 ) {
|
||||||
|
[dialog setNameFieldStringValue:[NSString stringWithUTF8String:defaultFilename]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Directory
|
||||||
|
if( defaultDirectory != NULL && strlen(defaultDirectory) > 0 ) {
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:defaultDirectory]];
|
||||||
|
[dialog setDirectoryURL:url];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Options
|
||||||
|
[dialog setCanCreateDirectories: canCreateDirectories];
|
||||||
|
[dialog setTreatsFilePackagesAsDirectories: treatPackagesAsDirectories];
|
||||||
|
[dialog setShowsHiddenFiles: showHiddenFiles];
|
||||||
|
|
||||||
|
// Setup callback handler
|
||||||
|
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
|
||||||
|
NSURL *url = [dialog URL];
|
||||||
|
processSaveFileDialogResponse([url.path UTF8String]);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[dialog runModal];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
32
v2/internal/frontend/desktop/darwin/calloc.go
Normal file
32
v2/internal/frontend/desktop/darwin/calloc.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package darwin
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// Calloc handles alloc/dealloc of C data
|
||||||
|
type Calloc struct {
|
||||||
|
pool []unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCalloc creates a new allocator
|
||||||
|
func NewCalloc() Calloc {
|
||||||
|
return Calloc{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String creates a new C string and retains a reference to it
|
||||||
|
func (c Calloc) String(in string) *C.char {
|
||||||
|
result := C.CString(in)
|
||||||
|
c.pool = append(c.pool, unsafe.Pointer(result))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free frees all allocated C memory
|
||||||
|
func (c Calloc) Free() {
|
||||||
|
for _, str := range c.pool {
|
||||||
|
C.free(str)
|
||||||
|
}
|
||||||
|
c.pool = []unsafe.Pointer{}
|
||||||
|
}
|
@ -3,31 +3,183 @@
|
|||||||
|
|
||||||
package darwin
|
package darwin
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -x objective-c
|
||||||
|
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "Application.h"
|
||||||
|
#import "WailsContext.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/leaanthony/slicer"
|
||||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Obj-C dialog methods send the response to this channel
|
||||||
|
var messageDialogResponse = make(chan int)
|
||||||
|
var openFileDialogResponse = make(chan string)
|
||||||
|
var saveFileDialogResponse = make(chan string)
|
||||||
|
var dialogLock sync.Mutex
|
||||||
|
|
||||||
// OpenDirectoryDialog prompts the user to select a directory
|
// OpenDirectoryDialog prompts the user to select a directory
|
||||||
func (f *Frontend) OpenDirectoryDialog(options frontend.OpenDialogOptions) (string, error) {
|
func (f *Frontend) OpenDirectoryDialog(options frontend.OpenDialogOptions) (string, error) {
|
||||||
return "", nil
|
results, err := f.openDialog(&options, false, false, true)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var selected string
|
||||||
|
if len(results) > 0 {
|
||||||
|
selected = results[0]
|
||||||
|
}
|
||||||
|
return selected, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) openDialog(options *frontend.OpenDialogOptions, multiple bool, allowfiles bool, allowdirectories bool) ([]string, error) {
|
||||||
|
dialogLock.Lock()
|
||||||
|
defer dialogLock.Unlock()
|
||||||
|
|
||||||
|
c := NewCalloc()
|
||||||
|
defer c.Free()
|
||||||
|
title := c.String(options.Title)
|
||||||
|
defaultFilename := c.String(options.DefaultFilename)
|
||||||
|
defaultDirectory := c.String(options.DefaultDirectory)
|
||||||
|
allowDirectories := bool2Cint(allowdirectories)
|
||||||
|
allowFiles := bool2Cint(allowfiles)
|
||||||
|
canCreateDirectories := bool2Cint(options.CanCreateDirectories)
|
||||||
|
treatPackagesAsDirectories := bool2Cint(options.TreatPackagesAsDirectories)
|
||||||
|
resolveAliases := bool2Cint(options.ResolvesAliases)
|
||||||
|
showHiddenFiles := bool2Cint(options.ShowHiddenFiles)
|
||||||
|
allowMultipleFileSelection := bool2Cint(multiple)
|
||||||
|
|
||||||
|
var filterStrings slicer.StringSlicer
|
||||||
|
if options.Filters != nil {
|
||||||
|
for _, filter := range options.Filters {
|
||||||
|
thesePatterns := strings.Split(filter.Pattern, ";")
|
||||||
|
for _, pattern := range thesePatterns {
|
||||||
|
pattern = strings.TrimSpace(pattern)
|
||||||
|
if pattern != "" {
|
||||||
|
filterStrings.Add(pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterStrings.Deduplicate()
|
||||||
|
}
|
||||||
|
filters := filterStrings.Join(";")
|
||||||
|
C.OpenFileDialog(f.mainWindow.context, title, defaultFilename, defaultDirectory, allowDirectories, allowFiles, canCreateDirectories, treatPackagesAsDirectories, resolveAliases, showHiddenFiles, allowMultipleFileSelection, c.String(filters))
|
||||||
|
|
||||||
|
var result = <-openFileDialogResponse
|
||||||
|
|
||||||
|
var parsedResults []string
|
||||||
|
err := json.Unmarshal([]byte(result), &parsedResults)
|
||||||
|
|
||||||
|
return parsedResults, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenFileDialog prompts the user to select a file
|
// OpenFileDialog prompts the user to select a file
|
||||||
func (f *Frontend) OpenFileDialog(options frontend.OpenDialogOptions) (string, error) {
|
func (f *Frontend) OpenFileDialog(options frontend.OpenDialogOptions) (string, error) {
|
||||||
return "", nil
|
results, err := f.openDialog(&options, false, options.AllowFiles, options.AllowDirectories)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var selected string
|
||||||
|
if len(results) > 0 {
|
||||||
|
selected = results[0]
|
||||||
|
}
|
||||||
|
return selected, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenMultipleFilesDialog prompts the user to select a file
|
// OpenMultipleFilesDialog prompts the user to select a file
|
||||||
func (f *Frontend) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
|
func (f *Frontend) OpenMultipleFilesDialog(options frontend.OpenDialogOptions) ([]string, error) {
|
||||||
return []string{}, nil
|
return f.openDialog(&options, true, options.AllowFiles, options.AllowDirectories)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveFileDialog prompts the user to select a file
|
// SaveFileDialog prompts the user to select a file
|
||||||
func (f *Frontend) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (string, error) {
|
func (f *Frontend) SaveFileDialog(options frontend.SaveDialogOptions) (string, error) {
|
||||||
return "", nil
|
dialogLock.Lock()
|
||||||
|
defer dialogLock.Unlock()
|
||||||
|
|
||||||
|
c := NewCalloc()
|
||||||
|
defer c.Free()
|
||||||
|
title := c.String(options.Title)
|
||||||
|
defaultFilename := c.String(options.DefaultFilename)
|
||||||
|
defaultDirectory := c.String(options.DefaultDirectory)
|
||||||
|
canCreateDirectories := bool2Cint(options.CanCreateDirectories)
|
||||||
|
treatPackagesAsDirectories := bool2Cint(options.TreatPackagesAsDirectories)
|
||||||
|
showHiddenFiles := bool2Cint(options.ShowHiddenFiles)
|
||||||
|
|
||||||
|
var filterStrings slicer.StringSlicer
|
||||||
|
if options.Filters != nil {
|
||||||
|
for _, filter := range options.Filters {
|
||||||
|
thesePatterns := strings.Split(filter.Pattern, ";")
|
||||||
|
for _, pattern := range thesePatterns {
|
||||||
|
pattern = strings.TrimSpace(pattern)
|
||||||
|
if pattern != "" {
|
||||||
|
filterStrings.Add(pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterStrings.Deduplicate()
|
||||||
|
}
|
||||||
|
filters := filterStrings.Join(";")
|
||||||
|
C.SaveFileDialog(f.mainWindow.context, title, defaultFilename, defaultDirectory, canCreateDirectories, treatPackagesAsDirectories, showHiddenFiles, c.String(filters))
|
||||||
|
|
||||||
|
var result = <-saveFileDialogResponse
|
||||||
|
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageDialog show a message dialog to the user
|
// MessageDialog show a message dialog to the user
|
||||||
func (f *Frontend) MessageDialog(options frontend.MessageDialogOptions) (string, error) {
|
func (f *Frontend) MessageDialog(options frontend.MessageDialogOptions) (string, error) {
|
||||||
return "", nil
|
dialogLock.Lock()
|
||||||
|
defer dialogLock.Unlock()
|
||||||
|
|
||||||
|
c := NewCalloc()
|
||||||
|
defer c.Free()
|
||||||
|
dialogType := c.String(string(options.Type))
|
||||||
|
title := c.String(options.Title)
|
||||||
|
message := c.String(options.Message)
|
||||||
|
defaultButton := c.String(options.DefaultButton)
|
||||||
|
cancelButton := c.String(options.CancelButton)
|
||||||
|
const MaxButtons = 4
|
||||||
|
var buttons [MaxButtons]*C.char
|
||||||
|
for index, buttonText := range options.Buttons {
|
||||||
|
if index == MaxButtons {
|
||||||
|
return "", fmt.Errorf("max %d buttons supported (%d given)", MaxButtons, len(options.Buttons))
|
||||||
|
}
|
||||||
|
buttons[index] = c.String(buttonText)
|
||||||
|
}
|
||||||
|
|
||||||
|
C.MessageDialog(f.mainWindow.context, dialogType, title, message, buttons[0], buttons[1], buttons[2], buttons[3], defaultButton, cancelButton)
|
||||||
|
|
||||||
|
var result = <-messageDialogResponse
|
||||||
|
|
||||||
|
selectedC := buttons[result]
|
||||||
|
var selected string
|
||||||
|
if selectedC != nil {
|
||||||
|
selected = options.Buttons[result]
|
||||||
|
}
|
||||||
|
return selected, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//export processMessageDialogResponse
|
||||||
|
func processMessageDialogResponse(selection int) {
|
||||||
|
messageDialogResponse <- selection
|
||||||
|
}
|
||||||
|
|
||||||
|
//export processOpenFileDialogResponse
|
||||||
|
func processOpenFileDialogResponse(cselection *C.char) {
|
||||||
|
selection := C.GoString(cselection)
|
||||||
|
openFileDialogResponse <- selection
|
||||||
|
}
|
||||||
|
|
||||||
|
//export processSaveFileDialogResponse
|
||||||
|
func processSaveFileDialogResponse(cselection *C.char) {
|
||||||
|
selection := C.GoString(cselection)
|
||||||
|
saveFileDialogResponse <- selection
|
||||||
}
|
}
|
||||||
|
56
v2/internal/frontend/desktop/darwin/main.m
Normal file
56
v2/internal/frontend/desktop/darwin/main.m
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//go:build ignore
|
||||||
|
// main.m
|
||||||
|
// test
|
||||||
|
//
|
||||||
|
// Created by Lea Anthony on 10/10/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
// ****** This file is used for testing purposes only ******
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "Application.h"
|
||||||
|
|
||||||
|
void processMessage(const char*t) {
|
||||||
|
NSLog(@"processMessage called");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void processMessageDialogResponse(int t) {
|
||||||
|
NSLog(@"processMessage called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void processOpenFileDialogResponse(const char *t) {
|
||||||
|
NSLog(@"processMessage called %s", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void processURLRequest(void *ctx, const char* url) {
|
||||||
|
NSLog(@"processURLRequest called");
|
||||||
|
const char myByteArray[] = { 0x3c,0x68,0x31,0x3e,0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64,0x21,0x3c,0x2f,0x68,0x31,0x3e };
|
||||||
|
ProcessURLResponse(ctx, url, "text/html", myByteArray, 21);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char * argv[]) {
|
||||||
|
// insert code here...
|
||||||
|
int frameless = 0;
|
||||||
|
int resizable = 1;
|
||||||
|
int fullscreen = 0;
|
||||||
|
int fullSizeContent = 1;
|
||||||
|
int hideTitleBar = 0;
|
||||||
|
int titlebarAppearsTransparent = 1;
|
||||||
|
int hideTitle = 0;
|
||||||
|
int useToolbar = 1;
|
||||||
|
int hideToolbarSeparator = 1;
|
||||||
|
int webviewIsTransparent = 0;
|
||||||
|
int alwaysOnTop = 1;
|
||||||
|
int hideWindowOnClose = 0;
|
||||||
|
const char* appearance = "NSAppearanceNameDarkAqua";
|
||||||
|
int windowIsTranslucent = 1;
|
||||||
|
int debug = 1;
|
||||||
|
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug);
|
||||||
|
SetRGBA(result, 255, 0, 0, 255);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Run((void*)CFBridgingRetain(result));
|
||||||
|
return 0;
|
||||||
|
}
|
@ -16,6 +16,9 @@ extern "C"
|
|||||||
|
|
||||||
void processMessage(const char *);
|
void processMessage(const char *);
|
||||||
void processURLRequest(void*, const char *);
|
void processURLRequest(void*, const char *);
|
||||||
|
void processMessageDialogResponse(int);
|
||||||
|
void processOpenFileDialogResponse(const char*);
|
||||||
|
void processSaveFileDialogResponse(const char*);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,9 @@ func bool2Cint(value bool) C.int {
|
|||||||
|
|
||||||
func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
||||||
|
|
||||||
|
c := NewCalloc()
|
||||||
|
defer c.Free()
|
||||||
|
|
||||||
frameless := bool2Cint(frontendOptions.Frameless)
|
frameless := bool2Cint(frontendOptions.Frameless)
|
||||||
resizable := bool2Cint(!frontendOptions.DisableResize)
|
resizable := bool2Cint(!frontendOptions.DisableResize)
|
||||||
fullscreen := bool2Cint(frontendOptions.Fullscreen)
|
fullscreen := bool2Cint(frontendOptions.Fullscreen)
|
||||||
@ -55,7 +58,7 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
|||||||
width := C.int(frontendOptions.Width)
|
width := C.int(frontendOptions.Width)
|
||||||
height := C.int(frontendOptions.Height)
|
height := C.int(frontendOptions.Height)
|
||||||
|
|
||||||
title = C.CString(frontendOptions.Title)
|
title = c.String(frontendOptions.Title)
|
||||||
|
|
||||||
if frontendOptions.Mac != nil {
|
if frontendOptions.Mac != nil {
|
||||||
mac := frontendOptions.Mac
|
mac := frontendOptions.Mac
|
||||||
@ -70,15 +73,10 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
|||||||
windowIsTranslucent = bool2Cint(mac.WindowIsTranslucent)
|
windowIsTranslucent = bool2Cint(mac.WindowIsTranslucent)
|
||||||
webviewIsTransparent = bool2Cint(mac.WebviewIsTransparent)
|
webviewIsTransparent = bool2Cint(mac.WebviewIsTransparent)
|
||||||
|
|
||||||
appearance = C.CString(string(mac.Appearance))
|
appearance = c.String(string(mac.Appearance))
|
||||||
}
|
}
|
||||||
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug)
|
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug)
|
||||||
|
|
||||||
C.free(unsafe.Pointer(title))
|
|
||||||
if appearance != nil {
|
|
||||||
C.free(unsafe.Pointer(appearance))
|
|
||||||
}
|
|
||||||
|
|
||||||
C.SetRGBA(unsafe.Pointer(context), red, green, blue, alpha)
|
C.SetRGBA(unsafe.Pointer(context), red, green, blue, alpha)
|
||||||
|
|
||||||
return &Window{
|
return &Window{
|
||||||
|
@ -6,50 +6,59 @@ sidebar_position: 5
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This part of the runtime provides access to native dialogs, such as File Selectors and Message boxes.Context
|
This part of the runtime provides access to native dialogs, such as File Selectors and Message boxes.
|
||||||
|
|
||||||
:::info Javascript
|
:::info Javascript
|
||||||
Dialog is currently unsupported in the JS runtime.
|
Dialog is currently unsupported in the JS runtime.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### OpenDirectoryDialog
|
### OpenDirectoryDialog
|
||||||
|
|
||||||
|
Opens a dialog that prompts the user to select a directory. Can be customised using [OpenDialogOptions](#opendialogoptions).
|
||||||
|
|
||||||
Go Signature: `OpenDirectoryDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)`
|
Go Signature: `OpenDirectoryDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)`
|
||||||
|
|
||||||
Returns: Selected directory (blank if the user cancelled) or an error
|
Returns: Selected directory (blank if the user cancelled) or an error
|
||||||
|
|
||||||
Opens a dialog that prompts the user to select a directory. Can be customised using [OpenDialogOptions](#OpenDialogOptions).
|
|
||||||
|
|
||||||
### OpenFileDialog
|
### OpenFileDialog
|
||||||
|
|
||||||
|
Opens a dialog that prompts the user to select a file. Can be customised using [OpenDialogOptions](#opendialogoptions).
|
||||||
|
|
||||||
Go Signature: `OpenFileDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)`
|
Go Signature: `OpenFileDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)`
|
||||||
|
|
||||||
Returns: Selected file (blank if the user cancelled) or an error
|
Returns: Selected file (blank if the user cancelled) or an error
|
||||||
|
|
||||||
Opens a dialog that prompts the user to select a file. Can be customised using [OpenDialogOptions](#OpenDialogOptions).
|
|
||||||
|
|
||||||
|
|
||||||
### OpenMultipleFilesDialog
|
### OpenMultipleFilesDialog
|
||||||
|
|
||||||
|
Opens a dialog that prompts the user to select multiple files. Can be customised using [OpenDialogOptions](#opendialogoptions).
|
||||||
|
|
||||||
Go Signature: `OpenMultipleFilesDialog(ctx context.Context, dialogOptions OpenDialogOptions) ([]string, error)`
|
Go Signature: `OpenMultipleFilesDialog(ctx context.Context, dialogOptions OpenDialogOptions) ([]string, error)`
|
||||||
|
|
||||||
Returns: Selected files (nil if the user cancelled) or an error
|
Returns: Selected files (nil if the user cancelled) or an error
|
||||||
|
|
||||||
Opens a dialog that prompts the user to select multiple files. Can be customised using [OpenDialogOptions](#OpenDialogOptions).
|
|
||||||
|
|
||||||
|
|
||||||
### SaveFileDialog
|
### SaveFileDialog
|
||||||
|
|
||||||
|
Opens a dialog that prompts the user to select a filename for the purposes of saving. Can be customised using [SaveDialogOptions](#savedialogoptions).
|
||||||
|
|
||||||
Go Signature: `SaveFileDialog(ctx context.Context, dialogOptions SaveDialogOptions) (string, error)`
|
Go Signature: `SaveFileDialog(ctx context.Context, dialogOptions SaveDialogOptions) (string, error)`
|
||||||
|
|
||||||
Returns: The selected file (blank if the user cancelled) or an error
|
Returns: The selected file (blank if the user cancelled) or an error
|
||||||
|
|
||||||
Opens a dialog that prompts the user to select a filename for the purposes of saving. Can be customised using [SaveDialogOptions](#SaveDialogOptions).
|
|
||||||
|
|
||||||
|
|
||||||
### MessageDialog
|
### MessageDialog
|
||||||
|
|
||||||
|
Displays a message using a message dialog. Can be customised using [MessageDialogOptions](#messagedialogoptions).
|
||||||
|
|
||||||
Go Signature: `MessageDialog(ctx context.Context, dialogOptions MessageDialogOptions) (string, error)`
|
Go Signature: `MessageDialog(ctx context.Context, dialogOptions MessageDialogOptions) (string, error)`
|
||||||
|
|
||||||
Returns: The text of the selected button or an error
|
Returns: The text of the selected button or an error
|
||||||
|
|
||||||
Displays a message using a message dialog. Can be customised using [MessageDialogOptions](#MessageDialogOptions).
|
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
### OpenDialogOptions
|
### OpenDialogOptions
|
||||||
@ -60,14 +69,27 @@ type OpenDialogOptions struct {
|
|||||||
DefaultFilename string
|
DefaultFilename string
|
||||||
Title string
|
Title string
|
||||||
Filters []FileFilter
|
Filters []FileFilter
|
||||||
AllowFiles bool // Mac Only
|
AllowFiles bool
|
||||||
AllowDirectories bool // Mac Only
|
AllowDirectories bool
|
||||||
ShowHiddenFiles bool // Mac Only
|
ShowHiddenFiles bool
|
||||||
CanCreateDirectories bool // Mac Only
|
CanCreateDirectories bool
|
||||||
ResolvesAliases bool // Mac Only
|
ResolvesAliases bool
|
||||||
TreatPackagesAsDirectories bool // Mac Only
|
TreatPackagesAsDirectories bool
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
| Field | Description | Win | Mac |
|
||||||
|
| -------------------------- | ---------------------------------------------- | --- | --- |
|
||||||
|
| DefaultDirectory | The directory the dialog will show when opened | ✅ | ✅ |
|
||||||
|
| DefaultFilename | The default filename | ✅ | ✅ |
|
||||||
|
| Title | Title for the dialog | ✅ | ✅ |
|
||||||
|
| [Filters](#filefilter) | A list of file filters | ✅ | ✅ |
|
||||||
|
| AllowFiles | Allow files to be selected | | ✅ |
|
||||||
|
| AllowDirectories | Allow directories to be selected | | ✅ |
|
||||||
|
| ShowHiddenFiles | Show files hidden by the system | | ✅ |
|
||||||
|
| CanCreateDirectories | Allow user to create directories | | ✅ |
|
||||||
|
| ResolvesAliases | If true, returns the file not the alias | | ✅ |
|
||||||
|
| TreatPackagesAsDirectories | Allow navigating into packages | | ✅ |
|
||||||
|
|
||||||
|
|
||||||
### SaveDialogOptions
|
### SaveDialogOptions
|
||||||
|
|
||||||
@ -77,12 +99,22 @@ type SaveDialogOptions struct {
|
|||||||
DefaultFilename string
|
DefaultFilename string
|
||||||
Title string
|
Title string
|
||||||
Filters []FileFilter
|
Filters []FileFilter
|
||||||
ShowHiddenFiles bool // Mac Only
|
ShowHiddenFiles bool
|
||||||
CanCreateDirectories bool // Mac Only
|
CanCreateDirectories bool
|
||||||
TreatPackagesAsDirectories bool // Mac Only
|
TreatPackagesAsDirectories bool
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
| Field | Description | Win | Mac |
|
||||||
|
| -------------------------- | ---------------------------------------------- | --- | --- |
|
||||||
|
| DefaultDirectory | The directory the dialog will show when opened | ✅ | ✅ |
|
||||||
|
| DefaultFilename | The default filename | ✅ | ✅ |
|
||||||
|
| Title | Title for the dialog | ✅ | ✅ |
|
||||||
|
| [Filters](#filefilter) | A list of file filters | ✅ | ✅ |
|
||||||
|
| ShowHiddenFiles | Show files hidden by the system | | ✅ |
|
||||||
|
| CanCreateDirectories | Allow user to create directories | | ✅ |
|
||||||
|
| TreatPackagesAsDirectories | Allow navigating into packages | | ✅ |
|
||||||
|
|
||||||
### MessageDialogOptions
|
### MessageDialogOptions
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -91,33 +123,76 @@ type MessageDialogOptions struct {
|
|||||||
Title string
|
Title string
|
||||||
Message string
|
Message string
|
||||||
Buttons []string
|
Buttons []string
|
||||||
DefaultButton string // Mac Only
|
DefaultButton string
|
||||||
CancelButton string // Mac Only
|
CancelButton string
|
||||||
Icon string // Mac Only
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
| Field | Description | Win | Mac |
|
||||||
|
| ------------- | ------------------------------------------------------------------------- | --- | --- |
|
||||||
|
| Type | The type of message dialog, eg question, info... | ✅ | ✅ |
|
||||||
|
| Title | Title for the dialog | ✅ | ✅ |
|
||||||
|
| Message | The message to show the user | ✅ | ✅ |
|
||||||
|
| Buttons | A list of button titles | | ✅ |
|
||||||
|
| DefaultButton | The button with this text should be treated as default. Bound to `return` | | ✅ |
|
||||||
|
| CancelButton | The button with this text should be treated as cancel. Bound to `escape` | | ✅ |
|
||||||
|
|
||||||
import Tabs from '@theme/Tabs';
|
#### Windows
|
||||||
import TabItem from '@theme/TabItem';
|
|
||||||
|
Windows has standard dialog types in which the buttons are not customisable.
|
||||||
|
The value returned will be one of: "Ok", "Cancel", "Abort", "Retry", "Ignore", "Yes", "No", "Try Again" or "Continue"
|
||||||
|
|
||||||
|
#### Mac
|
||||||
|
|
||||||
|
A message dialog on Mac may specify up to 4 buttons. If no `DefaultButton` or `CancelButton` is given, the first button
|
||||||
|
is considered default and is bound to the `return` key.
|
||||||
|
|
||||||
|
For the following code:
|
||||||
|
```go
|
||||||
|
selection, err := runtime.MessageDialog(b.ctx, runtime.MessageDialogOptions{
|
||||||
|
Title: "It's your turn!",
|
||||||
|
Message: "Select a number",
|
||||||
|
Buttons: []string{"one", "two", "three", "four"},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
the first button is shown as default:
|
||||||
|
<div class="text--center">
|
||||||
|
<img src="/img/runtime/dialog_no_defaults.png" width="30%" style={{"box-shadow": "rgb(255 255 255 / 20%) 0px 4px 8px 0px, rgb(104 104 104) 0px 6px 20px 0px"}}/>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
And if we specify `DefaultButton` to be "two":
|
||||||
|
```go
|
||||||
|
selection, err := runtime.MessageDialog(b.ctx, runtime.MessageDialogOptions{
|
||||||
|
Title: "It's your turn!",
|
||||||
|
Message: "Select a number",
|
||||||
|
Buttons: []string{"one", "two", "three", "four"},
|
||||||
|
DefaultButton: "two",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
the second button is shown as default. When `return` is pressed, the value "two" is returned.
|
||||||
|
<div class="text--center">
|
||||||
|
<img src="/img/runtime/dialog_default_button.png" width="30%" style={{"box-shadow": "rgb(255 255 255 / 20%) 0px 4px 8px 0px, rgb(104 104 104) 0px 6px 20px 0px"}}/>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
If we now specify `CancelButton` to be "three":
|
||||||
|
```go
|
||||||
|
selection, err := runtime.MessageDialog(b.ctx, runtime.MessageDialogOptions{
|
||||||
|
Title: "It's your turn!",
|
||||||
|
Message: "Select a number",
|
||||||
|
Buttons: []string{"one", "two", "three", "four"},
|
||||||
|
DefaultButton: "two",
|
||||||
|
CancelButton: "three",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
the button with "three" is shown at the bottom of the dialog. When `escape` is pressed, the value "three" is returned:
|
||||||
|
<div class="text--center">
|
||||||
|
<img src="/img/runtime/dialog_default_cancel.png" width="30%" style={{"box-shadow": "rgb(255 255 255 / 20%) 0px 4px 8px 0px, rgb(104 104 104) 0px 6px 20px 0px"}}/>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
<Tabs
|
|
||||||
defaultValue="Windows"
|
|
||||||
values={[
|
|
||||||
{label: 'Windows', value: 'Windows'},
|
|
||||||
{label: 'MacOS', value: 'MacOS'},
|
|
||||||
{label: 'Linux', value: 'Linux'},
|
|
||||||
]}>
|
|
||||||
<TabItem value="MacOS">
|
|
||||||
Both "DefaultButton" and "CancelButton" should match a value in "Buttons".
|
|
||||||
</TabItem>
|
|
||||||
<TabItem value="Windows">
|
|
||||||
Windows has standard dialog types and the buttons are not customisable. The
|
|
||||||
value returned will be one of: "Ok", "Cancel", "Abort", "Retry", "Ignore", "Yes", "No", "Try Again" or "Continue"
|
|
||||||
</TabItem>
|
|
||||||
<TabItem value="Linux">
|
|
||||||
Coming Soon...
|
|
||||||
</TabItem>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
#### DialogType
|
#### DialogType
|
||||||
|
|
||||||
@ -138,3 +213,30 @@ type FileFilter struct {
|
|||||||
Pattern string // semi-colon separated list of extensions, EG: "*.jpg;*.png"
|
Pattern string // semi-colon separated list of extensions, EG: "*.jpg;*.png"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
Windows allows you to use multiple file filters in dialog boxes. Each FileFilter will show up as a separate entry in the
|
||||||
|
dialog.
|
||||||
|
|
||||||
|
#### Mac
|
||||||
|
|
||||||
|
Mac dialogs only have the concept of a single set of patterns to filter files. If multiple FileFilters are provided,
|
||||||
|
Wails will use all the Patterns defined.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```go
|
||||||
|
selection, err := runtime.OpenFileDialog(b.ctx, runtime.OpenDialogOptions{
|
||||||
|
Title: "Select File",
|
||||||
|
Filters: []runtime.FileFilter{
|
||||||
|
{
|
||||||
|
DisplayName: "Images (*.png;*.jpg)",
|
||||||
|
Pattern: "*.png;*.jpg",
|
||||||
|
}, {
|
||||||
|
DisplayName: "Videos (*.mov;*.mp4)",
|
||||||
|
Pattern: "*.mov;*.mp4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
This will result in the Open File dialog using `*.png,*.jpg,*.mov,*.mp4` as a filter.
|
15652
website/package-lock.json
generated
15652
website/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
BIN
website/static/img/runtime/dialog_default_button.png
Normal file
BIN
website/static/img/runtime/dialog_default_button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
BIN
website/static/img/runtime/dialog_default_cancel.png
Normal file
BIN
website/static/img/runtime/dialog_default_cancel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
BIN
website/static/img/runtime/dialog_no_defaults.png
Normal file
BIN
website/static/img/runtime/dialog_no_defaults.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
Loading…
Reference in New Issue
Block a user