Compare commits

...

9 Commits

Author SHA1 Message Date
Lea Anthony
d923e84456 v2.0.0-alpha.14 2021-01-23 21:00:04 +11:00
Lea Anthony
343f573e78 Fix menu tooltips 2021-01-23 20:59:02 +11:00
Lea Anthony
c6d87da4f0 v2.0.0-alpha.13 2021-01-23 20:39:43 +11:00
Lea Anthony
a9faebe51a MenuItem image support 2021-01-23 20:32:42 +11:00
Lea Anthony
d436f5d1be v2.0.0-alpha.12 2021-01-23 16:22:00 +11:00
Lea Anthony
f40899821f Support ToolTips 2021-01-23 16:14:48 +11:00
Lea Anthony
2a64ed19a3 v2.0.0-alpha.11 2021-01-22 14:57:50 +11:00
Lea Anthony
47bca0be88 Support updating tray labels in an efficient manner 2021-01-16 11:35:49 +11:00
Lea Anthony
7ac8cc6b8b Add Menu.Merge() to combine 2 menus 2021-01-15 11:53:55 +11:00
24 changed files with 218 additions and 62 deletions

View File

@@ -1,3 +1,3 @@
package main package main
var version = "v2.0.0-alpha.10" var version = "v2.0.0-alpha.14"

View File

@@ -86,3 +86,10 @@ bool getJSONInt(JsonNode *item, const char* key, int *result) {
return false; 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;
}

View File

@@ -35,4 +35,6 @@ JsonNode* mustJSONObject(JsonNode *node, const char* key);
bool getJSONBool(JsonNode *item, const char* key, bool *result); bool getJSONBool(JsonNode *item, const char* key, bool *result);
bool getJSONInt(JsonNode *item, const char* key, int *result); bool getJSONInt(JsonNode *item, const char* key, int *result);
JsonNode* mustParseJSON(const char* JSON);
#endif //ASSETS_C_COMMON_H #endif //ASSETS_C_COMMON_H

View File

@@ -37,6 +37,7 @@ extern void DarkModeEnabled(struct Application*, char *callbackID);
extern void SetApplicationMenu(struct Application*, const char *); extern void SetApplicationMenu(struct Application*, const char *);
extern void AddTrayMenu(struct Application*, const char *menuTrayJSON); extern void AddTrayMenu(struct Application*, const char *menuTrayJSON);
extern void SetTrayMenu(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 AddContextMenu(struct Application*, char *contextMenuJSON);
extern void UpdateContextMenu(struct Application*, char *contextMenuJSON); extern void UpdateContextMenu(struct Application*, char *contextMenuJSON);

View File

@@ -192,6 +192,10 @@ func (c *Client) SetTrayMenu(trayMenuJSON string) {
C.SetTrayMenu(c.app.app, c.app.string2CString(trayMenuJSON)) 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) { func (c *Client) UpdateContextMenu(contextMenuJSON string) {
C.UpdateContextMenu(c.app.app, c.app.string2CString(contextMenuJSON)) C.UpdateContextMenu(c.app.app, c.app.string2CString(contextMenuJSON))
} }

View File

@@ -913,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) { void AddContextMenu(struct Application *app, const char *contextMenuJSON) {
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON); AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
} }
@@ -932,6 +933,13 @@ void SetTrayMenu(struct Application *app, const char* trayMenuJSON) {
); );
} }
void UpdateTrayMenuLabel(struct Application* app, const char* JSON) {
ON_MAIN_THREAD(
UpdateTrayMenuLabelInStore(app->trayMenuStore, JSON);
);
}
void SetBindings(struct Application *app, const char *bindings) { void SetBindings(struct Application *app, const char *bindings) {
const char* temp = concat("window.wailsbindings = \"", bindings); const char* temp = concat("window.wailsbindings = \"", bindings);
const char* jscall = concat(temp, "\";"); const char* jscall = concat(temp, "\";");

View File

@@ -107,7 +107,7 @@ void SetAppearance(struct Application* app, const char *);
void WebviewIsTransparent(struct Application* app); void WebviewIsTransparent(struct Application* app);
void WindowBackgroundIsTranslucent(struct Application* app); void WindowBackgroundIsTranslucent(struct Application* app);
void SetTray(struct Application* app, const char *, const char *, const char *); 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 *); void AddTrayMenu(struct Application* app, const char *);
#endif #endif

View File

@@ -63,8 +63,6 @@ MenuItemCallbackData* CreateMenuItemCallbackData(Menu *menu, id menuItem, const
return result; return result;
} }
void DeleteMenu(Menu *menu) { void DeleteMenu(Menu *menu) {
// Free menu item hashmap // Free menu item hashmap
@@ -99,7 +97,11 @@ void DeleteMenu(Menu *menu) {
// Creates a JSON message for the given menuItemID and data // 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) { const char* createMenuClickedMessage(const char *menuItemID, const char *data, enum MenuType menuType, const char *parentID) {
JsonNode *jsonObject = json_mkobject(); 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, "menuItemID", json_mkstring(menuItemID));
json_append_member(jsonObject, "menuType", json_mkstring(MenuTypeAsString[(int)menuType])); json_append_member(jsonObject, "menuType", json_mkstring(MenuTypeAsString[(int)menuType]));
if (data != NULL) { if (data != NULL) {
@@ -572,7 +574,7 @@ id processCheckboxMenuItem(Menu *menu, id parentmenu, const char *title, const c
return item; 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"); id item = ALLOC("NSMenuItem");
// Create a MenuItemCallbackData // 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), msg(item, s("initWithTitle:action:keyEquivalent:"), str(title),
s("menuItemCallback:"), key); 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("setEnabled:"), !disabled);
msg(item, s("autorelease")); msg(item, s("autorelease"));
@@ -666,6 +680,9 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
const char *acceleratorkey = NULL; const char *acceleratorkey = NULL;
const char **modifiers = NULL; const char **modifiers = NULL;
const char *tooltip = getJSONString(item, "Tooltip");
const char *image = getJSONString(item, "Image");
// If we have an accelerator // If we have an accelerator
if( accelerator != NULL ) { if( accelerator != NULL ) {
// Get the key // Get the key
@@ -698,7 +715,7 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
if( type != NULL ) { if( type != NULL ) {
if( STREQ(type->string_, "Text")) { 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")) { else if ( STREQ(type->string_, "Separator")) {
addSeparator(parentMenu); addSeparator(parentMenu);

View File

@@ -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 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 processMenuItem(Menu *menu, id parentMenu, JsonNode *item);
void processMenuData(Menu *menu, JsonNode *menuData); void processMenuData(Menu *menu, JsonNode *menuData);

View File

@@ -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 ); 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 void UpdateTrayLabel(TrayMenu *trayMenu, const char *label) {
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) {
// Exit early if NULL // Exit early if NULL
if( trayMenu->label == NULL ) { if( trayMenu->label == NULL ) {
return; return;
} }
// We don't check for a // Update button label
id statusBarButton = msg(trayMenu->statusbaritem, s("button")); 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 // Exit early if NULL
if( trayMenu->icon == NULL ) { if( trayMenu->icon == NULL ) {
@@ -105,6 +82,32 @@ void UpdateTrayMenuIcon(TrayMenu *trayMenu) {
msg(statusBarButton, s("setImage:"), trayImage); 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 // UpdateTrayMenuInPlace receives 2 menus. The current menu gets
// updated with the data from the new menu. // updated with the data from the new menu.
void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu) { void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu) {

View File

@@ -27,8 +27,8 @@ TrayMenu* NewTrayMenu(const char *trayJSON);
void DumpTrayMenu(TrayMenu* trayMenu); void DumpTrayMenu(TrayMenu* trayMenu);
void ShowTrayMenu(TrayMenu* trayMenu); void ShowTrayMenu(TrayMenu* trayMenu);
void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu); void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu);
void UpdateTrayMenuIcon(TrayMenu *trayMenu); void UpdateTrayIcon(TrayMenu *trayMenu);
void UpdateTrayMenuLabel(TrayMenu *trayMenu); void UpdateTrayLabel(TrayMenu *trayMenu, const char*);
void LoadTrayIcons(); void LoadTrayIcons();
void UnloadTrayIcons(); void UnloadTrayIcons();

View File

@@ -72,15 +72,39 @@ TrayMenu* GetTrayMenuFromStore(TrayMenuStore* store, const char* menuID) {
return hashmap_get(&store->trayMenuMap, menuID, strlen(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) { void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON) {
TrayMenu* newMenu = NewTrayMenu(menuJSON); TrayMenu* newMenu = NewTrayMenu(menuJSON);
DumpTrayMenu(newMenu);
// Get the current menu // Get the current menu
TrayMenu *currentMenu = GetTrayMenuFromStore(store, newMenu->ID); TrayMenu *currentMenu = GetTrayMenuFromStore(store, newMenu->ID);
// If we don't have a menu, we create one // If we don't have a menu, we create one
if ( currentMenu == NULL ) { if ( currentMenu == NULL ) {
printf(" currentMenu = NULL\n");
// Store the new menu // Store the new menu
hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu); hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
@@ -88,6 +112,7 @@ void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON) {
ShowTrayMenu(newMenu); ShowTrayMenu(newMenu);
return; return;
} }
DumpTrayMenu(currentMenu);
// Save the status bar reference // Save the status bar reference
newMenu->statusbaritem = currentMenu->statusbaritem; newMenu->statusbaritem = currentMenu->statusbaritem;
@@ -98,12 +123,6 @@ void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON) {
DeleteMenu(currentMenu->menu); DeleteMenu(currentMenu->menu);
currentMenu->menu = NULL; currentMenu->menu = NULL;
// Free JSON
if (currentMenu->processedJSON != NULL ) {
json_delete(currentMenu->processedJSON);
currentMenu->processedJSON = NULL;
}
// Free the tray menu memory // Free the tray menu memory
MEMFREE(currentMenu); MEMFREE(currentMenu);

View File

@@ -22,4 +22,6 @@ void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON);
void ShowTrayMenusInStore(TrayMenuStore* store); void ShowTrayMenusInStore(TrayMenuStore* store);
void DeleteTrayMenuStore(TrayMenuStore* store); void DeleteTrayMenuStore(TrayMenuStore* store);
void UpdateTrayMenuLabelInStore(TrayMenuStore* store, const char* JSON);
#endif //TRAYMENUSTORE_DARWIN_H #endif //TRAYMENUSTORE_DARWIN_H

View File

@@ -9,28 +9,35 @@ import (
type ProcessedMenuItem struct { type ProcessedMenuItem struct {
ID string ID string
// Label is what appears as the menu text // Label is what appears as the menu text
Label string Label string `json:",omitempty"`
// Role is a predefined menu type // 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 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 of MenuItem, EG: Checkbox, Text, Separator, Radio, Submenu
Type menu.Type Type menu.Type
// Disabled makes the item unselectable // Disabled makes the item unselectable
Disabled bool Disabled bool `json:",omitempty"`
// Hidden ensures that the item is not shown in the menu // 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 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 contains a list of menu items that will be shown as a submenu
//SubMenu []*MenuItem `json:"SubMenu,omitempty"` //SubMenu []*MenuItem `json:"SubMenu,omitempty"`
SubMenu *ProcessedMenu `json:"SubMenu,omitempty"` SubMenu *ProcessedMenu `json:",omitempty"`
// Foreground colour in hex RGBA format EG: 0xFF0000FF = #FF0000FF = red // Colour
Foreground int RGBA string `json:",omitempty"`
// Background colour // Font
Background int 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 { func NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu.MenuItem) *ProcessedMenuItem {
@@ -45,8 +52,12 @@ func NewProcessedMenuItem(menuItemMap *MenuItemMap, menuItem *menu.MenuItem) *Pr
Disabled: menuItem.Disabled, Disabled: menuItem.Disabled,
Hidden: menuItem.Hidden, Hidden: menuItem.Hidden,
Checked: menuItem.Checked, Checked: menuItem.Checked,
Foreground: menuItem.Foreground, SubMenu: nil,
Background: menuItem.Background, RGBA: menuItem.RGBA,
FontSize: menuItem.FontSize,
FontName: menuItem.FontName,
Image: menuItem.Image,
Tooltip: menuItem.Tooltip,
} }
if menuItem.SubMenu != nil { if menuItem.SubMenu != nil {

View File

@@ -3,6 +3,7 @@ package menumanager
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/pkg/errors"
"github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/menu"
"sync" "sync"
) )
@@ -94,6 +95,31 @@ func (m *Manager) GetTrayMenus() ([]string, error) {
return result, nil 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) { func (m *Manager) GetContextMenus() ([]string, error) {
result := []string{} result := []string{}
for _, contextMenu := range m.contextMenus { for _, contextMenu := range m.contextMenus {

View File

@@ -32,6 +32,7 @@ type Client interface {
DarkModeEnabled(callbackID string) DarkModeEnabled(callbackID string)
SetApplicationMenu(menuJSON string) SetApplicationMenu(menuJSON string)
SetTrayMenu(trayMenuJSON string) SetTrayMenu(trayMenuJSON string)
UpdateTrayMenuLabel(JSON string)
UpdateContextMenu(contextMenuJSON string) UpdateContextMenu(contextMenuJSON string)
} }

View File

@@ -473,6 +473,20 @@ func (d *Dispatcher) processMenuMessage(result *servicebus.Message) {
client.frontend.UpdateContextMenu(updatedContextMenu) 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: default:
d.logger.Error("Unknown menufrontend command: %s", command) d.logger.Error("Unknown menufrontend command: %s", command)
} }

View File

@@ -10,6 +10,7 @@ type Menu interface {
UpdateApplicationMenu() UpdateApplicationMenu()
UpdateContextMenu(contextMenu *menu.ContextMenu) UpdateContextMenu(contextMenu *menu.ContextMenu)
SetTrayMenu(trayMenu *menu.TrayMenu) SetTrayMenu(trayMenu *menu.TrayMenu)
UpdateTrayMenuLabel(trayMenu *menu.TrayMenu)
} }
type menuRuntime struct { type menuRuntime struct {
@@ -34,3 +35,7 @@ func (m *menuRuntime) UpdateContextMenu(contextMenu *menu.ContextMenu) {
func (m *menuRuntime) SetTrayMenu(trayMenu *menu.TrayMenu) { func (m *menuRuntime) SetTrayMenu(trayMenu *menu.TrayMenu) {
m.bus.Publish("menu:settraymenu", trayMenu) m.bus.Publish("menu:settraymenu", trayMenu)
} }
func (m *menuRuntime) UpdateTrayMenuLabel(trayMenu *menu.TrayMenu) {
m.bus.Publish("menu:updatetraymenulabel", trayMenu)
}

View File

@@ -131,6 +131,17 @@ func (m *Menu) Start() error {
// Notify frontend of menu change // Notify frontend of menu change
m.bus.Publish("menufrontend:settraymenu", 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: default:
m.logger.Error("unknown menu message: %+v", menuMessage) m.logger.Error("unknown menu message: %+v", menuMessage)
} }

View File

@@ -211,7 +211,6 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
options.CompiledBinary = compiledBinary options.CompiledBinary = compiledBinary
// Create the command // Create the command
fmt.Printf("Compile command: %+v", commands.AsSlice())
cmd := exec.Command(options.Compiler, commands.AsSlice()...) cmd := exec.Command(options.Compiler, commands.AsSlice()...)
// Set the directory // Set the directory

View File

@@ -12,6 +12,14 @@ func (m *Menu) Append(item *MenuItem) {
m.Items = append(m.Items, item) 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) { func (m *Menu) Prepend(item *MenuItem) {
m.Items = append([]*MenuItem{item}, m.Items...) m.Items = append([]*MenuItem{item}, m.Items...)
} }

View File

@@ -28,11 +28,18 @@ type MenuItem struct {
// Callback function when menu clicked // Callback function when menu clicked
Click Callback `json:"-"` Click Callback `json:"-"`
// Foreground colour in hex RGBA format EG: 0xFF0000FF = #FF0000FF = red // Colour
Foreground int RGBA string
// Background colour // Font
Background int FontSize int
FontName string
// Image - base64 image data
Image string
// Tooltip
Tooltip string
// This holds the menu item's parent. // This holds the menu item's parent.
parent *MenuItem parent *MenuItem

10
v2/pkg/str/str.go Normal file
View File

@@ -0,0 +1,10 @@
package str
import (
"fmt"
"time"
)
func UnixNow() string {
return fmt.Sprintf("%+v", time.Now().Unix())
}

View File

@@ -58,6 +58,7 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= 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/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/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=