mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Add SaveFileDialog
Add Toolbar Styles Add Invisible Titlebar option with drag support
This commit is contained in:
parent
e7abe1c606
commit
025e8d7645
12 changed files with 339 additions and 38 deletions
|
|
@ -140,7 +140,7 @@ func main() {
|
|||
openMenu.Add("Open File").OnClick(func(ctx *application.Context) {
|
||||
result, _ := app.NewOpenFileDialog().
|
||||
CanChooseFiles(true).
|
||||
PromptForSingleFile()
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
} else {
|
||||
|
|
@ -152,7 +152,7 @@ func main() {
|
|||
CanChooseFiles(true).
|
||||
CanCreateDirectories(true).
|
||||
ShowHiddenFiles(true).
|
||||
PromptForSingleFile()
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
} else {
|
||||
|
|
@ -165,7 +165,7 @@ func main() {
|
|||
CanCreateDirectories(true).
|
||||
ShowHiddenFiles(true).
|
||||
AttachToWindow(app.GetCurrentWindow()).
|
||||
PromptForSingleFile()
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
} else {
|
||||
|
|
@ -177,7 +177,7 @@ func main() {
|
|||
CanChooseFiles(true).
|
||||
CanCreateDirectories(true).
|
||||
ShowHiddenFiles(true).
|
||||
PromptForMultipleFiles()
|
||||
PromptForMultipleSelection()
|
||||
if len(result) > 0 {
|
||||
app.NewInfoDialog().SetMessage(strings.Join(result, ",")).Show()
|
||||
} else {
|
||||
|
|
@ -187,7 +187,7 @@ func main() {
|
|||
openMenu.Add("Open Directory").OnClick(func(ctx *application.Context) {
|
||||
result, _ := app.NewOpenFileDialog().
|
||||
CanChooseDirectories(true).
|
||||
PromptForSingleFile()
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
} else {
|
||||
|
|
@ -198,7 +198,7 @@ func main() {
|
|||
result, _ := app.NewOpenFileDialog().
|
||||
CanChooseDirectories(true).
|
||||
CanCreateDirectories(true).
|
||||
PromptForSingleFile()
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
} else {
|
||||
|
|
@ -206,6 +206,39 @@ func main() {
|
|||
}
|
||||
})
|
||||
|
||||
saveMenu := menu.AddSubmenu("Save")
|
||||
saveMenu.Add("Select File (Defaults)").OnClick(func(ctx *application.Context) {
|
||||
result, _ := app.NewSaveFileDialog().
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
}
|
||||
})
|
||||
saveMenu.Add("Select File (Attach To Window)").OnClick(func(ctx *application.Context) {
|
||||
result, _ := app.NewSaveFileDialog().
|
||||
AttachToWindow(app.GetCurrentWindow()).
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
}
|
||||
})
|
||||
saveMenu.Add("Select File (Show Hidden Files)").OnClick(func(ctx *application.Context) {
|
||||
result, _ := app.NewSaveFileDialog().
|
||||
ShowHiddenFiles(true).
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
}
|
||||
})
|
||||
saveMenu.Add("Select File (Cannot Create Directories)").OnClick(func(ctx *application.Context) {
|
||||
result, _ := app.NewSaveFileDialog().
|
||||
CanCreateDirectories(false).
|
||||
PromptForSingleSelection()
|
||||
if result != "" {
|
||||
app.NewInfoDialog().SetMessage(result).Show()
|
||||
}
|
||||
})
|
||||
|
||||
app.SetMenu(menu)
|
||||
|
||||
app.NewWindow()
|
||||
|
|
|
|||
|
|
@ -12,6 +12,18 @@ import (
|
|||
func main() {
|
||||
app := application.New()
|
||||
|
||||
// Create window
|
||||
app.NewWindowWithOptions(&options.Window{
|
||||
Title: "Plain Bundle",
|
||||
EnableDevTools: true,
|
||||
HTML: `<html><head><title>Plain Bundle</title></head><body><div class="main"><h1>Plain Bundle</h1><p>This is a plain bundle. It has no frontend code.</p></div></body></html>`,
|
||||
CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`,
|
||||
Mac: &options.MacWindow{
|
||||
InvisibleTitleBarHeight: 50,
|
||||
Backdrop: options.MacBackdropTranslucent,
|
||||
TitleBar: options.TitleBarHiddenInset,
|
||||
},
|
||||
})
|
||||
// Create window
|
||||
app.NewWindowWithOptions(&options.Window{
|
||||
Title: "Plain Bundle",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ func main() {
|
|||
EnableDevTools: true,
|
||||
Mac: &options.MacWindow{
|
||||
Backdrop: options.MacBackdropTranslucent,
|
||||
TitleBar: options.TitleBarHiddenInset,
|
||||
TitleBar: options.TitleBarHiddenInsetUnified,
|
||||
},
|
||||
})
|
||||
myWindow.On(events.Mac.WindowDidBecomeMain, func() {
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ func (a *App) NewSystemTray() *SystemTray {
|
|||
}
|
||||
|
||||
func (a *App) Run() error {
|
||||
a.impl = newPlatformApp(a.options)
|
||||
a.impl = newPlatformApp(a)
|
||||
|
||||
a.running = true
|
||||
go func() {
|
||||
|
|
@ -344,3 +344,7 @@ func (a *App) NewOpenDirectoryDialog() *MessageDialog {
|
|||
func (a *App) NewOpenFileDialog() *OpenFileDialog {
|
||||
return newOpenFileDialog()
|
||||
}
|
||||
|
||||
func (a *App) NewSaveFileDialog() *SaveFileDialog {
|
||||
return newSaveFileDialog()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,28 @@ static void init(void) {
|
|||
[NSApplication sharedApplication];
|
||||
appDelegate = [[AppDelegate alloc] init];
|
||||
[NSApp setDelegate:appDelegate];
|
||||
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown handler:^NSEvent * _Nullable(NSEvent * _Nonnull event) {
|
||||
NSWindow* eventWindow = [event window];
|
||||
if (![eventWindow respondsToSelector:@selector(handleLeftMouseDown)]) {
|
||||
return event;
|
||||
}
|
||||
|
||||
WindowDelegate* windowDelegate = (WindowDelegate*)[eventWindow delegate];
|
||||
[windowDelegate handleLeftMouseDown:event];
|
||||
return event;
|
||||
}];
|
||||
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseUp handler:^NSEvent * _Nullable(NSEvent * _Nonnull event) {
|
||||
NSWindow* eventWindow = [event window];
|
||||
if (![eventWindow respondsToSelector:@selector(handleLeftMouseUp)]) {
|
||||
return event;
|
||||
}
|
||||
|
||||
WindowDelegate* windowDelegate = (WindowDelegate*)[eventWindow delegate];
|
||||
[windowDelegate handleLeftMouseUp:eventWindow];
|
||||
return event;
|
||||
}];
|
||||
}
|
||||
|
||||
static void setActivationPolicy(int policy) {
|
||||
|
|
@ -79,12 +101,14 @@ import "C"
|
|||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/exp/pkg/events"
|
||||
|
||||
"github.com/wailsapp/wails/exp/pkg/options"
|
||||
)
|
||||
|
||||
type macosApp struct {
|
||||
options *options.Application
|
||||
applicationMenu unsafe.Pointer
|
||||
parent *App
|
||||
}
|
||||
|
||||
func (m *macosApp) setIcon(icon []byte) {
|
||||
|
|
@ -107,12 +131,19 @@ func (m *macosApp) setApplicationMenu(menu *Menu) {
|
|||
menu = defaultApplicationMenu()
|
||||
}
|
||||
menu.Update()
|
||||
|
||||
// Convert impl to macosMenu object
|
||||
m.applicationMenu = (menu.impl).(*macosMenu).nsMenu
|
||||
C.setApplicationMenu(m.applicationMenu)
|
||||
}
|
||||
|
||||
func (m *macosApp) run() error {
|
||||
m.parent.On(events.Mac.ApplicationDidFinishLaunching, func() {
|
||||
if m.parent.options != nil && m.parent.options.Mac != nil {
|
||||
C.setActivationPolicy(C.int(m.parent.options.Mac.ActivationPolicy))
|
||||
}
|
||||
C.activateIgnoringOtherApps()
|
||||
})
|
||||
C.run()
|
||||
return nil
|
||||
}
|
||||
|
|
@ -121,15 +152,14 @@ func (m *macosApp) destroy() {
|
|||
C.destroyApp()
|
||||
}
|
||||
|
||||
func newPlatformApp(appOptions *options.Application) *macosApp {
|
||||
func newPlatformApp(app *App) *macosApp {
|
||||
appOptions := app.options
|
||||
if appOptions == nil {
|
||||
appOptions = options.ApplicationDefaults
|
||||
}
|
||||
C.init()
|
||||
C.setActivationPolicy(C.int(appOptions.Mac.ActivationPolicy))
|
||||
C.activateIgnoringOtherApps()
|
||||
return &macosApp{
|
||||
options: appOptions,
|
||||
parent: app,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
type DialogType int
|
||||
|
||||
// TODO: Make this a map and clear it when the dialog is closed
|
||||
var dialogID uint
|
||||
var dialogIDLock sync.RWMutex
|
||||
|
||||
|
|
@ -18,6 +19,7 @@ func getDialogID() uint {
|
|||
}
|
||||
|
||||
var openFileResponses = make(map[uint]chan string)
|
||||
var saveFileResponses = make(map[uint]chan string)
|
||||
|
||||
const (
|
||||
InfoDialog DialogType = iota
|
||||
|
|
@ -154,7 +156,7 @@ func (d *OpenFileDialog) AttachToWindow(window *Window) *OpenFileDialog {
|
|||
return d
|
||||
}
|
||||
|
||||
func (d *OpenFileDialog) PromptForSingleFile() (string, error) {
|
||||
func (d *OpenFileDialog) PromptForSingleSelection() (string, error) {
|
||||
d.allowsMultipleSelection = false
|
||||
if d.impl == nil {
|
||||
d.impl = newOpenFileDialogImpl(d)
|
||||
|
|
@ -168,7 +170,7 @@ func (d *OpenFileDialog) PromptForSingleFile() (string, error) {
|
|||
return result, err
|
||||
}
|
||||
|
||||
func (d *OpenFileDialog) PromptForMultipleFiles() ([]string, error) {
|
||||
func (d *OpenFileDialog) PromptForMultipleSelection() ([]string, error) {
|
||||
d.allowsMultipleSelection = true
|
||||
if d.impl == nil {
|
||||
d.impl = newOpenFileDialogImpl(d)
|
||||
|
|
@ -181,6 +183,48 @@ func newOpenFileDialog() *OpenFileDialog {
|
|||
id: getDialogID(),
|
||||
canChooseDirectories: false,
|
||||
canChooseFiles: true,
|
||||
canCreateDirectories: false,
|
||||
canCreateDirectories: true,
|
||||
}
|
||||
}
|
||||
|
||||
func newSaveFileDialog() *SaveFileDialog {
|
||||
return &SaveFileDialog{
|
||||
id: getDialogID(),
|
||||
canCreateDirectories: true,
|
||||
}
|
||||
}
|
||||
|
||||
type SaveFileDialog struct {
|
||||
id uint
|
||||
canCreateDirectories bool
|
||||
showHiddenFiles bool
|
||||
window *Window
|
||||
|
||||
impl saveFileDialogImpl
|
||||
}
|
||||
|
||||
type saveFileDialogImpl interface {
|
||||
show() (string, error)
|
||||
}
|
||||
|
||||
func (d *SaveFileDialog) CanCreateDirectories(canCreateDirectories bool) *SaveFileDialog {
|
||||
d.canCreateDirectories = canCreateDirectories
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *SaveFileDialog) ShowHiddenFiles(showHiddenFiles bool) *SaveFileDialog {
|
||||
d.showHiddenFiles = showHiddenFiles
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *SaveFileDialog) AttachToWindow(window *Window) *SaveFileDialog {
|
||||
d.window = window
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *SaveFileDialog) PromptForSingleSelection() (string, error) {
|
||||
if d.impl == nil {
|
||||
d.impl = newSaveFileDialogImpl(d)
|
||||
}
|
||||
return d.impl.show()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package application
|
|||
|
||||
extern void openFileDialogCallback(uint id, char* path);
|
||||
extern void openFileDialogCallbackEnd(uint id);
|
||||
extern void saveFileDialogCallback(uint id, char* path);
|
||||
|
||||
static void showAboutBox(char* title, char *message, void *icon, int length) {
|
||||
|
||||
|
|
@ -146,6 +147,52 @@ static void showOpenFileDialog(unsigned int dialogID, bool canChooseFiles, bool
|
|||
});
|
||||
}
|
||||
|
||||
static void showSaveFileDialog(unsigned int dialogID, bool canCreateDirectories, bool showHiddenFiles, void *window) {
|
||||
// run on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
|
||||
[panel setCanCreateDirectories:canCreateDirectories];
|
||||
[panel setShowsHiddenFiles:showHiddenFiles];
|
||||
|
||||
//if (title != NULL) {
|
||||
// [panel setTitle:[NSString stringWithUTF8String:title]];
|
||||
// free(title);
|
||||
//}
|
||||
|
||||
//if (defaultFilename != NULL) {
|
||||
// [panel setNameFieldStringValue:[NSString stringWithUTF8String:defaultFilename]];
|
||||
// free(defaultFilename);
|
||||
//}
|
||||
//
|
||||
//if (defaultDirectory != NULL) {
|
||||
// [panel setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:defaultDirectory]]];
|
||||
// free(defaultDirectory);
|
||||
//}
|
||||
|
||||
if (window != NULL) {
|
||||
[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];
|
||||
}
|
||||
saveFileDialogCallback(dialogID, (char *)path);
|
||||
}];
|
||||
} else {
|
||||
[panel beginWithCompletionHandler:^(NSInteger result) {
|
||||
const char *path = NULL;
|
||||
if (result == NSModalResponseOK) {
|
||||
NSURL *url = [panel URL];
|
||||
const char *path = [[url path] UTF8String];
|
||||
}
|
||||
saveFileDialogCallback(dialogID, (char *)path);
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
|
|
@ -296,3 +343,40 @@ func openFileDialogCallbackEnd(id C.uint) {
|
|||
panic("No channel found for open file dialog")
|
||||
}
|
||||
}
|
||||
|
||||
type macosSaveFileDialog struct {
|
||||
dialog *SaveFileDialog
|
||||
}
|
||||
|
||||
func newSaveFileDialogImpl(d *SaveFileDialog) *macosSaveFileDialog {
|
||||
return &macosSaveFileDialog{
|
||||
dialog: d,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *macosSaveFileDialog) show() (string, error) {
|
||||
saveFileResponses[dialogID] = make(chan string)
|
||||
nsWindow := unsafe.Pointer(nil)
|
||||
if m.dialog.window != nil {
|
||||
// get NSWindow from window
|
||||
nsWindow = m.dialog.window.impl.(*macosWindow).nsWindow
|
||||
}
|
||||
C.showSaveFileDialog(C.uint(m.dialog.id),
|
||||
C.bool(m.dialog.canCreateDirectories),
|
||||
C.bool(m.dialog.showHiddenFiles),
|
||||
nsWindow)
|
||||
return <-saveFileResponses[m.dialog.id], nil
|
||||
}
|
||||
|
||||
//export saveFileDialogCallback
|
||||
func saveFileDialogCallback(id C.uint, path *C.char) {
|
||||
// Covert the path to a string
|
||||
filePath := C.GoString(path)
|
||||
// put response on channel
|
||||
channel, ok := saveFileResponses[uint(id)]
|
||||
if ok {
|
||||
channel <- filePath
|
||||
} else {
|
||||
panic("No channel found for save file dialog")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,15 @@ void* windowNew(unsigned int id, int width, int height) {
|
|||
return window;
|
||||
}
|
||||
|
||||
// setInvisibleTitleBarHeight sets the invisible title bar height
|
||||
void setInvisibleTitleBarHeight(void* window, unsigned int height) {
|
||||
NSWindow* nsWindow = (NSWindow*)window;
|
||||
// Get delegate
|
||||
WindowDelegate* delegate = (WindowDelegate*)[nsWindow delegate];
|
||||
// Set height
|
||||
delegate.invisibleTitleBarHeight = height;
|
||||
}
|
||||
|
||||
//// Make window toggle frameless
|
||||
//void windowSetFrameless(void* window, bool frameless) {
|
||||
// NSWindow* nsWindow = (NSWindow*)window;
|
||||
|
|
@ -81,6 +90,18 @@ void windowSetTransparent(void* nsWindow) {
|
|||
});
|
||||
}
|
||||
|
||||
void windowSetInvisibleTitleBar(void* nsWindow, unsigned int height) {
|
||||
// On main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSWindow* window = (NSWindow*)nsWindow;
|
||||
// Get delegate
|
||||
WindowDelegate* delegate = (WindowDelegate*)[window delegate];
|
||||
// Set height
|
||||
delegate.invisibleTitleBarHeight = height;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Set the title of the NSWindow
|
||||
void windowSetTitle(void* nsWindow, char* title) {
|
||||
// Set window title on main thread
|
||||
|
|
@ -407,7 +428,7 @@ void windowSetHideTitle(void* nsWindow, bool hideTitle) {
|
|||
}
|
||||
|
||||
// Set Window use toolbar
|
||||
void windowSetUseToolbar(void* nsWindow, bool useToolbar) {
|
||||
void windowSetUseToolbar(void* nsWindow, bool useToolbar, int toolbarStyle) {
|
||||
// Set window use toolbar on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// get main window
|
||||
|
|
@ -416,12 +437,35 @@ void windowSetUseToolbar(void* nsWindow, bool useToolbar) {
|
|||
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"wails.toolbar"];
|
||||
[toolbar autorelease];
|
||||
[window setToolbar:toolbar];
|
||||
|
||||
// If macos 11 or higher, set toolbar style
|
||||
if (@available(macOS 11.0, *)) {
|
||||
[window setToolbarStyle:toolbarStyle];
|
||||
}
|
||||
|
||||
} else {
|
||||
[window setToolbar:nil];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set window toolbar style
|
||||
void windowSetToolbarStyle(void* nsWindow, int style) {
|
||||
// use @available to check if the function is available
|
||||
// if not, return
|
||||
if (@available(macOS 11.0, *)) {
|
||||
// Set window toolbar style on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// get main window
|
||||
NSWindow* window = (NSWindow*)nsWindow;
|
||||
// get toolbar
|
||||
NSToolbar* toolbar = [window toolbar];
|
||||
// set toolbar style
|
||||
[toolbar setShowsBaselineSeparator:style];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Set Hide Toolbar Separator
|
||||
void windowSetHideToolbarSeparator(void* nsWindow, bool hideSeparator) {
|
||||
// Set window hide toolbar separator on main thread
|
||||
|
|
@ -808,7 +852,9 @@ func (w *macosWindow) run() {
|
|||
C.windowSetHideTitleBar(w.nsWindow, C.bool(titleBarOptions.Hide))
|
||||
C.windowSetHideTitle(w.nsWindow, C.bool(titleBarOptions.HideTitle))
|
||||
C.windowSetFullSizeContent(w.nsWindow, C.bool(titleBarOptions.FullSizeContent))
|
||||
C.windowSetUseToolbar(w.nsWindow, C.bool(titleBarOptions.UseToolbar))
|
||||
if titleBarOptions.UseToolbar {
|
||||
C.windowSetUseToolbar(w.nsWindow, C.bool(titleBarOptions.UseToolbar), C.int(titleBarOptions.ToolbarStyle))
|
||||
}
|
||||
C.windowSetHideToolbarSeparator(w.nsWindow, C.bool(titleBarOptions.HideToolbarSeparator))
|
||||
}
|
||||
|
||||
|
|
@ -816,15 +862,18 @@ func (w *macosWindow) run() {
|
|||
C.windowSetAppearanceTypeByName(w.nsWindow, C.CString(string(macOptions.Appearance)))
|
||||
}
|
||||
|
||||
switch w.parent.options.StartState {
|
||||
case options.WindowStateMaximised:
|
||||
w.setMaximised()
|
||||
case options.WindowStateMinimised:
|
||||
w.setMinimised()
|
||||
case options.WindowStateFullscreen:
|
||||
w.setFullscreen()
|
||||
|
||||
if macOptions.InvisibleTitleBarHeight != 0 {
|
||||
C.windowSetInvisibleTitleBar(w.nsWindow, C.uint(macOptions.InvisibleTitleBarHeight))
|
||||
}
|
||||
}
|
||||
|
||||
switch w.parent.options.StartState {
|
||||
case options.WindowStateMaximised:
|
||||
w.setMaximised()
|
||||
case options.WindowStateMinimised:
|
||||
w.setMinimised()
|
||||
case options.WindowStateFullscreen:
|
||||
w.setFullscreen()
|
||||
|
||||
}
|
||||
C.windowCenter(w.nsWindow)
|
||||
|
|
@ -832,7 +881,7 @@ func (w *macosWindow) run() {
|
|||
if w.parent.options.URL != "" {
|
||||
w.navigateToURL(w.parent.options.URL)
|
||||
}
|
||||
// Ee need to wait for the HTML to load before we can execute the javascript
|
||||
// We need to wait for the HTML to load before we can execute the javascript
|
||||
w.parent.On(events.Mac.WebViewDidFinishNavigation, func() {
|
||||
if w.parent.options.JS != "" {
|
||||
w.execJS(w.parent.options.JS)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@
|
|||
@property bool hideOnClose;
|
||||
@property (retain) WKWebView* webView;
|
||||
@property unsigned int windowId;
|
||||
@property (retain) NSEvent* leftMouseEvent;
|
||||
@property unsigned int invisibleTitleBarHeight;
|
||||
|
||||
- (void)handleLeftMouseUp:(NSWindow *)window;
|
||||
- (void)handleLeftMouseDown:(NSEvent*)event;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,26 @@ extern void processMessage(unsigned int, const char*);
|
|||
processMessage(self.windowId, _m);
|
||||
}
|
||||
|
||||
- (void) mouseDown:(NSEvent*)someEvent {
|
||||
NSLog(@"MOUSE DOWN!!!");
|
||||
- (void)handleLeftMouseDown:(NSEvent *)event {
|
||||
self.leftMouseEvent = event;
|
||||
NSWindow *window = [event window];
|
||||
WindowDelegate* delegate = (WindowDelegate*)[window delegate];
|
||||
|
||||
if( self.invisibleTitleBarHeight > 0 ) {
|
||||
NSPoint location = [event locationInWindow];
|
||||
NSRect frame = [window frame];
|
||||
if( location.y > frame.size.height - self.invisibleTitleBarHeight ) {
|
||||
[window performWindowDragWithEvent:event];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleLeftMouseUp:(NSWindow *)window {
|
||||
self.leftMouseEvent = nil;
|
||||
}
|
||||
|
||||
|
||||
// GENERATED EVENTS START
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
||||
processWindowEvent(self.windowId, EventWindowDidBecomeKey);
|
||||
|
|
|
|||
|
|
@ -24,11 +24,6 @@ void showDevTools(void *window) {
|
|||
WindowDelegate* delegate = (WindowDelegate*)[(NSWindow*)window delegate];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[delegate.webView._inspector show];
|
||||
//dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
|
||||
//dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
||||
// // Detach must be deferred a little bit and is ignored directly after a show.
|
||||
// [delegate.webView._inspector detach];
|
||||
//});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,27 @@ const (
|
|||
MacBackdropTranslucent
|
||||
)
|
||||
|
||||
type MacToolbarStyle int
|
||||
|
||||
const (
|
||||
// MacToolbarStyleAutomatic - The default value. The style will be determined by the window's given configuration
|
||||
MacToolbarStyleAutomatic MacToolbarStyle = iota
|
||||
// MacToolbarStyleExpanded - The toolbar will appear below the window title
|
||||
MacToolbarStyleExpanded
|
||||
// MacToolbarStylePreference - The toolbar will appear below the window title and the items in the toolbar will attempt to have equal widths when possible
|
||||
MacToolbarStylePreference
|
||||
// MacToolbarStyleUnified - The window title will appear inline with the toolbar when visible
|
||||
MacToolbarStyleUnified
|
||||
// MacToolbarStyleUnifiedCompact - Same as MacToolbarStyleUnified, but with reduced margins in the toolbar allowing more focus to be on the contents of the window
|
||||
MacToolbarStyleUnifiedCompact
|
||||
)
|
||||
|
||||
// MacWindow contains macOS specific options
|
||||
type MacWindow struct {
|
||||
Backdrop MacBackdrop
|
||||
TitleBar *TitleBar
|
||||
Appearance MacAppearanceType
|
||||
Backdrop MacBackdrop
|
||||
TitleBar *TitleBar
|
||||
Appearance MacAppearanceType
|
||||
InvisibleTitleBarHeight int
|
||||
}
|
||||
|
||||
// TitleBar contains options for the Mac titlebar
|
||||
|
|
@ -37,9 +53,10 @@ type TitleBar struct {
|
|||
FullSizeContent bool
|
||||
UseToolbar bool
|
||||
HideToolbarSeparator bool
|
||||
ToolbarStyle MacToolbarStyle
|
||||
}
|
||||
|
||||
// TitleBarDefault results in the default Mac Titlebar
|
||||
// TitleBarDefault results in the default Mac TitleBar
|
||||
var TitleBarDefault = &TitleBar{
|
||||
AppearsTransparent: false,
|
||||
Hide: false,
|
||||
|
|
@ -74,6 +91,18 @@ var TitleBarHiddenInset = &TitleBar{
|
|||
HideToolbarSeparator: true,
|
||||
}
|
||||
|
||||
// TitleBarHiddenInsetUnified results in a hidden title bar with an alternative look where
|
||||
// the traffic light buttons are even more inset from the window edge.
|
||||
var TitleBarHiddenInsetUnified = &TitleBar{
|
||||
AppearsTransparent: true,
|
||||
Hide: false,
|
||||
HideTitle: true,
|
||||
FullSizeContent: true,
|
||||
UseToolbar: true,
|
||||
HideToolbarSeparator: true,
|
||||
ToolbarStyle: MacToolbarStyleUnified,
|
||||
}
|
||||
|
||||
// MacAppearanceType is a type of Appearance for Cocoa windows
|
||||
type MacAppearanceType string
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue