Tray menu callbacks working

This commit is contained in:
Lea Anthony 2020-12-07 07:08:15 +11:00
commit 0802d0d57a
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
8 changed files with 211 additions and 8 deletions

View file

@ -19,6 +19,7 @@ var messageParsers = map[byte]func(string) (*parsedMessage, error){
'D': dialogMessageParser,
'S': systemMessageParser,
'M': menuMessageParser,
'T': trayMessageParser,
}
// Parse will attempt to parse the given message

View file

@ -0,0 +1,43 @@
package message
import (
"fmt"
"github.com/wailsapp/wails/v2/pkg/menu"
)
// TrayOnMessage is used to emit listener registration requests
// on the service bus
type TrayOnMessage struct {
// MenuID is the id of the menu item we are interested in
MenuID string
// Callback is called when the menu is clicked
Callback func(*menu.MenuItem)
}
// trayMessageParser does what it says on the tin!
func trayMessageParser(message string) (*parsedMessage, error) {
// Sanity check: Menu messages must be at least 2 bytes
if len(message) < 3 {
return nil, fmt.Errorf("event message was an invalid length")
}
var topic string
var data interface{}
// Switch the message type
switch message[1] {
case 'C':
callbackid := message[2:]
topic = "tray:clicked"
data = callbackid
default:
return nil, fmt.Errorf("invalid menu message: %s", message)
}
// Create a new parsed message struct
parsedMessage := &parsedMessage{Topic: topic, Data: data}
return parsedMessage, nil
}

View file

