mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Move TrayMenu from config to runtime
Support better tray menu API Move object creation to main thread
This commit is contained in:
parent
c1d4aeb3cd
commit
ae0933c82a
12 changed files with 407 additions and 280 deletions
|
|
@ -59,8 +59,9 @@ void UpdateApplicationMenu(void *inctx);
|
|||
void SetMenuItemChecked(void* nsMenuItem, int checked);
|
||||
|
||||
/* Tray Menu */
|
||||
void* NewNSStatusItem(const char* label);
|
||||
void NewNSStatusItem(int);
|
||||
void SetTrayMenu(void *nsStatusItem, void* nsMenu);
|
||||
void SetTrayMenuLabel(void *nsStatusItem, const char *label);
|
||||
|
||||
void SetAbout(void *inctx, const char* title, const char* description, void* imagedata, int datalen);
|
||||
void* AppendMenuItem(void* inctx, void* nsmenu, const char* label, const char* shortcutKey, int modifiers, int disabled, int checked, int menuItemID);
|
||||
|
|
@ -69,4 +70,6 @@ void UpdateMenuItem(void* nsmenuitem, int checked);
|
|||
|
||||
NSString* safeInit(const char* input);
|
||||
|
||||
void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position);
|
||||
|
||||
#endif /* Application_h */
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#import "AppDelegate.h"
|
||||
#import "WailsMenu.h"
|
||||
#import "WailsMenuItem.h"
|
||||
#import "message.h"
|
||||
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight) {
|
||||
|
||||
|
|
@ -274,12 +275,20 @@ void AppendRole(void *inctx, void *inMenu, int role) {
|
|||
[menu appendRole :ctx :role];
|
||||
}
|
||||
|
||||
void* NewNSStatusItem(const char* label) {
|
||||
NSString *_label = safeInit(label);
|
||||
NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
|
||||
NSStatusItem *result = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain];
|
||||
[result button].title = _label;
|
||||
return result;
|
||||
void NewNSStatusItem(int id) {
|
||||
ON_MAIN_THREAD(
|
||||
NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
|
||||
NSStatusItem *result = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain];
|
||||
objectCreated(id,result);
|
||||
)
|
||||
}
|
||||
|
||||
void SetTrayMenuLabel(void *_nsStatusItem, const char *label) {
|
||||
ON_MAIN_THREAD(
|
||||
NSStatusItem *nsStatusItem = (NSStatusItem*) _nsStatusItem;
|
||||
nsStatusItem.button.title = safeInit(label);
|
||||
free((void*)label);
|
||||
)
|
||||
}
|
||||
|
||||
void SetTrayMenu(void *nsStatusItem, void* nsMenu) {
|
||||
|
|
@ -313,8 +322,8 @@ void SetAsApplicationMenu(void *inctx, void *inMenu) {
|
|||
void UpdateApplicationMenu(void *inctx) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
ON_MAIN_THREAD(
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
[app setMainMenu:ctx.applicationMenu];
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
[app setMainMenu:ctx.applicationMenu];
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +348,7 @@ void UpdateMenuItem(void* nsmenuitem, int checked) {
|
|||
ON_MAIN_THREAD(
|
||||
WailsMenuItem *menuItem = (__bridge WailsMenuItem*) nsmenuitem;
|
||||
[menuItem setState:(checked == 1?NSControlStateValueOn:NSControlStateValueOff)];
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -348,6 +357,27 @@ void AppendSeparator(void* inMenu) {
|
|||
[menu AppendSeparator];
|
||||
}
|
||||
|
||||
void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position) {
|
||||
ON_MAIN_THREAD(
|
||||
NSStatusItem *statusItem = (NSStatusItem*) nsStatusItem;
|
||||
NSData *nsdata = [NSData dataWithBytes:imageData length:imageDataLength];
|
||||
NSImage *image = [[[NSImage alloc] initWithData:nsdata] autorelease];
|
||||
if(template) {
|
||||
image.template = true;
|
||||
}
|
||||
statusItem.button.image = image;
|
||||
|
||||
// Swap NSNoImage and NSImageLeading because we wanted NSImageLeading to be default in Go
|
||||
int actualPosition = position;
|
||||
if( position == 7) {
|
||||
actualPosition = 0;
|
||||
} else if (position == 0) {
|
||||
actualPosition = 7;
|
||||
}
|
||||
[statusItem.button setImagePosition:actualPosition];
|
||||
)
|
||||
}
|
||||
|
||||
void Run(void *inctx, const char* url, int activationPolicy) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
|
|
|
|||
|
|
@ -14,24 +14,82 @@ package darwin
|
|||
*/
|
||||
import "C"
|
||||
import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu/keys"
|
||||
)
|
||||
|
||||
var createNSObjectMap = make(map[uint32]chan unsafe.Pointer)
|
||||
var createNSObjectMapLock sync.RWMutex
|
||||
|
||||
func waitNSObjectCreate(id uint32, fn func()) unsafe.Pointer {
|
||||
waitchan := make(chan unsafe.Pointer)
|
||||
createNSObjectMapLock.Lock()
|
||||
createNSObjectMap[id] = waitchan
|
||||
createNSObjectMapLock.Unlock()
|
||||
fn()
|
||||
result := <-waitchan
|
||||
createNSObjectMapLock.Lock()
|
||||
createNSObjectMap[id] = nil
|
||||
createNSObjectMapLock.Unlock()
|
||||
return result
|
||||
}
|
||||
|
||||
//export objectCreated
|
||||
func objectCreated(id uint32, pointer unsafe.Pointer) {
|
||||
createNSObjectMapLock.Lock()
|
||||
createNSObjectMap[id] <- pointer
|
||||
createNSObjectMapLock.Unlock()
|
||||
}
|
||||
|
||||
func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu) *NSTrayMenu {
|
||||
c := NewCalloc()
|
||||
defer c.Free()
|
||||
theMenu := NewNSMenu(context, "")
|
||||
processMenu(theMenu, trayMenu.Menu)
|
||||
title := c.String(trayMenu.Label)
|
||||
nsStatusItem := C.NewNSStatusItem(title)
|
||||
C.SetTrayMenu(nsStatusItem, theMenu.nsmenu)
|
||||
return &NSTrayMenu{
|
||||
|
||||
id := uuid.New().ID()
|
||||
nsStatusItem := waitNSObjectCreate(id, func() {
|
||||
C.NewNSStatusItem(C.int(id))
|
||||
})
|
||||
result := &NSTrayMenu{
|
||||
context: context,
|
||||
nsStatusItem: nsStatusItem,
|
||||
}
|
||||
|
||||
if trayMenu.Label != "" {
|
||||
result.SetLabel(trayMenu.Label)
|
||||
}
|
||||
|
||||
// TODO: Move this into NSTrayMenu method
|
||||
if trayMenu.Menu != nil {
|
||||
theMenu := NewNSMenu(context, "")
|
||||
processMenu(theMenu, trayMenu.Menu)
|
||||
result.SetMenu(theMenu)
|
||||
}
|
||||
|
||||
if trayMenu.Image != nil {
|
||||
result.SetImage(trayMenu.Image)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (n *NSTrayMenu) SetImage(image *menu.TrayImage) {
|
||||
if image.Image == nil {
|
||||
return
|
||||
}
|
||||
C.SetTrayImage(n.nsStatusItem,
|
||||
unsafe.Pointer(&image.Image[0]),
|
||||
C.int(len(image.Image)),
|
||||
bool2Cint(image.IsTemplate),
|
||||
C.int(image.Position),
|
||||
)
|
||||
}
|
||||
|
||||
func (n *NSTrayMenu) SetMenu(menu *NSMenu) {
|
||||
C.SetTrayMenu(n.nsStatusItem, menu.nsmenu)
|
||||
}
|
||||
|
||||
type NSMenu struct {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ void processOpenFileDialogResponse(const char*);
|
|||
void processSaveFileDialogResponse(const char*);
|
||||
void processCallback(int);
|
||||
void processNotification(int);
|
||||
void objectCreated(int, void*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ package darwin
|
|||
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
|
@ -17,13 +16,10 @@ import (
|
|||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
)
|
||||
|
||||
func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) {
|
||||
if f.applicationDidFinishLaunching == false {
|
||||
f.trayMenusBuffer = append(f.trayMenusBuffer, trayMenu)
|
||||
return
|
||||
}
|
||||
func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl {
|
||||
nsTrayMenu := f.mainWindow.TrayMenuAdd(trayMenu)
|
||||
f.trayMenus[trayMenu] = nsTrayMenu
|
||||
return nsTrayMenu
|
||||
}
|
||||
|
||||
type NSTrayMenu struct {
|
||||
|
|
@ -31,6 +27,11 @@ type NSTrayMenu struct {
|
|||
nsStatusItem unsafe.Pointer // NSStatusItem
|
||||
}
|
||||
|
||||
func (n *NSTrayMenu) SetLabel(label string) {
|
||||
cLabel := C.CString(label)
|
||||
C.SetTrayMenuLabel(n.nsStatusItem, cLabel)
|
||||
}
|
||||
|
||||
func (w *Window) TrayMenuAdd(trayMenu *menu.TrayMenu) *NSTrayMenu {
|
||||
return NewNSTrayMenu(w.context, trayMenu)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,10 +112,6 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
|||
result.SetApplicationMenu(frontendOptions.Menu)
|
||||
}
|
||||
|
||||
if frontendOptions.TrayMenu != nil {
|
||||
result.TrayMenuAdd(frontendOptions.TrayMenu)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,5 +103,5 @@ type Frontend interface {
|
|||
BrowserOpenURL(url string)
|
||||
|
||||
// Tray Menu
|
||||
TrayMenuAdd(trayMenu *menu.TrayMenu)
|
||||
TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
package menumanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
)
|
||||
import "github.com/wailsapp/wails/v2/pkg/menu"
|
||||
|
||||
//
|
||||
//import (
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
//
|
||||
// "github.com/wailsapp/wails/v2/pkg/menu"
|
||||
//)
|
||||
//
|
||||
type ContextMenu struct {
|
||||
ID string
|
||||
ProcessedMenu *WailsMenu
|
||||
|
|
@ -14,48 +17,49 @@ type ContextMenu struct {
|
|||
menu *menu.Menu
|
||||
}
|
||||
|
||||
func (t *ContextMenu) AsJSON() (string, error) {
|
||||
data, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func NewContextMenu(contextMenu *menu.ContextMenu) *ContextMenu {
|
||||
|
||||
result := &ContextMenu{
|
||||
ID: contextMenu.ID,
|
||||
menu: contextMenu.Menu,
|
||||
menuItemMap: NewMenuItemMap(),
|
||||
}
|
||||
|
||||
result.menuItemMap.AddMenu(contextMenu.Menu)
|
||||
result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *Manager) AddContextMenu(contextMenu *menu.ContextMenu) {
|
||||
|
||||
newContextMenu := NewContextMenu(contextMenu)
|
||||
|
||||
// Save the references
|
||||
m.contextMenus[contextMenu.ID] = newContextMenu
|
||||
m.contextMenuPointers[contextMenu] = contextMenu.ID
|
||||
}
|
||||
|
||||
func (m *Manager) UpdateContextMenu(contextMenu *menu.ContextMenu) (string, error) {
|
||||
contextMenuID, contextMenuKnown := m.contextMenuPointers[contextMenu]
|
||||
if !contextMenuKnown {
|
||||
return "", fmt.Errorf("unknown Context Menu '%s'. Please add the context menu using AddContextMenu()", contextMenu.ID)
|
||||
}
|
||||
|
||||
// Create the updated context menu
|
||||
updatedContextMenu := NewContextMenu(contextMenu)
|
||||
|
||||
// Save the reference
|
||||
m.contextMenus[contextMenuID] = updatedContextMenu
|
||||
|
||||
return updatedContextMenu.AsJSON()
|
||||
}
|
||||
//
|
||||
//func (t *ContextMenu) AsJSON() (string, error) {
|
||||
// data, err := json.Marshal(t)
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
// return string(data), nil
|
||||
//}
|
||||
//
|
||||
//func NewContextMenu(contextMenu *menu.ContextMenu) *ContextMenu {
|
||||
//
|
||||
// result := &ContextMenu{
|
||||
// ID: contextMenu.ID,
|
||||
// menu: contextMenu.Menu,
|
||||
// menuItemMap: NewMenuItemMap(),
|
||||
// }
|
||||
//
|
||||
// result.menuItemMap.AddMenu(contextMenu.Menu)
|
||||
// result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
|
||||
//
|
||||
// return result
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) AddContextMenu(contextMenu *menu.ContextMenu) {
|
||||
//
|
||||
// newContextMenu := NewContextMenu(contextMenu)
|
||||
//
|
||||
// // Save the references
|
||||
// m.contextMenus[contextMenu.ID] = newContextMenu
|
||||
// m.contextMenuPointers[contextMenu] = contextMenu.ID
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) UpdateContextMenu(contextMenu *menu.ContextMenu) (string, error) {
|
||||
// contextMenuID, contextMenuKnown := m.contextMenuPointers[contextMenu]
|
||||
// if !contextMenuKnown {
|
||||
// return "", fmt.Errorf("unknown Context Menu '%s'. Please add the context menu using AddContextMenu()", contextMenu.ID)
|
||||
// }
|
||||
//
|
||||
// // Create the updated context menu
|
||||
// updatedContextMenu := NewContextMenu(contextMenu)
|
||||
//
|
||||
// // Save the reference
|
||||
// m.contextMenus[contextMenuID] = updatedContextMenu
|
||||
//
|
||||
// return updatedContextMenu.AsJSON()
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package menumanager
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
package menumanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/leaanthony/go-ansi-parser"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
)
|
||||
|
||||
|
|
@ -32,7 +28,7 @@ type TrayMenu struct {
|
|||
FontName string
|
||||
Disabled bool
|
||||
Tooltip string `json:",omitempty"`
|
||||
Image string
|
||||
Image []byte
|
||||
MacTemplateImage bool
|
||||
RGBA string
|
||||
menuItemMap *MenuItemMap
|
||||
|
|
@ -42,181 +38,182 @@ type TrayMenu struct {
|
|||
StyledLabel []*ansi.StyledText `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (t *TrayMenu) AsJSON() (string, error) {
|
||||
data, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func NewTrayMenu(trayMenu *menu.TrayMenu) *TrayMenu {
|
||||
|
||||
// Parse ANSI text
|
||||
var styledLabel []*ansi.StyledText
|
||||
tempLabel := trayMenu.Label
|
||||
if strings.Contains(tempLabel, "\033[") {
|
||||
parsedLabel, err := ansi.Parse(tempLabel)
|
||||
if err == nil {
|
||||
styledLabel = parsedLabel
|
||||
}
|
||||
}
|
||||
|
||||
result := &TrayMenu{
|
||||
Label: trayMenu.Label,
|
||||
FontName: trayMenu.FontName,
|
||||
FontSize: trayMenu.FontSize,
|
||||
Disabled: trayMenu.Disabled,
|
||||
Tooltip: trayMenu.Tooltip,
|
||||
Image: trayMenu.Image,
|
||||
MacTemplateImage: trayMenu.MacTemplateImage,
|
||||
menu: trayMenu.Menu,
|
||||
RGBA: trayMenu.RGBA,
|
||||
menuItemMap: NewMenuItemMap(),
|
||||
trayMenu: trayMenu,
|
||||
StyledLabel: styledLabel,
|
||||
}
|
||||
|
||||
result.menuItemMap.AddMenu(trayMenu.Menu)
|
||||
result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *Manager) OnTrayMenuOpen(id string) {
|
||||
trayMenu, ok := m.trayMenus[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if trayMenu.trayMenu.OnOpen == nil {
|
||||
return
|
||||
}
|
||||
go trayMenu.trayMenu.OnOpen()
|
||||
}
|
||||
|
||||
func (m *Manager) OnTrayMenuClose(id string) {
|
||||
trayMenu, ok := m.trayMenus[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if trayMenu.trayMenu.OnClose == nil {
|
||||
return
|
||||
}
|
||||
go trayMenu.trayMenu.OnClose()
|
||||
}
|
||||
|
||||
func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
newTrayMenu := NewTrayMenu(trayMenu)
|
||||
|
||||
// Hook up a new ID
|
||||
trayID := generateTrayID()
|
||||
newTrayMenu.ID = trayID
|
||||
|
||||
// Save the references
|
||||
m.trayMenus[trayID] = newTrayMenu
|
||||
m.trayMenuPointers[trayMenu] = trayID
|
||||
|
||||
return newTrayMenu.AsJSON()
|
||||
}
|
||||
|
||||
func (m *Manager) GetTrayID(trayMenu *menu.TrayMenu) (string, error) {
|
||||
trayID, exists := m.trayMenuPointers[trayMenu]
|
||||
if !exists {
|
||||
return "", fmt.Errorf("Unable to find menu ID for tray menu!")
|
||||
}
|
||||
return trayID, nil
|
||||
}
|
||||
|
||||
// SetTrayMenu updates or creates a menu
|
||||
func (m *Manager) SetTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
|
||||
if !trayMenuKnown {
|
||||
return m.AddTrayMenu(trayMenu)
|
||||
}
|
||||
|
||||
// Create the updated tray menu
|
||||
updatedTrayMenu := NewTrayMenu(trayMenu)
|
||||
updatedTrayMenu.ID = trayID
|
||||
|
||||
// Save the reference
|
||||
m.trayMenus[trayID] = updatedTrayMenu
|
||||
|
||||
return updatedTrayMenu.AsJSON()
|
||||
}
|
||||
|
||||
func (m *Manager) GetTrayMenus() ([]string, error) {
|
||||
result := []string{}
|
||||
for _, trayMenu := range m.trayMenus {
|
||||
JSON, err := trayMenu.AsJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, JSON)
|
||||
}
|
||||
|
||||
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 `json:",omitempty"`
|
||||
FontName string `json:",omitempty"`
|
||||
FontSize int
|
||||
RGBA string `json:",omitempty"`
|
||||
Disabled bool
|
||||
Tooltip string `json:",omitempty"`
|
||||
Image string `json:",omitempty"`
|
||||
MacTemplateImage bool
|
||||
StyledLabel []*ansi.StyledText `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Parse ANSI text
|
||||
var styledLabel []*ansi.StyledText
|
||||
tempLabel := trayMenu.Label
|
||||
if strings.Contains(tempLabel, "\033[") {
|
||||
parsedLabel, err := ansi.Parse(tempLabel)
|
||||
if err == nil {
|
||||
styledLabel = parsedLabel
|
||||
}
|
||||
}
|
||||
|
||||
update := &LabelUpdate{
|
||||
ID: trayID,
|
||||
Label: trayMenu.Label,
|
||||
FontName: trayMenu.FontName,
|
||||
FontSize: trayMenu.FontSize,
|
||||
Disabled: trayMenu.Disabled,
|
||||
Tooltip: trayMenu.Tooltip,
|
||||
Image: trayMenu.Image,
|
||||
MacTemplateImage: trayMenu.MacTemplateImage,
|
||||
RGBA: trayMenu.RGBA,
|
||||
StyledLabel: styledLabel,
|
||||
}
|
||||
|
||||
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 {
|
||||
JSON, err := contextMenu.AsJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, JSON)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
//
|
||||
//func (t *TrayMenu) AsJSON() (string, error) {
|
||||
// data, err := json.Marshal(t)
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
// return string(data), nil
|
||||
//}
|
||||
//
|
||||
//func NewTrayMenu(trayMenu *menu.TrayMenu) *TrayMenu {
|
||||
//
|
||||
// // Parse ANSI text
|
||||
// var styledLabel []*ansi.StyledText
|
||||
// tempLabel := trayMenu.Label
|
||||
// if strings.Contains(tempLabel, "\033[") {
|
||||
// parsedLabel, err := ansi.Parse(tempLabel)
|
||||
// if err == nil {
|
||||
// styledLabel = parsedLabel
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// result := &TrayMenu{
|
||||
// Label: trayMenu.Label,
|
||||
// FontName: trayMenu.FontName,
|
||||
// FontSize: trayMenu.FontSize,
|
||||
// Disabled: trayMenu.Disabled,
|
||||
// Tooltip: trayMenu.Tooltip,
|
||||
// Image: trayMenu.Image,
|
||||
// MacTemplateImage: trayMenu.MacTemplateImage,
|
||||
// menu: trayMenu.Menu,
|
||||
// RGBA: trayMenu.RGBA,
|
||||
// menuItemMap: NewMenuItemMap(),
|
||||
// trayMenu: trayMenu,
|
||||
// StyledLabel: styledLabel,
|
||||
// }
|
||||
//
|
||||
// result.menuItemMap.AddMenu(trayMenu.Menu)
|
||||
// result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
|
||||
//
|
||||
// return result
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) OnTrayMenuOpen(id string) {
|
||||
// trayMenu, ok := m.trayMenus[id]
|
||||
// if !ok {
|
||||
// return
|
||||
// }
|
||||
// if trayMenu.trayMenu.OnOpen == nil {
|
||||
// return
|
||||
// }
|
||||
// go trayMenu.trayMenu.OnOpen()
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) OnTrayMenuClose(id string) {
|
||||
// trayMenu, ok := m.trayMenus[id]
|
||||
// if !ok {
|
||||
// return
|
||||
// }
|
||||
// if trayMenu.trayMenu.OnClose == nil {
|
||||
// return
|
||||
// }
|
||||
// go trayMenu.trayMenu.OnClose()
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
// newTrayMenu := NewTrayMenu(trayMenu)
|
||||
//
|
||||
// // Hook up a new ID
|
||||
// trayID := generateTrayID()
|
||||
// newTrayMenu.ID = trayID
|
||||
//
|
||||
// // Save the references
|
||||
// m.trayMenus[trayID] = newTrayMenu
|
||||
// m.trayMenuPointers[trayMenu] = trayID
|
||||
//
|
||||
// return newTrayMenu.AsJSON()
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) GetTrayID(trayMenu *menu.TrayMenu) (string, error) {
|
||||
// trayID, exists := m.trayMenuPointers[trayMenu]
|
||||
// if !exists {
|
||||
// return "", fmt.Errorf("Unable to find menu ID for tray menu!")
|
||||
// }
|
||||
// return trayID, nil
|
||||
//}
|
||||
//
|
||||
//// SetTrayMenu updates or creates a menu
|
||||
//func (m *Manager) SetTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
// trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
|
||||
// if !trayMenuKnown {
|
||||
// return m.AddTrayMenu(trayMenu)
|
||||
// }
|
||||
//
|
||||
// // Create the updated tray menu
|
||||
// updatedTrayMenu := NewTrayMenu(trayMenu)
|
||||
// updatedTrayMenu.ID = trayID
|
||||
//
|
||||
// // Save the reference
|
||||
// m.trayMenus[trayID] = updatedTrayMenu
|
||||
//
|
||||
// return updatedTrayMenu.AsJSON()
|
||||
//}
|
||||
//
|
||||
//func (m *Manager) GetTrayMenus() ([]string, error) {
|
||||
// result := []string{}
|
||||
// for _, trayMenu := range m.trayMenus {
|
||||
// JSON, err := trayMenu.AsJSON()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// result = append(result, JSON)
|
||||
// }
|
||||
//
|
||||
// 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 `json:",omitempty"`
|
||||
// FontName string `json:",omitempty"`
|
||||
// FontSize int
|
||||
// RGBA string `json:",omitempty"`
|
||||
// Disabled bool
|
||||
// Tooltip string `json:",omitempty"`
|
||||
// Image []byte `json:",omitempty"`
|
||||
// MacTemplateImage bool
|
||||
// StyledLabel []*ansi.StyledText `json:",omitempty"`
|
||||
// }
|
||||
//
|
||||
// // Parse ANSI text
|
||||
// var styledLabel []*ansi.StyledText
|
||||
// tempLabel := trayMenu.Label
|
||||
// if strings.Contains(tempLabel, "\033[") {
|
||||
// parsedLabel, err := ansi.Parse(tempLabel)
|
||||
// if err == nil {
|
||||
// styledLabel = parsedLabel
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// update := &LabelUpdate{
|
||||
// ID: trayID,
|
||||
// Label: trayMenu.Label,
|
||||
// FontName: trayMenu.FontName,
|
||||
// FontSize: trayMenu.FontSize,
|
||||
// Disabled: trayMenu.Disabled,
|
||||
// Tooltip: trayMenu.Tooltip,
|
||||
// Image: trayMenu.Image,
|
||||
// MacTemplateImage: trayMenu.MacTemplateImage,
|
||||
// RGBA: trayMenu.RGBA,
|
||||
// StyledLabel: styledLabel,
|
||||
// }
|
||||
//
|
||||
// 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 {
|
||||
// JSON, err := contextMenu.AsJSON()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// result = append(result, JSON)
|
||||
// }
|
||||
//
|
||||
// return result, nil
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,32 @@ import (
|
|||
)
|
||||
|
||||
type TrayMenuAdd interface {
|
||||
TrayMenuAdd(menu *TrayMenu)
|
||||
TrayMenuAdd(menu *TrayMenu) TrayMenuImpl
|
||||
}
|
||||
|
||||
type TrayMenuImpl interface {
|
||||
SetLabel(string)
|
||||
SetImage(*TrayImage)
|
||||
}
|
||||
|
||||
type ImagePosition int
|
||||
|
||||
const (
|
||||
NSImageLeading ImagePosition = 0
|
||||
NSImageOnly ImagePosition = 1
|
||||
NSImageLeft ImagePosition = 2
|
||||
NSImageRight ImagePosition = 3
|
||||
NSImageBelow ImagePosition = 4
|
||||
NSImageAbove ImagePosition = 5
|
||||
NSImageOverlaps ImagePosition = 6
|
||||
NSNoImage ImagePosition = 7
|
||||
NSImageTrailing ImagePosition = 8
|
||||
)
|
||||
|
||||
type TrayImage struct {
|
||||
Image []byte
|
||||
IsTemplate bool
|
||||
Position ImagePosition
|
||||
}
|
||||
|
||||
// TrayMenu are the options
|
||||
|
|
@ -17,12 +42,7 @@ type TrayMenu struct {
|
|||
// Label is the text we wish to display in the tray
|
||||
Label string
|
||||
|
||||
// Image is the name of the tray icon we wish to display.
|
||||
// These are read up during build from <projectdir>/trayicons and
|
||||
// the filenames are used as IDs, minus the extension
|
||||
// EG: <projectdir>/trayicons/main.png can be referenced here with "main"
|
||||
// If the image is not a filename, it will be treated as base64 image data
|
||||
Image string
|
||||
Image *TrayImage
|
||||
|
||||
// MacTemplateImage indicates that on a Mac, this image is a template image
|
||||
MacTemplateImage bool
|
||||
|
|
@ -51,22 +71,39 @@ type TrayMenu struct {
|
|||
|
||||
// OnClose is called when the Menu is closed
|
||||
OnClose func()
|
||||
|
||||
impl TrayMenuImpl
|
||||
}
|
||||
|
||||
func NewTrayMenu(ctx context.Context) *TrayMenu {
|
||||
return &TrayMenu{
|
||||
ctx: ctx,
|
||||
func NewTrayMenu() *TrayMenu {
|
||||
return &TrayMenu{}
|
||||
}
|
||||
|
||||
func (t *TrayMenu) Show(ctx context.Context) {
|
||||
if ctx == nil {
|
||||
log.Fatal("TrayMenu.Show() called before Run()")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TrayMenu) Show() {
|
||||
result := t.ctx.Value("frontend")
|
||||
t.ctx = ctx
|
||||
result := ctx.Value("frontend")
|
||||
if result == nil {
|
||||
pc, _, _, _ := goruntime.Caller(1)
|
||||
funcName := goruntime.FuncForPC(pc).Name()
|
||||
log.Fatalf("invalid context at '%s'", funcName)
|
||||
}
|
||||
println("\n\n\n\nFWEFWEFWFE")
|
||||
result.(TrayMenuAdd).TrayMenuAdd(t)
|
||||
t.impl = result.(TrayMenuAdd).TrayMenuAdd(t)
|
||||
|
||||
}
|
||||
|
||||
func (t *TrayMenu) SetLabel(label string) {
|
||||
t.Label = label
|
||||
if t.impl != nil {
|
||||
t.impl.SetLabel(label)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TrayMenu) SetImage(image *TrayImage) {
|
||||
t.Image = image
|
||||
if t.impl != nil {
|
||||
t.impl.SetImage(image)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,10 +56,9 @@ type App struct {
|
|||
|
||||
//ContextMenus []*menu.ContextMenu
|
||||
//TrayMenus []*menu.TrayMenu
|
||||
Windows *windows.Options
|
||||
Mac *mac.Options
|
||||
Linux *linux.Options
|
||||
TrayMenu *menu.TrayMenu
|
||||
Windows *windows.Options
|
||||
Mac *mac.Options
|
||||
Linux *linux.Options
|
||||
}
|
||||
|
||||
type RGBA struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue