mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 13:19:00 -07:00
Compare commits
13 Commits
v2.0.0-alp
...
v2.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d923e84456 | ||
|
|
343f573e78 | ||
|
|
c6d87da4f0 | ||
|
|
a9faebe51a | ||
|
|
d436f5d1be | ||
|
|
f40899821f | ||
|
|
2a64ed19a3 | ||
|
|
47bca0be88 | ||
|
|
7ac8cc6b8b | ||
|
|
b435ec1217 | ||
|
|
688d4fee6a | ||
|
|
29ffeaa9f3 | ||
|
|
742e4ba2cb |
@@ -1,3 +1,3 @@
|
||||
package main
|
||||
|
||||
var version = "v2.0.0-alpha.9"
|
||||
var version = "v2.0.0-alpha.14"
|
||||
|
||||
@@ -43,6 +43,10 @@ type App struct {
|
||||
// Application Stores
|
||||
loglevelStore *runtime.Store
|
||||
appconfigStore *runtime.Store
|
||||
|
||||
// Startup/Shutdown
|
||||
startupCallback func(*runtime.Runtime)
|
||||
shutdownCallback func()
|
||||
}
|
||||
|
||||
// Create App
|
||||
@@ -76,11 +80,13 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
window := ffenestri.NewApplicationWithConfig(appoptions, myLogger, menuManager)
|
||||
|
||||
result := &App{
|
||||
window: window,
|
||||
servicebus: servicebus.New(myLogger),
|
||||
logger: myLogger,
|
||||
bindings: binding.NewBindings(myLogger),
|
||||
menuManager: menuManager,
|
||||
window: window,
|
||||
servicebus: servicebus.New(myLogger),
|
||||
logger: myLogger,
|
||||
bindings: binding.NewBindings(myLogger),
|
||||
menuManager: menuManager,
|
||||
startupCallback: appoptions.Startup,
|
||||
shutdownCallback: appoptions.Shutdown,
|
||||
}
|
||||
|
||||
result.options = appoptions
|
||||
@@ -112,7 +118,7 @@ func (a *App) Run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
runtimesubsystem, err := subsystem.NewRuntime(a.servicebus, a.logger)
|
||||
runtimesubsystem, err := subsystem.NewRuntime(a.servicebus, a.logger, a.startupCallback, a.shutdownCallback)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -34,26 +34,6 @@ func (b *Bindings) Add(structPtr interface{}) error {
|
||||
structName := splitName[1]
|
||||
methodName := splitName[2]
|
||||
|
||||
// Is this WailsInit?
|
||||
if method.IsWailsInit() {
|
||||
err := b.db.AddWailsInit(method)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.logger.Trace("Registered WailsInit method: %s", method.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// Is this WailsShutdown?
|
||||
if method.IsWailsShutdown() {
|
||||
err := b.db.AddWailsShutdown(method)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.logger.Trace("Registered WailsShutdown method: %s", method.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// Add it as a regular method
|
||||
b.db.AddMethod(packageName, structName, methodName, method)
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BoundMethod defines all the data related to a Go method that is
|
||||
@@ -17,58 +16,6 @@ type BoundMethod struct {
|
||||
Method reflect.Value `json:"-"`
|
||||
}
|
||||
|
||||
// IsWailsInit returns true if the method name is "WailsInit"
|
||||
func (b *BoundMethod) IsWailsInit() bool {
|
||||
return strings.HasSuffix(b.Name, "WailsInit")
|
||||
}
|
||||
|
||||
// IsWailsShutdown returns true if the method name is "WailsShutdown"
|
||||
func (b *BoundMethod) IsWailsShutdown() bool {
|
||||
return strings.HasSuffix(b.Name, "WailsShutdown")
|
||||
}
|
||||
|
||||
// VerifyWailsInit checks if the WailsInit signature is correct
|
||||
func (b *BoundMethod) VerifyWailsInit() error {
|
||||
// Must only have 1 input
|
||||
if b.InputCount() != 1 {
|
||||
return fmt.Errorf("invalid method signature for %s: expected `WailsInit(*wails.Runtime) error`", b.Name)
|
||||
}
|
||||
|
||||
// Check input type
|
||||
if !b.Inputs[0].IsType("*runtime.Runtime") {
|
||||
return fmt.Errorf("invalid method signature for %s: expected `WailsInit(*wails.Runtime) error`", b.Name)
|
||||
}
|
||||
|
||||
// Must only have 1 output
|
||||
if b.OutputCount() != 1 {
|
||||
return fmt.Errorf("invalid method signature for %s: expected `WailsInit(*wails.Runtime) error`", b.Name)
|
||||
}
|
||||
|
||||
// Check output type
|
||||
if !b.Outputs[0].IsError() {
|
||||
return fmt.Errorf("invalid method signature for %s: expected `WailsInit(*wails.Runtime) error`", b.Name)
|
||||
}
|
||||
|
||||
// Input must be of type Runtime
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyWailsShutdown checks if the WailsShutdown signature is correct
|
||||
func (b *BoundMethod) VerifyWailsShutdown() error {
|
||||
// Must have no inputs
|
||||
if b.InputCount() != 0 {
|
||||
return fmt.Errorf("invalid method signature for WailsShutdown: expected `WailsShutdown()`")
|
||||
}
|
||||
|
||||
// Must have no outputs
|
||||
if b.OutputCount() != 0 {
|
||||
return fmt.Errorf("invalid method signature for WailsShutdown: expected `WailsShutdown()`")
|
||||
}
|
||||
|
||||
// Input must be of type Runtime
|
||||
return nil
|
||||
}
|
||||
|
||||
// InputCount returns the number of inputs this bound method has
|
||||
func (b *BoundMethod) InputCount() int {
|
||||
return len(b.Inputs)
|
||||
|
||||
@@ -15,10 +15,6 @@ type DB struct {
|
||||
// It used for performance gains at runtime
|
||||
methodMap map[string]*BoundMethod
|
||||
|
||||
// These are slices of methods registered using WailsInit and WailsShutdown
|
||||
wailsInitMethods []*BoundMethod
|
||||
wailsShutdownMethods []*BoundMethod
|
||||
|
||||
// Lock to ensure sync access to the data
|
||||
lock sync.RWMutex
|
||||
}
|
||||
@@ -94,38 +90,6 @@ func (d *DB) AddMethod(packageName string, structName string, methodName string,
|
||||
|
||||
}
|
||||
|
||||
// AddWailsInit checks the given method is a WailsInit method and if it
|
||||
// is, adds it to the list of WailsInit methods
|
||||
func (d *DB) AddWailsInit(method *BoundMethod) error {
|
||||
err := method.VerifyWailsInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Lock the db whilst processing and unlock on return
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
d.wailsInitMethods = append(d.wailsInitMethods, method)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddWailsShutdown checks the given method is a WailsInit method and if it
|
||||
// is, adds it to the list of WailsShutdown methods
|
||||
func (d *DB) AddWailsShutdown(method *BoundMethod) error {
|
||||
err := method.VerifyWailsShutdown()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Lock the db whilst processing and unlock on return
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
d.wailsShutdownMethods = append(d.wailsShutdownMethods, method)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToJSON converts the method map to JSON
|
||||
func (d *DB) ToJSON() (string, error) {
|
||||
|
||||
@@ -138,13 +102,3 @@ func (d *DB) ToJSON() (string, error) {
|
||||
// Return zero copy string as this string will be read only
|
||||
return *(*string)(unsafe.Pointer(&bytes)), err
|
||||
}
|
||||
|
||||
// WailsInitMethods returns the list of registered WailsInit methods
|
||||
func (d *DB) WailsInitMethods() []*BoundMethod {
|
||||
return d.wailsInitMethods
|
||||
}
|
||||
|
||||
// WailsShutdownMethods returns the list of registered WailsInit methods
|
||||
func (d *DB) WailsShutdownMethods() []*BoundMethod {
|
||||
return d.wailsShutdownMethods
|
||||
}
|
||||
|
||||
@@ -86,3 +86,10 @@ bool getJSONInt(JsonNode *item, const char* key, int *result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonNode* mustParseJSON(const char* JSON) {
|
||||
JsonNode* parsedUpdate = json_decode(JSON);
|
||||
if ( parsedUpdate == NULL ) {
|
||||
ABORT("Unable to decode JSON: %s\n", JSON);
|
||||
}
|
||||
return parsedUpdate;
|
||||
}
|
||||
@@ -35,4 +35,6 @@ JsonNode* mustJSONObject(JsonNode *node, const char* key);
|
||||
bool getJSONBool(JsonNode *item, const char* key, bool *result);
|
||||
bool getJSONInt(JsonNode *item, const char* key, int *result);
|
||||
|
||||
JsonNode* mustParseJSON(const char* JSON);
|
||||
|
||||
#endif //ASSETS_C_COMMON_H
|
||||
|
||||
@@ -36,7 +36,8 @@ extern void MessageDialog(struct Application*, char *callbackID, char *type, cha
|
||||
extern void DarkModeEnabled(struct Application*, char *callbackID);
|
||||
extern void SetApplicationMenu(struct Application*, const char *);
|
||||
extern void AddTrayMenu(struct Application*, const char *menuTrayJSON);
|
||||
extern void UpdateTrayMenu(struct Application*, const char *menuTrayJSON);
|
||||
extern void SetTrayMenu(struct Application*, const char *menuTrayJSON);
|
||||
extern void UpdateTrayMenuLabel(struct Application*, const char* JSON);
|
||||
extern void AddContextMenu(struct Application*, char *contextMenuJSON);
|
||||
extern void UpdateContextMenu(struct Application*, char *contextMenuJSON);
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ package ffenestri
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"strconv"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
// Client is our implentation of messageDispatcher.Client
|
||||
@@ -120,7 +120,7 @@ func (c *Client) WindowSetColour(colour int) {
|
||||
}
|
||||
|
||||
// OpenDialog will open a dialog with the given title and filter
|
||||
func (c *Client) OpenDialog(dialogOptions *options.OpenDialog, callbackID string) {
|
||||
func (c *Client) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
||||
C.OpenDialog(c.app.app,
|
||||
c.app.string2CString(callbackID),
|
||||
c.app.string2CString(dialogOptions.Title),
|
||||
@@ -138,7 +138,7 @@ func (c *Client) OpenDialog(dialogOptions *options.OpenDialog, callbackID string
|
||||
}
|
||||
|
||||
// SaveDialog will open a dialog with the given title and filter
|
||||
func (c *Client) SaveDialog(dialogOptions *options.SaveDialog, callbackID string) {
|
||||
func (c *Client) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
||||
C.SaveDialog(c.app.app,
|
||||
c.app.string2CString(callbackID),
|
||||
c.app.string2CString(dialogOptions.Title),
|
||||
@@ -152,7 +152,7 @@ func (c *Client) SaveDialog(dialogOptions *options.SaveDialog, callbackID string
|
||||
}
|
||||
|
||||
// MessageDialog will open a message dialog with the given options
|
||||
func (c *Client) MessageDialog(dialogOptions *options.MessageDialog, callbackID string) {
|
||||
func (c *Client) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
||||
|
||||
// Sanity check button length
|
||||
if len(dialogOptions.Buttons) > 4 {
|
||||
@@ -188,8 +188,12 @@ func (c *Client) SetApplicationMenu(applicationMenuJSON string) {
|
||||
C.SetApplicationMenu(c.app.app, c.app.string2CString(applicationMenuJSON))
|
||||
}
|
||||
|
||||
func (c *Client) UpdateTrayMenu(trayMenuJSON string) {
|
||||
C.UpdateTrayMenu(c.app.app, c.app.string2CString(trayMenuJSON))
|
||||
func (c *Client) SetTrayMenu(trayMenuJSON string) {
|
||||
C.SetTrayMenu(c.app.app, c.app.string2CString(trayMenuJSON))
|
||||
}
|
||||
|
||||
func (c *Client) UpdateTrayMenuLabel(JSON string) {
|
||||
C.UpdateTrayMenuLabel(c.app.app, c.app.string2CString(JSON))
|
||||
}
|
||||
|
||||
func (c *Client) UpdateContextMenu(contextMenuJSON string) {
|
||||
|
||||
@@ -21,10 +21,6 @@ int debug;
|
||||
// A cache for all our dialog icons
|
||||
struct hashmap_s dialogIconCache;
|
||||
|
||||
// Context menu data is given by the frontend when clicking a context menu.
|
||||
// We send this to the backend when an item is selected;
|
||||
const char *contextMenuData;
|
||||
|
||||
// Dispatch Method
|
||||
typedef void (^dispatchMethod)(void);
|
||||
|
||||
@@ -255,6 +251,10 @@ void messageHandler(id self, SEL cmd, id contentController, id message) {
|
||||
|
||||
// TODO: Check this actually does reduce flicker
|
||||
msg(app->config, s("setValue:forKey:"), msg(c("NSNumber"), s("numberWithBool:"), 0), str("suppressesIncrementalRendering"));
|
||||
|
||||
// Notify backend we are ready (system startup)
|
||||
app->sendMessageToBackend("SS");
|
||||
|
||||
} else if( strcmp(name, "windowDrag") == 0 ) {
|
||||
// Guard against null events
|
||||
if( app->mouseEvent != NULL ) {
|
||||
@@ -633,6 +633,8 @@ extern void MessageDialog(struct Application *app, char *callbackID, char *type,
|
||||
dialogIcon = icon;
|
||||
}
|
||||
|
||||
// TODO: move dialog icons + methods to own file
|
||||
|
||||
// Determine what dialog icon we are looking for
|
||||
id dialogImage = NULL;
|
||||
// Look for `name-theme2x` first
|
||||
@@ -911,7 +913,8 @@ void SetDebug(void *applicationPointer, int flag) {
|
||||
}
|
||||
|
||||
|
||||
// SetContextMenus sets the context menu map for this application
|
||||
|
||||
// AddContextMenu sets the context menu map for this application
|
||||
void AddContextMenu(struct Application *app, const char *contextMenuJSON) {
|
||||
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
|
||||
}
|
||||
@@ -924,10 +927,19 @@ void AddTrayMenu(struct Application *app, const char *trayMenuJSON) {
|
||||
AddTrayMenuToStore(app->trayMenuStore, trayMenuJSON);
|
||||
}
|
||||
|
||||
void UpdateTrayMenu(struct Application *app, const char* trayMenuJSON) {
|
||||
UpdateTrayMenuInStore(app->trayMenuStore, trayMenuJSON);
|
||||
void SetTrayMenu(struct Application *app, const char* trayMenuJSON) {
|
||||
ON_MAIN_THREAD(
|
||||
UpdateTrayMenuInStore(app->trayMenuStore, trayMenuJSON);
|
||||
);
|
||||
}
|
||||
|
||||
void UpdateTrayMenuLabel(struct Application* app, const char* JSON) {
|
||||
ON_MAIN_THREAD(
|
||||
UpdateTrayMenuLabelInStore(app->trayMenuStore, JSON);
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void SetBindings(struct Application *app, const char *bindings) {
|
||||
const char* temp = concat("window.wailsbindings = \"", bindings);
|
||||
const char* jscall = concat(temp, "\";");
|
||||
@@ -1501,6 +1513,9 @@ void Run(struct Application *app, int argc, char **argv) {
|
||||
makeWindowBackgroundTranslucent(app);
|
||||
}
|
||||
|
||||
// We set it to be invisible by default. It will become visible when everything has initialised
|
||||
msg(app->mainWindow, s("setIsVisible:"), NO);
|
||||
|
||||
// Setup webview
|
||||
id config = msg(c("WKWebViewConfiguration"), s("new"));
|
||||
msg(config, s("setValue:forKey:"), msg(c("NSNumber"), s("numberWithBool:"), 1), str("suppressesIncrementalRendering"));
|
||||
@@ -1651,9 +1666,6 @@ void Run(struct Application *app, int argc, char **argv) {
|
||||
// Process dialog icons
|
||||
processUserDialogIcons(app);
|
||||
|
||||
// We set it to be invisible by default. It will become visible when everything has initialised
|
||||
msg(app->mainWindow, s("setIsVisible:"), NO);
|
||||
|
||||
// Finally call run
|
||||
Debug(app, "Run called");
|
||||
msg(app->application, s("run"));
|
||||
|
||||
@@ -107,7 +107,7 @@ void SetAppearance(struct Application* app, const char *);
|
||||
void WebviewIsTransparent(struct Application* app);
|
||||
void WindowBackgroundIsTranslucent(struct Application* app);
|
||||
void SetTray(struct Application* app, const char *, const char *, const char *);
|
||||
void SetContextMenus(struct Application* app, const char *);
|
||||
//void SetContextMenus(struct Application* app, const char *);
|
||||
void AddTrayMenu(struct Application* app, const char *);
|
||||
|
||||
#endif
|
||||
@@ -63,8 +63,6 @@ MenuItemCallbackData* CreateMenuItemCallbackData(Menu *menu, id menuItem, const
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DeleteMenu(Menu *menu) {
|
||||
|
||||
// Free menu item hashmap
|
||||
@@ -99,7 +97,11 @@ void DeleteMenu(Menu *menu) {
|
||||
|
||||
// Creates a JSON message for the given menuItemID and data
|
||||
const char* createMenuClickedMessage(const char *menuItemID, const char *data, enum MenuType menuType, const char *parentID) {
|
||||
|
||||
JsonNode *jsonObject = json_mkobject();
|
||||
if (menuItemID == NULL ) {
|
||||
ABORT("Item ID NULL for menu!!\n");
|
||||
}
|
||||
json_append_member(jsonObject, "menuItemID", json_mkstring(menuItemID));
|
||||
json_append_member(jsonObject, "menuType", json_mkstring(MenuTypeAsString[(int)menuType]));
|
||||
if (data != NULL) {
|
||||
@@ -572,7 +574,7 @@ id processCheckboxMenuItem(Menu *menu, id parentmenu, const char *title, const c
|
||||
return item;
|
||||
}
|
||||
|
||||
id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers) {
|
||||
id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers, const char* tooltip, const char* image) {
|
||||
id item = ALLOC("NSMenuItem");
|
||||
|
||||
// Create a MenuItemCallbackData
|
||||
@@ -585,6 +587,18 @@ id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char
|
||||
msg(item, s("initWithTitle:action:keyEquivalent:"), str(title),
|
||||
s("menuItemCallback:"), key);
|
||||
|
||||
if( tooltip != NULL ) {
|
||||
msg(item, s("setToolTip:"), str(tooltip));
|
||||
}
|
||||
|
||||
if( image != NULL && strlen(image) > 0) {
|
||||
id data = ALLOC("NSData");
|
||||
id imageData = msg(data, s("initWithBase64EncodedString:options:"), str(image), 0);
|
||||
id nsimage = ALLOC("NSImage");
|
||||
msg(nsimage, s("initWithData:"), imageData);
|
||||
msg(item, s("setImage:"), nsimage);
|
||||
}
|
||||
|
||||
msg(item, s("setEnabled:"), !disabled);
|
||||
msg(item, s("autorelease"));
|
||||
|
||||
@@ -666,6 +680,9 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
||||
const char *acceleratorkey = NULL;
|
||||
const char **modifiers = NULL;
|
||||
|
||||
const char *tooltip = getJSONString(item, "Tooltip");
|
||||
const char *image = getJSONString(item, "Image");
|
||||
|
||||
// If we have an accelerator
|
||||
if( accelerator != NULL ) {
|
||||
// Get the key
|
||||
@@ -698,7 +715,7 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
||||
if( type != NULL ) {
|
||||
|
||||
if( STREQ(type->string_, "Text")) {
|
||||
processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers);
|
||||
processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image);
|
||||
}
|
||||
else if ( STREQ(type->string_, "Separator")) {
|
||||
addSeparator(parentMenu);
|
||||
|
||||
@@ -90,7 +90,7 @@ id processRadioMenuItem(Menu *menu, id parentmenu, const char *title, const char
|
||||
|
||||
id processCheckboxMenuItem(Menu *menu, id parentmenu, const char *title, const char *menuid, bool disabled, bool checked, const char *key);
|
||||
|
||||
id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers);
|
||||
id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers, const char* tooltip, const char* image);
|
||||
|
||||
void processMenuItem(Menu *menu, id parentMenu, JsonNode *item);
|
||||
void processMenuData(Menu *menu, JsonNode *menuData);
|
||||
|
||||
@@ -49,42 +49,19 @@ void DumpTrayMenu(TrayMenu* trayMenu) {
|
||||
printf(" ['%s':%p] = { label: '%s', icon: '%s', menu: %p, statusbar: %p }\n", trayMenu->ID, trayMenu, trayMenu->label, trayMenu->icon, trayMenu->menu, trayMenu->statusbaritem );
|
||||
}
|
||||
|
||||
void ShowTrayMenu(TrayMenu* trayMenu) {
|
||||
|
||||
// Create a status bar item if we don't have one
|
||||
if( trayMenu->statusbaritem == NULL ) {
|
||||
id statusBar = msg( c("NSStatusBar"), s("systemStatusBar") );
|
||||
trayMenu->statusbaritem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength);
|
||||
msg(trayMenu->statusbaritem, s("retain"));
|
||||
|
||||
}
|
||||
|
||||
id statusBarButton = msg(trayMenu->statusbaritem, s("button"));
|
||||
msg(statusBarButton, s("setImagePosition:"), trayMenu->trayIconPosition);
|
||||
|
||||
// Update the icon if needed
|
||||
UpdateTrayMenuIcon(trayMenu);
|
||||
|
||||
// Update the label if needed
|
||||
UpdateTrayMenuLabel(trayMenu);
|
||||
|
||||
// Update the menu
|
||||
id menu = GetMenu(trayMenu->menu);
|
||||
msg(trayMenu->statusbaritem, s("setMenu:"), menu);
|
||||
}
|
||||
|
||||
void UpdateTrayMenuLabel(TrayMenu *trayMenu) {
|
||||
void UpdateTrayLabel(TrayMenu *trayMenu, const char *label) {
|
||||
|
||||
// Exit early if NULL
|
||||
if( trayMenu->label == NULL ) {
|
||||
return;
|
||||
}
|
||||
// We don't check for a
|
||||
// Update button label
|
||||
id statusBarButton = msg(trayMenu->statusbaritem, s("button"));
|
||||
msg(statusBarButton, s("setTitle:"), str(trayMenu->label));
|
||||
msg(statusBarButton, s("setTitle:"), str(label));
|
||||
}
|
||||
|
||||
void UpdateTrayMenuIcon(TrayMenu *trayMenu) {
|
||||
void UpdateTrayIcon(TrayMenu *trayMenu) {
|
||||
|
||||
// Exit early if NULL
|
||||
if( trayMenu->icon == NULL ) {
|
||||
@@ -105,6 +82,32 @@ void UpdateTrayMenuIcon(TrayMenu *trayMenu) {
|
||||
msg(statusBarButton, s("setImage:"), trayImage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ShowTrayMenu(TrayMenu* trayMenu) {
|
||||
|
||||
// Create a status bar item if we don't have one
|
||||
if( trayMenu->statusbaritem == NULL ) {
|
||||
id statusBar = msg( c("NSStatusBar"), s("systemStatusBar") );
|
||||
trayMenu->statusbaritem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength);
|
||||
msg(trayMenu->statusbaritem, s("retain"));
|
||||
|
||||
}
|
||||
|
||||
id statusBarButton = msg(trayMenu->statusbaritem, s("button"));
|
||||
msg(statusBarButton, s("setImagePosition:"), trayMenu->trayIconPosition);
|
||||
|
||||
// Update the icon if needed
|
||||
UpdateTrayIcon(trayMenu);
|
||||
|
||||
// Update the label if needed
|
||||
UpdateTrayLabel(trayMenu, trayMenu->label);
|
||||
|
||||
// Update the menu
|
||||
id menu = GetMenu(trayMenu->menu);
|
||||
msg(trayMenu->statusbaritem, s("setMenu:"), menu);
|
||||
}
|
||||
|
||||
// UpdateTrayMenuInPlace receives 2 menus. The current menu gets
|
||||
// updated with the data from the new menu.
|
||||
void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu) {
|
||||
|
||||
@@ -27,8 +27,8 @@ TrayMenu* NewTrayMenu(const char *trayJSON);
|
||||
void DumpTrayMenu(TrayMenu* trayMenu);
|
||||
void ShowTrayMenu(TrayMenu* trayMenu);
|
||||
void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu);
|
||||
void UpdateTrayMenuIcon(TrayMenu *trayMenu);
|
||||
void UpdateTrayMenuLabel(TrayMenu *trayMenu);
|
||||
void UpdateTrayIcon(TrayMenu *trayMenu);
|
||||
void UpdateTrayLabel(TrayMenu *trayMenu, const char*);
|
||||
|
||||
void LoadTrayIcons();
|
||||
void UnloadTrayIcons();
|
||||
|
||||
@@ -72,14 +72,47 @@ TrayMenu* GetTrayMenuFromStore(TrayMenuStore* store, const char* menuID) {
|
||||
return hashmap_get(&store->trayMenuMap, menuID, strlen(menuID));
|
||||
}
|
||||
|
||||
TrayMenu* MustGetTrayMenuFromStore(TrayMenuStore* store, const char* menuID) {
|
||||
// Get the current menu
|
||||
TrayMenu* result = hashmap_get(&store->trayMenuMap, menuID, strlen(menuID));
|
||||
if (result == NULL ) {
|
||||
ABORT("Unable to find TrayMenu with ID '%s' in the TrayMenuStore!", menuID);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void UpdateTrayMenuLabelInStore(TrayMenuStore* store, const char* JSON) {
|
||||
// Parse the JSON
|
||||
JsonNode *parsedUpdate = mustParseJSON(JSON);
|
||||
|
||||
// Get the data out
|
||||
const char* ID = mustJSONString(parsedUpdate, "ID");
|
||||
const char* Label = mustJSONString(parsedUpdate, "Label");
|
||||
|
||||
// Check we have this menu
|
||||
TrayMenu *menu = MustGetTrayMenuFromStore(store, ID);
|
||||
UpdateTrayLabel(menu, Label);
|
||||
|
||||
}
|
||||
|
||||
void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON) {
|
||||
TrayMenu* newMenu = NewTrayMenu(menuJSON);
|
||||
DumpTrayMenu(newMenu);
|
||||
|
||||
// Get the current menu
|
||||
TrayMenu *currentMenu = GetTrayMenuFromStore(store, newMenu->ID);
|
||||
|
||||
// If we don't have a menu, we create one
|
||||
if ( currentMenu == NULL ) {
|
||||
ABORT("Attempted to update unknown tray menu with ID '%s'.", newMenu->ID);
|
||||
printf(" currentMenu = NULL\n");
|
||||
// Store the new menu
|
||||
hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
|
||||
|
||||
// Show it
|
||||
ShowTrayMenu(newMenu);
|
||||
return;
|
||||
}
|
||||
DumpTrayMenu(currentMenu);
|
||||
|
||||
// Save the status bar reference
|
||||
newMenu->statusbaritem = currentMenu->statusbaritem;
|
||||
@@ -90,12 +123,6 @@ void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON) {
|
||||
DeleteMenu(currentMenu->menu);
|
||||
currentMenu->menu = NULL;
|
||||
|
||||
// Free JSON
|
||||
if (currentMenu->processedJSON != NULL ) {
|
||||
json_delete(currentMenu->processedJSON);
|
||||
currentMenu->processedJSON = NULL;
|
||||
}
|
||||
|
||||
// Free the tray menu memory
|
||||
MEMFREE(currentMenu);
|
||||
|
||||
|
||||
@@ -22,4 +22,6 @@ void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON);
|
||||
void ShowTrayMenusInStore(TrayMenuStore* store);
|
||||
void DeleteTrayMenuStore(TrayMenuStore* store);
|
||||
|
||||
void UpdateTrayMenuLabelInStore(TrayMenuStore* store, const char* JSON);
|
||||
|
||||
#endif //TRAYMENUSTORE_DARWIN_H
|
||||
|
||||
@@ -26,6 +26,9 @@ func NewMenuItemMap() *MenuItemMap {
|
||||
}
|
||||
|
||||
func (m *MenuItemMap) AddMenu(menu *menu.Menu) {
|
||||
if menu == nil {
|
||||
return
|
||||
}
|
||||
for _, item := range menu.Items {
|
||||
m.processMenuItem(item)
|
||||
}
|
||||
|
||||
@@ -9,28 +9,35 @@ import (
|
||||
type ProcessedMenuItem struct {
|
||||
ID string
|
||||
// Label is what appears as the menu text
|
||||
Label string
|
||||
Label string `json:",omitempty"`
|
||||
// Role is a predefined menu type
|
||||
Role menu.Role `json:"Role,omitempty"`
|
||||
Role menu.Role `json:",omitempty"`
|
||||
// Accelerator holds a representation of a key binding
|
||||
Accelerator *keys.Accelerator `json:"Accelerator,omitempty"`
|
||||
Accelerator *keys.Accelerator `json:",omitempty"`
|
||||
// Type of MenuItem, EG: Checkbox, Text, Separator, Radio, Submenu
|
||||
Type menu.Type
|
||||
// Disabled makes the item unselectable
|
||||
Disabled bool
|
||||
Disabled bool `json:",omitempty"`
|
||||
// Hidden ensures that the item is not shown in the menu
|
||||
Hidden bool
|
||||
Hidden bool `json:",omitempty"`
|
||||
// Checked indicates if the item is selected (used by Checkbox and Radio types only)
|
||||
Checked bool
|
||||
Checked bool `json:",omitempty"`
|
||||
// Submenu contains a list of menu items that will be shown as a submenu
|
||||
//SubMenu []*MenuItem `json:"SubMenu,omitempty"`
|
||||
SubMenu *ProcessedMenu `json:"SubMenu,omitempty"`
|
||||
SubMenu *ProcessedMenu `json:",omitempty"`
|
||||
|
||||
// Foreground colour in hex RGBA format EG: 0xFF0000FF = #FF0000FF = red
|
||||
Foreground int
|
||||
// Colour
|
||||
RGBA string `json:",omitempty"`
|
||||
|
||||
// Background colour
|
||||
Background int
|
||||
// Font
|
||||
FontSize int `json:",omitempty"`
|
||||
FontName string `json:",omitempty"`
|
||||
|
||||
// Image - base64 image data
|
||||
Image string `json:",omitempty"`
|
||||
|
||||
// Tooltip
|
||||
Tooltip string `json:",omitempty"`
|
||||
}
|
||||
|
||||
func NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu.MenuItem) *ProcessedMenuItem {
|
||||
@@ -45,8 +52,12 @@ func NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu.MenuItem) *Pr
|
||||
Disabled: menuItem.Disabled,
|
||||
Hidden: menuItem.Hidden,
|
||||
Checked: menuItem.Checked,
|
||||
Foreground: menuItem.Foreground,
|
||||
Background: menuItem.Background,
|
||||
SubMenu: nil,
|
||||
RGBA: menuItem.RGBA,
|
||||
FontSize: menuItem.FontSize,
|
||||
FontName: menuItem.FontName,
|
||||
Image: menuItem.Image,
|
||||
Tooltip: menuItem.Tooltip,
|
||||
}
|
||||
|
||||
if menuItem.SubMenu != nil {
|
||||
@@ -63,9 +74,11 @@ type ProcessedMenu struct {
|
||||
func NewProcessedMenu(menuItemMap *MenuItemMap, menu *menu.Menu) *ProcessedMenu {
|
||||
|
||||
result := &ProcessedMenu{}
|
||||
for _, item := range menu.Items {
|
||||
processedMenuItem := NewProcessedMenuItem(menuItemMap, item)
|
||||
result.Items = append(result.Items, processedMenuItem)
|
||||
if menu != nil {
|
||||
for _, item := range menu.Items {
|
||||
processedMenuItem := NewProcessedMenuItem(menuItemMap, item)
|
||||
result.Items = append(result.Items, processedMenuItem)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -3,6 +3,7 @@ package menumanager
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"sync"
|
||||
)
|
||||
@@ -50,7 +51,7 @@ func NewTrayMenu(trayMenu *menu.TrayMenu) *TrayMenu {
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) {
|
||||
func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
newTrayMenu := NewTrayMenu(trayMenu)
|
||||
|
||||
// Hook up a new ID
|
||||
@@ -60,12 +61,15 @@ func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) {
|
||||
// Save the references
|
||||
m.trayMenus[trayID] = newTrayMenu
|
||||
m.trayMenuPointers[trayMenu] = trayID
|
||||
|
||||
return newTrayMenu.AsJSON()
|
||||
}
|
||||
|
||||
func (m *Manager) UpdateTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
// SetTrayMenu updates or creates a menu
|
||||
func (m *Manager) SetTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
|
||||
if !trayMenuKnown {
|
||||
return "", fmt.Errorf("unknown Tray Menu '%s'. Please add the tray menu using AddTrayMenu()", trayMenu.Label)
|
||||
return m.AddTrayMenu(trayMenu)
|
||||
}
|
||||
|
||||
// Create the updated tray menu
|
||||
@@ -91,6 +95,31 @@ func (m *Manager) GetTrayMenus() ([]string, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (m *Manager) UpdateTrayMenuLabel(trayMenu *menu.TrayMenu) (string, error) {
|
||||
trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
|
||||
if !trayMenuKnown {
|
||||
return "", fmt.Errorf("[UpdateTrayMenuLabel] unknown tray id for tray %s", trayMenu.Label)
|
||||
}
|
||||
|
||||
type LabelUpdate struct {
|
||||
ID string
|
||||
Label string
|
||||
}
|
||||
|
||||
update := &LabelUpdate{
|
||||
ID: trayID,
|
||||
Label: trayMenu.Label,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(update)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "[UpdateTrayMenuLabel] ")
|
||||
}
|
||||
|
||||
return string(data), nil
|
||||
|
||||
}
|
||||
|
||||
func (m *Manager) GetContextMenus() ([]string, error) {
|
||||
result := []string{}
|
||||
for _, contextMenu := range m.contextMenus {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
)
|
||||
|
||||
// Client defines what a frontend client can do
|
||||
@@ -13,9 +13,9 @@ type Client interface {
|
||||
Quit()
|
||||
NotifyEvent(message string)
|
||||
CallResult(message string)
|
||||
OpenDialog(dialogOptions *options.OpenDialog, callbackID string)
|
||||
SaveDialog(dialogOptions *options.SaveDialog, callbackID string)
|
||||
MessageDialog(dialogOptions *options.MessageDialog, callbackID string)
|
||||
OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string)
|
||||
SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string)
|
||||
MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string)
|
||||
WindowSetTitle(title string)
|
||||
WindowShow()
|
||||
WindowHide()
|
||||
@@ -31,7 +31,8 @@ type Client interface {
|
||||
WindowSetColour(colour int)
|
||||
DarkModeEnabled(callbackID string)
|
||||
SetApplicationMenu(menuJSON string)
|
||||
UpdateTrayMenu(trayMenuJSON string)
|
||||
SetTrayMenu(trayMenuJSON string)
|
||||
UpdateTrayMenuLabel(JSON string)
|
||||
UpdateContextMenu(contextMenuJSON string)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
// systemMessageParser does what it says on the tin!
|
||||
func systemMessageParser(message string) (*parsedMessage, error) {
|
||||
|
||||
// Sanity check: system messages must be at least 4 bytes
|
||||
if len(message) < 4 {
|
||||
// Sanity check: system messages must be at least 2 bytes
|
||||
if len(message) < 2 {
|
||||
return nil, fmt.Errorf("system message was an invalid length")
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ func systemMessageParser(message string) (*parsedMessage, error) {
|
||||
// Format of system response messages: S<command><callbackID>|<payload>
|
||||
// DarkModeEnabled
|
||||
case 'D':
|
||||
if len(message) < 4 {
|
||||
return nil, fmt.Errorf("system message was an invalid length")
|
||||
}
|
||||
message = message[1:]
|
||||
idx := strings.IndexByte(message, '|')
|
||||
if idx < 0 {
|
||||
@@ -34,6 +37,10 @@ func systemMessageParser(message string) (*parsedMessage, error) {
|
||||
topic := "systemresponse:" + callbackID
|
||||
responseMessage = &parsedMessage{Topic: topic, Data: payloadData == "T"}
|
||||
|
||||
// This is our startup hook - the frontend is now ready
|
||||
case 'S':
|
||||
topic := "hooks:startup"
|
||||
responseMessage = &parsedMessage{Topic: topic, Data: nil}
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid message to systemMessageParser()")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package messagedispatcher
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
// Dispatcher translates messages received from the frontend
|
||||
@@ -370,7 +370,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
||||
dialogType := splitTopic[2]
|
||||
switch dialogType {
|
||||
case "open":
|
||||
dialogOptions, ok := result.Data().(*options.OpenDialog)
|
||||
dialogOptions, ok := result.Data().(*dialog.OpenDialog)
|
||||
if !ok {
|
||||
d.logger.Error("Invalid data for 'dialog:select:open' : %#v", result.Data())
|
||||
return
|
||||
@@ -384,7 +384,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
||||
client.frontend.OpenDialog(dialogOptions, callbackID)
|
||||
}
|
||||
case "save":
|
||||
dialogOptions, ok := result.Data().(*options.SaveDialog)
|
||||
dialogOptions, ok := result.Data().(*dialog.SaveDialog)
|
||||
if !ok {
|
||||
d.logger.Error("Invalid data for 'dialog:select:save' : %#v", result.Data())
|
||||
return
|
||||
@@ -398,7 +398,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
||||
client.frontend.SaveDialog(dialogOptions, callbackID)
|
||||
}
|
||||
case "message":
|
||||
dialogOptions, ok := result.Data().(*options.MessageDialog)
|
||||
dialogOptions, ok := result.Data().(*dialog.MessageDialog)
|
||||
if !ok {
|
||||
d.logger.Error("Invalid data for 'dialog:select:message' : %#v", result.Data())
|
||||
return
|
||||
@@ -445,10 +445,10 @@ func (d *Dispatcher) processMenuMessage(result *servicebus.Message) {
|
||||
client.frontend.SetApplicationMenu(updatedMenu)
|
||||
}
|
||||
|
||||
case "updatetraymenu":
|
||||
updatedTrayMenu, ok := result.Data().(string)
|
||||
case "settraymenu":
|
||||
trayMenuJSON, ok := result.Data().(string)
|
||||
if !ok {
|
||||
d.logger.Error("Invalid data for 'menufrontend:updatetraymenu' : %#v",
|
||||
d.logger.Error("Invalid data for 'menufrontend:settraymenu' : %#v",
|
||||
result.Data())
|
||||
return
|
||||
}
|
||||
@@ -456,8 +456,9 @@ func (d *Dispatcher) processMenuMessage(result *servicebus.Message) {
|
||||
// TODO: Work out what we mean in a multi window environment...
|
||||
// For now we will just pick the first one
|
||||
for _, client := range d.clients {
|
||||
client.frontend.UpdateTrayMenu(updatedTrayMenu)
|
||||
client.frontend.SetTrayMenu(trayMenuJSON)
|
||||
}
|
||||
|
||||
case "updatecontextmenu":
|
||||
updatedContextMenu, ok := result.Data().(string)
|
||||
if !ok {
|
||||
@@ -472,6 +473,20 @@ func (d *Dispatcher) processMenuMessage(result *servicebus.Message) {
|
||||
client.frontend.UpdateContextMenu(updatedContextMenu)
|
||||
}
|
||||
|
||||
case "updatetraymenulabel":
|
||||
updatedTrayMenuLabel, ok := result.Data().(string)
|
||||
if !ok {
|
||||
d.logger.Error("Invalid data for 'menufrontend:updatetraymenulabel' : %#v",
|
||||
result.Data())
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Work out what we mean in a multi window environment...
|
||||
// For now we will just pick the first one
|
||||
for _, client := range d.clients {
|
||||
client.frontend.UpdateTrayMenuLabel(updatedTrayMenuLabel)
|
||||
}
|
||||
|
||||
default:
|
||||
d.logger.Error("Unknown menufrontend command: %s", command)
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
var internalMethods = slicer.String([]string{"WailsInit", "Wails Shutdown"})
|
||||
|
||||
var structCache = make(map[string]*ParsedStruct)
|
||||
var boundStructs = make(map[string]*ParsedStruct)
|
||||
var boundMethods = []string{}
|
||||
@@ -49,7 +47,7 @@ func ParseProject(projectPath string) (BoundStructs, error) {
|
||||
cfg := &packages.Config{Mode: packages.NeedFiles | packages.NeedSyntax | packages.NeedTypesInfo}
|
||||
pkgs, err := packages.Load(cfg, projectPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "load: %v\n", err)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "load: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if packages.PrintErrors(pkgs) > 0 {
|
||||
@@ -203,10 +201,6 @@ func ParseProject(projectPath string) (BoundStructs, error) {
|
||||
// This is a struct pointer method
|
||||
i, ok := se.X.(*ast.Ident)
|
||||
if ok {
|
||||
// We want to ignore Internal functions
|
||||
if internalMethods.Contains(x.Name.Name) {
|
||||
continue
|
||||
}
|
||||
// If we haven't already found this struct,
|
||||
// Create a placeholder in the cache
|
||||
parsedStruct := structCache[i.Name]
|
||||
@@ -437,4 +431,6 @@ func ParseProject(projectPath string) (BoundStructs, error) {
|
||||
println()
|
||||
println("}")
|
||||
println()
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@ import (
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/crypto"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
dialogoptions "github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
)
|
||||
|
||||
// Dialog defines all Dialog related operations
|
||||
type Dialog interface {
|
||||
Open(dialogOptions *options.OpenDialog) []string
|
||||
Save(dialogOptions *options.SaveDialog) string
|
||||
Message(dialogOptions *options.MessageDialog) string
|
||||
Open(dialogOptions *dialogoptions.OpenDialog) []string
|
||||
Save(dialogOptions *dialogoptions.SaveDialog) string
|
||||
Message(dialogOptions *dialogoptions.MessageDialog) string
|
||||
}
|
||||
|
||||
// dialog exposes the Dialog interface
|
||||
@@ -45,7 +45,7 @@ func (r *dialog) processTitleAndFilter(params ...string) (string, string) {
|
||||
}
|
||||
|
||||
// Open prompts the user to select a file
|
||||
func (r *dialog) Open(dialogOptions *options.OpenDialog) []string {
|
||||
func (r *dialog) Open(dialogOptions *dialogoptions.OpenDialog) []string {
|
||||
|
||||
// Create unique dialog callback
|
||||
uniqueCallback := crypto.RandomID()
|
||||
@@ -70,7 +70,7 @@ func (r *dialog) Open(dialogOptions *options.OpenDialog) []string {
|
||||
}
|
||||
|
||||
// Save prompts the user to select a file
|
||||
func (r *dialog) Save(dialogOptions *options.SaveDialog) string {
|
||||
func (r *dialog) Save(dialogOptions *dialogoptions.SaveDialog) string {
|
||||
|
||||
// Create unique dialog callback
|
||||
uniqueCallback := crypto.RandomID()
|
||||
@@ -95,7 +95,7 @@ func (r *dialog) Save(dialogOptions *options.SaveDialog) string {
|
||||
}
|
||||
|
||||
// Message show a message to the user
|
||||
func (r *dialog) Message(dialogOptions *options.MessageDialog) string {
|
||||
func (r *dialog) Message(dialogOptions *dialogoptions.MessageDialog) string {
|
||||
|
||||
// Create unique dialog callback
|
||||
uniqueCallback := crypto.RandomID()
|
||||
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
type Menu interface {
|
||||
UpdateApplicationMenu()
|
||||
UpdateContextMenu(contextMenu *menu.ContextMenu)
|
||||
UpdateTrayMenu(trayMenu *menu.TrayMenu)
|
||||
SetTrayMenu(trayMenu *menu.TrayMenu)
|
||||
UpdateTrayMenuLabel(trayMenu *menu.TrayMenu)
|
||||
}
|
||||
|
||||
type menuRuntime struct {
|
||||
@@ -31,6 +32,10 @@ func (m *menuRuntime) UpdateContextMenu(contextMenu *menu.ContextMenu) {
|
||||
m.bus.Publish("menu:updatecontextmenu", contextMenu)
|
||||
}
|
||||
|
||||
func (m *menuRuntime) UpdateTrayMenu(trayMenu *menu.TrayMenu) {
|
||||
m.bus.Publish("menu:updatetraymenu", trayMenu)
|
||||
func (m *menuRuntime) SetTrayMenu(trayMenu *menu.TrayMenu) {
|
||||
m.bus.Publish("menu:settraymenu", trayMenu)
|
||||
}
|
||||
|
||||
func (m *menuRuntime) UpdateTrayMenuLabel(trayMenu *menu.TrayMenu) {
|
||||
m.bus.Publish("menu:updatetraymenulabel", trayMenu)
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ func (r *system) IsDarkMode() bool {
|
||||
systemResponseChannel, err := r.bus.Subscribe(responseTopic)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
message := "system:isdarkmode:" + uniqueCallback
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Binding is the Binding subsystem. It manages all service bus messages
|
||||
@@ -26,13 +24,6 @@ type Binding struct {
|
||||
runtime *runtime.Runtime
|
||||
}
|
||||
|
||||
func showError(err error) {
|
||||
// Add a slight delay so log buffer clears
|
||||
time.Sleep(1 * time.Second)
|
||||
println("\n\n\n\n\n\n")
|
||||
println("Fatal Error in WailsInit(): " + err.Error())
|
||||
}
|
||||
|
||||
// NewBinding creates a new binding subsystem. Uses the given bindings db for reference.
|
||||
func NewBinding(bus *servicebus.ServiceBus, logger *logger.Logger, bindings *binding.Bindings, runtime *runtime.Runtime) (*Binding, error) {
|
||||
|
||||
@@ -56,16 +47,6 @@ func NewBinding(bus *servicebus.ServiceBus, logger *logger.Logger, bindings *bin
|
||||
runtime: runtime,
|
||||
}
|
||||
|
||||
// Call WailsInit methods once the frontend is loaded
|
||||
runtime.Events.On("wails:loaded", func(...interface{}) {
|
||||
result.logger.Trace("Calling WailsInit() methods")
|
||||
err := result.CallWailsInit()
|
||||
if err != nil {
|
||||
showError(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -94,34 +75,6 @@ func (b *Binding) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CallWailsInit will callback to the registered WailsInit
|
||||
// methods with the runtime object
|
||||
func (b *Binding) CallWailsInit() error {
|
||||
for _, wailsinit := range b.bindings.DB().WailsInitMethods() {
|
||||
_, err := wailsinit.Call([]interface{}{b.runtime})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CallWailsShutdown will callback to the registered WailsShutdown
|
||||
// methods with the runtime object
|
||||
func (b *Binding) CallWailsShutdown() error {
|
||||
for _, wailsshutdown := range b.bindings.DB().WailsShutdownMethods() {
|
||||
_, err := wailsshutdown.Call([]interface{}{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Binding) shutdown() {
|
||||
err := b.CallWailsShutdown()
|
||||
if err != nil {
|
||||
showError(err)
|
||||
}
|
||||
b.logger.Trace("Shutdown")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package subsystem
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
||||
"github.com/wailsapp/wails/v2/internal/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
// Call is the Call subsystem. It manages all service bus messages
|
||||
@@ -131,7 +131,7 @@ func (c *Call) processSystemCall(payload *message.CallMessage, clientID string)
|
||||
darkModeEnabled := c.runtime.System.IsDarkMode()
|
||||
c.sendResult(darkModeEnabled, payload, clientID)
|
||||
case "Dialog.Open":
|
||||
dialogOptions := new(options.OpenDialog)
|
||||
dialogOptions := new(dialog.OpenDialog)
|
||||
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
||||
if err != nil {
|
||||
c.logger.Error("Error decoding: %s", err)
|
||||
@@ -139,7 +139,7 @@ func (c *Call) processSystemCall(payload *message.CallMessage, clientID string)
|
||||
result := c.runtime.Dialog.Open(dialogOptions)
|
||||
c.sendResult(result, payload, clientID)
|
||||
case "Dialog.Save":
|
||||
dialogOptions := new(options.SaveDialog)
|
||||
dialogOptions := new(dialog.SaveDialog)
|
||||
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
||||
if err != nil {
|
||||
c.logger.Error("Error decoding: %s", err)
|
||||
@@ -147,7 +147,7 @@ func (c *Call) processSystemCall(payload *message.CallMessage, clientID string)
|
||||
result := c.runtime.Dialog.Save(dialogOptions)
|
||||
c.sendResult(result, payload, clientID)
|
||||
case "Dialog.Message":
|
||||
dialogOptions := new(options.MessageDialog)
|
||||
dialogOptions := new(dialog.MessageDialog)
|
||||
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
||||
if err != nil {
|
||||
c.logger.Error("Error decoding: %s", err)
|
||||
|
||||
@@ -120,16 +120,27 @@ func (m *Menu) Start() error {
|
||||
// Notify frontend of menu change
|
||||
m.bus.Publish("menufrontend:updatecontextmenu", updatedMenu)
|
||||
|
||||
case "updatetraymenu":
|
||||
case "settraymenu":
|
||||
trayMenu := menuMessage.Data().(*menu.TrayMenu)
|
||||
updatedMenu, err := m.menuManager.UpdateTrayMenu(trayMenu)
|
||||
updatedMenu, err := m.menuManager.SetTrayMenu(trayMenu)
|
||||
if err != nil {
|
||||
m.logger.Trace("%s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Notify frontend of menu change
|
||||
m.bus.Publish("menufrontend:updatetraymenu", updatedMenu)
|
||||
m.bus.Publish("menufrontend:settraymenu", updatedMenu)
|
||||
|
||||
case "updatetraymenulabel":
|
||||
trayMenu := menuMessage.Data().(*menu.TrayMenu)
|
||||
updatedLabel, err := m.menuManager.UpdateTrayMenuLabel(trayMenu)
|
||||
if err != nil {
|
||||
m.logger.Trace("%s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Notify frontend of menu change
|
||||
m.bus.Publish("menufrontend:updatetraymenulabel", updatedLabel)
|
||||
|
||||
default:
|
||||
m.logger.Error("unknown menu message: %+v", menuMessage)
|
||||
|
||||
@@ -14,7 +14,13 @@ import (
|
||||
type Runtime struct {
|
||||
quitChannel <-chan *servicebus.Message
|
||||
runtimeChannel <-chan *servicebus.Message
|
||||
running bool
|
||||
|
||||
// The hooks channel allows us to hook into frontend startup
|
||||
hooksChannel <-chan *servicebus.Message
|
||||
startupCallback func(*runtime.Runtime)
|
||||
shutdownCallback func()
|
||||
|
||||
running bool
|
||||
|
||||
logger logger.CustomLogger
|
||||
|
||||
@@ -23,7 +29,7 @@ type Runtime struct {
|
||||
}
|
||||
|
||||
// NewRuntime creates a new runtime subsystem
|
||||
func NewRuntime(bus *servicebus.ServiceBus, logger *logger.Logger) (*Runtime, error) {
|
||||
func NewRuntime(bus *servicebus.ServiceBus, logger *logger.Logger, startupCallback func(*runtime.Runtime), shutdownCallback func()) (*Runtime, error) {
|
||||
|
||||
// Register quit channel
|
||||
quitChannel, err := bus.Subscribe("quit")
|
||||
@@ -37,11 +43,20 @@ func NewRuntime(bus *servicebus.ServiceBus, logger *logger.Logger) (*Runtime, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Subscribe to log messages
|
||||
hooksChannel, err := bus.Subscribe("hooks:")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &Runtime{
|
||||
quitChannel: quitChannel,
|
||||
runtimeChannel: runtimeChannel,
|
||||
logger: logger.CustomLogger("Runtime Subsystem"),
|
||||
runtime: runtime.New(bus),
|
||||
quitChannel: quitChannel,
|
||||
runtimeChannel: runtimeChannel,
|
||||
hooksChannel: hooksChannel,
|
||||
logger: logger.CustomLogger("Runtime Subsystem"),
|
||||
runtime: runtime.New(bus),
|
||||
startupCallback: startupCallback,
|
||||
shutdownCallback: shutdownCallback,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
@@ -59,6 +74,21 @@ func (r *Runtime) Start() error {
|
||||
case <-r.quitChannel:
|
||||
r.running = false
|
||||
break
|
||||
case hooksMessage := <-r.hooksChannel:
|
||||
r.logger.Trace(fmt.Sprintf("Received hooksmessage: %+v", hooksMessage))
|
||||
messageSlice := strings.Split(hooksMessage.Topic(), ":")
|
||||
hook := messageSlice[1]
|
||||
switch hook {
|
||||
case "startup":
|
||||
if r.startupCallback != nil {
|
||||
go r.startupCallback(r.runtime)
|
||||
} else {
|
||||
r.logger.Error("no startup callback registered!")
|
||||
}
|
||||
default:
|
||||
r.logger.Error("unknown hook message: %+v", hooksMessage)
|
||||
continue
|
||||
}
|
||||
case runtimeMessage := <-r.runtimeChannel:
|
||||
r.logger.Trace(fmt.Sprintf("Received message: %+v", runtimeMessage))
|
||||
// Topics have the format: "runtime:category:call"
|
||||
@@ -99,6 +129,9 @@ func (r *Runtime) GoRuntime() *runtime.Runtime {
|
||||
}
|
||||
|
||||
func (r *Runtime) shutdown() {
|
||||
if r.shutdownCallback != nil {
|
||||
go r.shutdownCallback()
|
||||
}
|
||||
r.logger.Trace("Shutdown")
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package webserver
|
||||
import (
|
||||
"context"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -20,11 +20,27 @@ type WebClient struct {
|
||||
running bool
|
||||
}
|
||||
|
||||
func (wc *WebClient) OpenDialog(dialogOptions *options.OpenDialog, callbackID string) {
|
||||
func (wc *WebClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
func (wc *WebClient) SaveDialog(dialogOptions *options.SaveDialog, callbackID string) {
|
||||
func (wc *WebClient) SetApplicationMenu(menuJSON string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
func (wc *WebClient) UpdateTrayMenu(trayMenuJSON string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
func (wc *WebClient) UpdateContextMenu(contextMenuJSON string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
func (wc *WebClient) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
func (wc *WebClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
@@ -84,10 +100,6 @@ func (wc *WebClient) UpdateTrayIcon(name string) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
func (wc *WebClient) UpdateContextMenus(contextMenus *menu.ContextMenus) {
|
||||
wc.logger.Info("Not implemented in server build")
|
||||
}
|
||||
|
||||
// Quit terminates the webclient session
|
||||
func (wc *WebClient) Quit() {
|
||||
wc.running = false
|
||||
|
||||
@@ -211,7 +211,6 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
||||
options.CompiledBinary = compiledBinary
|
||||
|
||||
// Create the command
|
||||
fmt.Printf("Compile command: %+v", commands.AsSlice())
|
||||
cmd := exec.Command(options.Compiler, commands.AsSlice()...)
|
||||
|
||||
// Set the directory
|
||||
|
||||
@@ -12,6 +12,14 @@ func (m *Menu) Append(item *MenuItem) {
|
||||
m.Items = append(m.Items, item)
|
||||
}
|
||||
|
||||
// Merge will append the items in the given menu
|
||||
// into this menu
|
||||
func (m *Menu) Merge(menu *Menu) {
|
||||
for _, item := range menu.Items {
|
||||
m.Items = append(m.Items, item)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Menu) Prepend(item *MenuItem) {
|
||||
m.Items = append([]*MenuItem{item}, m.Items...)
|
||||
}
|
||||
|
||||
@@ -28,11 +28,18 @@ type MenuItem struct {
|
||||
// Callback function when menu clicked
|
||||
Click Callback `json:"-"`
|
||||
|
||||
// Foreground colour in hex RGBA format EG: 0xFF0000FF = #FF0000FF = red
|
||||
Foreground int
|
||||
// Colour
|
||||
RGBA string
|
||||
|
||||
// Background colour
|
||||
Background int
|
||||
// Font
|
||||
FontSize int
|
||||
FontName string
|
||||
|
||||
// Image - base64 image data
|
||||
Image string
|
||||
|
||||
// Tooltip
|
||||
Tooltip string
|
||||
|
||||
// This holds the menu item's parent.
|
||||
parent *MenuItem
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package options
|
||||
package dialog
|
||||
|
||||
// OpenDialog contains the options for the OpenDialog runtime method
|
||||
type OpenDialog struct {
|
||||
@@ -1,6 +1,7 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
wailsruntime "github.com/wailsapp/wails/v2/internal/runtime"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"log"
|
||||
"runtime"
|
||||
@@ -30,6 +31,8 @@ type App struct {
|
||||
Mac *mac.Options
|
||||
Logger logger.Logger `json:"-"`
|
||||
LogLevel logger.LogLevel
|
||||
Startup func(*wailsruntime.Runtime) `json:"-"`
|
||||
Shutdown func() `json:"-"`
|
||||
}
|
||||
|
||||
// MergeDefaults will set the minimum default values for an application
|
||||
|
||||
@@ -44,11 +44,6 @@ func (p *Parser) parseStructMethods(boundStruct *Struct) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// We want to ignore Internal functions
|
||||
if funcDecl.Name.Name == "WailsInit" || funcDecl.Name.Name == "WailsShutdown" {
|
||||
continue
|
||||
}
|
||||
|
||||
// If this method is not Public, ignore
|
||||
if string(funcDecl.Name.Name[0]) != strings.ToUpper((string(funcDecl.Name.Name[0]))) {
|
||||
continue
|
||||
|
||||
10
v2/pkg/str/str.go
Normal file
10
v2/pkg/str/str.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package str
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func UnixNow() string {
|
||||
return fmt.Sprintf("%+v", time.Now().Unix())
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
)
|
||||
|
||||
// Dialog struct
|
||||
@@ -18,16 +18,16 @@ func (l *Dialog) WailsInit(runtime *wails.Runtime) error {
|
||||
}
|
||||
|
||||
// Open Dialog
|
||||
func (l *Dialog) Open(options *options.OpenDialog) []string {
|
||||
func (l *Dialog) Open(options *dialog.OpenDialog) []string {
|
||||
return l.runtime.Dialog.Open(options)
|
||||
}
|
||||
|
||||
// Save Dialog
|
||||
func (l *Dialog) Save(options *options.SaveDialog) string {
|
||||
func (l *Dialog) Save(options *dialog.SaveDialog) string {
|
||||
return l.runtime.Dialog.Save(options)
|
||||
}
|
||||
|
||||
// Message Dialog
|
||||
func (l *Dialog) Message(options *options.MessageDialog) string {
|
||||
func (l *Dialog) Message(options *dialog.MessageDialog) string {
|
||||
return l.runtime.Dialog.Message(options)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
type Notepad struct {
|
||||
@@ -21,7 +21,7 @@ func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
||||
// successful save.
|
||||
func (n *Notepad) SaveNotes(notes string) (bool, error) {
|
||||
|
||||
selectedFile := n.runtime.Dialog.Save(&options.SaveDialog{
|
||||
selectedFile := n.runtime.Dialog.Save(&dialog.SaveDialog{
|
||||
DefaultFilename: "notes.md",
|
||||
Filters: "*.md",
|
||||
})
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
type Notepad struct {
|
||||
@@ -18,7 +18,7 @@ func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
||||
|
||||
func (n *Notepad) LoadNotes() (string, error) {
|
||||
|
||||
selectedFiles := n.runtime.Dialog.Open(&options.OpenDialog{
|
||||
selectedFiles := n.runtime.Dialog.Open(&dialog.OpenDialog{
|
||||
DefaultFilename: "notes.md",
|
||||
Filters: "*.md",
|
||||
AllowFiles: true,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
type Notepad struct {
|
||||
@@ -21,7 +21,7 @@ func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
||||
// successful save.
|
||||
func (n *Notepad) SaveNotes(notes string) (bool, error) {
|
||||
|
||||
selectedFile := n.runtime.Dialog.Save(&options.SaveDialog{
|
||||
selectedFile := n.runtime.Dialog.Save(&dialog.SaveDialog{
|
||||
DefaultFilename: "notes.md",
|
||||
Filters: "*.md",
|
||||
})
|
||||
|
||||
@@ -2,8 +2,6 @@ module test
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/wailsapp/wails/v2 v2.0.0-alpha
|
||||
)
|
||||
require github.com/wailsapp/wails/v2 v2.0.0-alpha
|
||||
|
||||
replace github.com/wailsapp/wails/v2 v2.0.0-alpha => ../../../v2
|
||||
|
||||
@@ -1,112 +1,90 @@
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
|
||||
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/colors v1.2.0/go.mod h1:miw1R2JIE19cclPxsXqNdzLZsk4DP4iF+m88bRc7kfM=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
||||
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leaanthony/clir v1.0.4 h1:Dov2y9zWJmZr7CjaCe86lKa4b5CSxskGAt2yBkoDyiU=
|
||||
github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/gosod v0.0.4/go.mod h1:nGMCb1PJfXwBDbOAike78jEYlpqge+xUKFf0iBKjKxU=
|
||||
github.com/leaanthony/mewn v0.10.7/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
|
||||
github.com/leaanthony/slicer v1.4.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/slicer v1.4.1/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/spinner v0.5.3/go.mod h1:oHlrvWicr++CVV7ALWYi+qHk/XNA91D9IJ48IqmpVUo=
|
||||
github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
|
||||
github.com/leaanthony/wincursor v0.1.0/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs=
|
||||
github.com/tdewolff/minify/v2 v2.9.5/go.mod h1:jshtBj/uUJH6JX1fuxTLnnHOA1RVJhF5MM+leJzDKb4=
|
||||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||
github.com/tdewolff/parse/v2 v2.5.3/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/wailsapp/wails v1.8.0 h1:gnQhpwoGM8s2GD5PZrgMKU1PO3pQ9cdKKJgwtkNz2f4=
|
||||
github.com/wailsapp/wails v1.8.0/go.mod h1:XFZunea+USOCMMgBlz0A0JHLL3oWrRhnOl4baZlRpxo=
|
||||
github.com/wailsapp/wails v1.9.1 h1:ez/TK8YpU9lvOZ9nkgzUXsWu+xOPFVO57zTy0n5w3hc=
|
||||
github.com/xyproto/xpm v1.2.1/go.mod h1:cMnesLsD0PBXLgjDfTDEaKr8XyTFsnP1QycSqRw7BiY=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -123,12 +101,14 @@ golang.org/x/tools v0.0.0-20200902012652-d1954cc86c82/go.mod h1:Cj7w3i3Rnn0Xh82u
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
|
||||
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
|
||||
@@ -34,6 +34,8 @@ func main() {
|
||||
TrayMenus: Tray.createTrayMenus(),
|
||||
},
|
||||
LogLevel: logger.TRACE,
|
||||
Startup: Tray.start,
|
||||
Shutdown: Tray.shutdown,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -21,8 +21,8 @@ type Tray struct {
|
||||
done bool
|
||||
}
|
||||
|
||||
// WailsInit is called at application startup
|
||||
func (t *Tray) WailsInit(runtime *wails.Runtime) error {
|
||||
// This is called at application startup
|
||||
func (t *Tray) start(runtime *wails.Runtime) {
|
||||
// Perform your setup here
|
||||
t.runtime = runtime
|
||||
|
||||
@@ -36,7 +36,6 @@ func (t *Tray) WailsInit(runtime *wails.Runtime) error {
|
||||
// t.runtime.Tray.SetIcon("dark")
|
||||
//})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tray) showWindow(_ *menu.CallbackData) {
|
||||
@@ -55,7 +54,7 @@ func (t *Tray) minimiseWindow(_ *menu.CallbackData) {
|
||||
t.runtime.Window.Minimise()
|
||||
}
|
||||
|
||||
func (t *Tray) WailsShutdown() {
|
||||
func (t *Tray) shutdown() {
|
||||
t.done = true
|
||||
}
|
||||
|
||||
@@ -71,19 +70,19 @@ func (t *Tray) decrementcounter() int {
|
||||
|
||||
func (t *Tray) SvelteIcon(_ *menu.CallbackData) {
|
||||
t.secondTrayMenu.Icon = "svelte"
|
||||
t.runtime.Menu.UpdateTrayMenu(t.secondTrayMenu)
|
||||
t.runtime.Menu.SetTrayMenu(t.secondTrayMenu)
|
||||
}
|
||||
func (t *Tray) NoIcon(_ *menu.CallbackData) {
|
||||
t.secondTrayMenu.Icon = ""
|
||||
t.runtime.Menu.UpdateTrayMenu(t.secondTrayMenu)
|
||||
t.runtime.Menu.SetTrayMenu(t.secondTrayMenu)
|
||||
}
|
||||
func (t *Tray) LightIcon(_ *menu.CallbackData) {
|
||||
t.secondTrayMenu.Icon = "light"
|
||||
t.runtime.Menu.UpdateTrayMenu(t.secondTrayMenu)
|
||||
t.runtime.Menu.SetTrayMenu(t.secondTrayMenu)
|
||||
}
|
||||
func (t *Tray) DarkIcon(_ *menu.CallbackData) {
|
||||
t.secondTrayMenu.Icon = "dark"
|
||||
t.runtime.Menu.UpdateTrayMenu(t.secondTrayMenu)
|
||||
t.runtime.Menu.SetTrayMenu(t.secondTrayMenu)
|
||||
}
|
||||
|
||||
//func (t *Tray) removeMenu(_ *menu.MenuItem) {
|
||||
@@ -146,7 +145,7 @@ func (t *Tray) createTrayMenus() []*menu.TrayMenu {
|
||||
counter := t.incrementcounter()
|
||||
trayLabel := "Updated Label " + strconv.Itoa(counter)
|
||||
secondTrayMenu.Label = trayLabel
|
||||
t.runtime.Menu.UpdateTrayMenu(t.secondTrayMenu)
|
||||
t.runtime.Menu.SetTrayMenu(t.secondTrayMenu)
|
||||
}),
|
||||
menu.SubMenu("Select Icon", menu.NewMenuFromItems(
|
||||
menu.Text("Svelte", nil, t.SvelteIcon),
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
// RuntimeTest to test the runtimes
|
||||
@@ -75,7 +75,7 @@ func (r *RuntimeTest) SetColour(colour int) {
|
||||
|
||||
// OpenFileDialog will call the Runtime.Dialog.OpenDialog method requesting File selection
|
||||
func (r *RuntimeTest) OpenFileDialog(title string, filter string) []string {
|
||||
dialogOptions := &options.OpenDialog{
|
||||
dialogOptions := &dialog.OpenDialog{
|
||||
Title: title,
|
||||
Filters: filter,
|
||||
AllowFiles: true,
|
||||
@@ -85,7 +85,7 @@ func (r *RuntimeTest) OpenFileDialog(title string, filter string) []string {
|
||||
|
||||
// OpenDirectoryDialog will call the Runtime.Dialog.OpenDialog method requesting File selection
|
||||
func (r *RuntimeTest) OpenDirectoryDialog(title string, filter string) []string {
|
||||
dialogOptions := &options.OpenDialog{
|
||||
dialogOptions := &dialog.OpenDialog{
|
||||
Title: title,
|
||||
Filters: filter,
|
||||
AllowDirectories: true,
|
||||
@@ -95,7 +95,7 @@ func (r *RuntimeTest) OpenDirectoryDialog(title string, filter string) []string
|
||||
|
||||
// OpenDialog will call the Runtime.Dialog.OpenDialog method requesting both Files and Directories
|
||||
func (r *RuntimeTest) OpenDialog(title string, filter string) []string {
|
||||
dialogOptions := &options.OpenDialog{
|
||||
dialogOptions := &dialog.OpenDialog{
|
||||
Title: title,
|
||||
Filters: filter,
|
||||
AllowDirectories: true,
|
||||
@@ -106,7 +106,7 @@ func (r *RuntimeTest) OpenDialog(title string, filter string) []string {
|
||||
|
||||
// OpenDialogMultiple will call the Runtime.Dialog.OpenDialog method allowing multiple selection
|
||||
func (r *RuntimeTest) OpenDialogMultiple(title string, filter string) []string {
|
||||
dialogOptions := &options.OpenDialog{
|
||||
dialogOptions := &dialog.OpenDialog{
|
||||
Title: title,
|
||||
Filters: filter,
|
||||
AllowDirectories: true,
|
||||
@@ -118,7 +118,7 @@ func (r *RuntimeTest) OpenDialogMultiple(title string, filter string) []string {
|
||||
|
||||
// OpenDialogAllOptions will call the Runtime.Dialog.OpenDialog method allowing multiple selection
|
||||
func (r *RuntimeTest) OpenDialogAllOptions(filter string, defaultDir string, defaultFilename string) []string {
|
||||
dialogOptions := &options.OpenDialog{
|
||||
dialogOptions := &dialog.OpenDialog{
|
||||
DefaultDirectory: defaultDir,
|
||||
DefaultFilename: defaultFilename,
|
||||
Filters: filter,
|
||||
@@ -134,7 +134,7 @@ func (r *RuntimeTest) OpenDialogAllOptions(filter string, defaultDir string, def
|
||||
|
||||
// SaveFileDialog will call the Runtime.Dialog.SaveDialog method requesting a File selection
|
||||
func (r *RuntimeTest) SaveFileDialog(title string, filter string) string {
|
||||
dialogOptions := &options.SaveDialog{
|
||||
dialogOptions := &dialog.SaveDialog{
|
||||
Title: title,
|
||||
Filters: filter,
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func (r *RuntimeTest) SaveFileDialog(title string, filter string) string {
|
||||
|
||||
// SaveDialogAllOptions will call the Runtime.Dialog.SaveDialog method allowing multiple selection
|
||||
func (r *RuntimeTest) SaveDialogAllOptions(filter string, defaultDir string, defaultFilename string) string {
|
||||
dialogOptions := &options.SaveDialog{
|
||||
dialogOptions := &dialog.SaveDialog{
|
||||
DefaultDirectory: defaultDir,
|
||||
DefaultFilename: defaultFilename,
|
||||
Filters: filter,
|
||||
|
||||
Reference in New Issue
Block a user