@ -13,6 +13,7 @@ type Runtime struct {
Dialog Dialog
System System
Menu Menu
Tray Tray
Store *StoreProvider
Log Log
bus *servicebus.ServiceBus
@ -27,6 +28,7 @@ func New(serviceBus *servicebus.ServiceBus, menu *menu.Menu) *Runtime {
Dialog: newDialog(serviceBus),
System: newSystem(serviceBus),
Menu: newMenu(serviceBus, menu),
Tray: newTray(serviceBus, menu),
Log: newLog(serviceBus),
bus: serviceBus,
}

View file

@ -0,0 +1,48 @@
package runtime
import (
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
"github.com/wailsapp/wails/v2/internal/servicebus"
"github.com/wailsapp/wails/v2/pkg/menu"
)
// Tray defines all Tray related operations
type Tray interface {
On(menuID string, callback func(*menu.MenuItem))
Update()
GetByID(menuID string) *menu.MenuItem
RemoveByID(id string) bool
}
type trayRuntime struct {
bus *servicebus.ServiceBus
trayMenu *menu.Menu
}
// newTray creates a new Menu struct
func newTray(bus *servicebus.ServiceBus, menu *menu.Menu) Menu {
return &trayRuntime{
bus: bus,
trayMenu: menu,
}
}
// On registers a listener for a particular event
func (t *trayRuntime) On(menuID string, callback func(*menu.MenuItem)) {
t.bus.Publish("tray:on", &message.TrayOnMessage{
MenuID: menuID,
Callback: callback,
})
}
func (t *trayRuntime) Update() {
t.bus.Publish("tray:update", t.trayMenu)
}
func (t *trayRuntime) GetByID(menuID string) *menu.MenuItem {
return t.trayMenu.GetByID(menuID)
}
func (t *trayRuntime) RemoveByID(id string) bool {
return t.trayMenu.RemoveByID(id)
}

View file

@ -87,7 +87,7 @@ func (t *Tray) Start() error {
t.logger.Error("Received clicked message with invalid topic format. Expected 2 sections in topic, got %s", splitTopic)
continue
}
t.logger.Trace("Got Menu clicked Message: %s %+v", menuMessage.Topic(), menuMessage.Data())
t.logger.Trace("Got Tray Menu clicked Message: %s %+v", menuMessage.Topic(), menuMessage.Data())
menuid := menuMessage.Data().(string)
// Get the menu item
@ -106,7 +106,7 @@ func (t *Tray) Start() error {
// Notify listeners
t.notifyListeners(menuid, menuItem)
case "on":
listenerDetails := menuMessage.Data().(*message.MenuOnMessage)
listenerDetails := menuMessage.Data().(*message.TrayOnMessage)
id := listenerDetails.MenuID
t.listeners[id] = append(t.listeners[id], listenerDetails.Callback)

View file

@ -39,6 +39,7 @@ func main() {
app.Bind(&Dialog{})
app.Bind(&Window{})
app.Bind(&Menu{})
app.Bind(&Tray{})
err = app.Run()
if err != nil {

View file

@ -213,12 +213,6 @@ func (m *Menu) insertAfterRandom(_ *menu.MenuItem) {
m.runtime.Menu.Update()
}
func createApplicationTray() *menu.Menu {
trayMenu := &menu.Menu{}
trayMenu.Append(menu.Text("Hello from the tray!", "hi"))
return trayMenu
}
func createApplicationMenu() *menu.Menu {
// Create menu

114
v2/test/kitchensink/tray.go Normal file
View file

@ -0,0 +1,114 @@
package main
import (
"strconv"
"sync"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/menu"
)
// Tray struct
type Tray struct {
runtime *wails.Runtime
dynamicMenuCounter int
lock sync.Mutex
dynamicMenuItems map[string]*menu.MenuItem
anotherDynamicMenuCounter int
}
// WailsInit is called at application startup
func (t *Tray) WailsInit(runtime *wails.Runtime) error {
// Perform your setup here
t.runtime = runtime
// Setup Menu Listeners
t.runtime.Tray.On("Show Window", func(mi *menu.MenuItem) {
t.runtime.Window.Show()
})
t.runtime.Tray.On("Hide Window", func(mi *menu.MenuItem) {
t.runtime.Window.Hide()
})
return nil
}
func (t *Tray) incrementcounter() int {
t.dynamicMenuCounter++
return t.dynamicMenuCounter
}
func (t *Tray) decrementcounter() int {
t.dynamicMenuCounter--
return t.dynamicMenuCounter
}
func (t *Tray) addMenu(mi *menu.MenuItem) {
// Lock because this method will be called in a gorouting
t.lock.Lock()
defer t.lock.Unlock()
// Get this menu's parent
parent := mi.Parent()
counter := t.incrementcounter()
menuText := "Dynamic Menu Item " + strconv.Itoa(counter)
parent.Append(menu.Text(menuText, menuText))
// parent.Append(menu.TextWithAccelerator(menuText, menuText, menu.Accel("[")))
// If this is the first dynamic menu added, let's add a remove menu item
if counter == 1 {
removeMenu := menu.TextWithAccelerator("Remove "+menuText,
"Remove Last Item", menu.CmdOrCtrlAccel("-"))
parent.Prepend(removeMenu)
t.runtime.Tray.On("Remove Last Item", t.removeMenu)
} else {
removeMenu := t.runtime.Tray.GetByID("Remove Last Item")
// Test if the remove menu hasn't already been removed in another thread
if removeMenu != nil {
removeMenu.Label = "Remove " + menuText
}
}
t.runtime.Tray.Update()
}
func (t *Tray) removeMenu(_ *menu.MenuItem) {
// Lock because this method will be called in a goroutine
t.lock.Lock()
defer t.lock.Unlock()
// Get the id of the last dynamic menu
menuID := "Dynamic Menu Item " + strconv.Itoa(t.dynamicMenuCounter)
// Remove the last menu item by ID
t.runtime.Tray.RemoveByID(menuID)
// Update the counter
counter := t.decrementcounter()
// If we deleted the last dynamic menu, remove the "Remove Last Item" menu
if counter == 0 {
t.runtime.Tray.RemoveByID("Remove Last Item")
} else {
// Update label
menuText := "Dynamic Menu Item " + strconv.Itoa(counter)
removeMenu := t.runtime.Tray.GetByID("Remove Last Item")
// Test if the remove menu hasn't already been removed in another thread
if removeMenu == nil {
return
}
removeMenu.Label = "Remove " + menuText
}
// parent.Append(menu.TextWithAccelerator(menuText, menuText, menu.Accel("[")))
t.runtime.Tray.Update()
}
func createApplicationTray() *menu.Menu {
trayMenu := &menu.Menu{}
trayMenu.Append(menu.Text("Show Window", "Show Window"))
trayMenu.Append(menu.Text("Hide Window", "Hide Window"))
return trayMenu
}