Support checkbox logic. Support duplicate checkboxes

This commit is contained in:
Lea Anthony 2022-10-07 20:02:58 +11:00
commit b5478e52db
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
5 changed files with 76 additions and 25 deletions

3
.gitignore vendored
View file

@ -32,4 +32,5 @@ v2/cmd/wails/internal/commands/initialise/templates/testtemplates/
.env
/website/static/img/.cache.json
v2/internal/frontend/desktop/darwin/test.xcodeproj
v2/internal/frontend/desktop/darwin/test.xcodeproj
TODO.md

View file

@ -7,10 +7,11 @@ import (
)
type PopupMenu struct {
menu win32.HMENU
parent win32.HWND
menuMapping map[int]*menu.MenuItem
menuData *menu.Menu
menu win32.HMENU
parent win32.HWND
menuMapping map[int]*menu.MenuItem
checkboxItems map[*menu.MenuItem][]int
menuData *menu.Menu
}
func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, startindex int) error {
@ -45,6 +46,9 @@ func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, star
}
p.menuMapping[itemID] = item
if item.IsCheckbox() {
p.checkboxItems[item] = append(p.checkboxItems[item], itemID)
}
ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(itemID), item.Label)
if ret == false {
return errors.New("AppendMenu failed")
@ -60,9 +64,10 @@ func (p *PopupMenu) Update() error {
func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) {
result := &PopupMenu{
parent: parent,
menuData: inputMenu,
menuMapping: make(map[int]*menu.MenuItem),
parent: parent,
menuData: inputMenu,
menuMapping: make(map[int]*menu.MenuItem),
checkboxItems: make(map[*menu.MenuItem][]int),
}
err := result.Update()
return result, err
@ -92,7 +97,20 @@ func (p *PopupMenu) ShowAtCursor() error {
func (p *PopupMenu) ProcessCommand(cmdMsgID int) {
item := p.menuMapping[cmdMsgID]
if item != nil {
item.Click(&menu.CallbackData{MenuItem: item})
if item.Type == menu.CheckboxType {
item.Checked = !item.Checked
var checkState uint = win32.MF_UNCHECKED
if item.Checked {
checkState = win32.MF_CHECKED
}
for _, menuID := range p.checkboxItems[item] {
win32.CheckMenuItem(p.menu, int32(menuID), checkState)
}
// TODO: Check duplicate menu items
}
if item.Click != nil {
item.Click(&menu.CallbackData{MenuItem: item})
}
}
}

View file

@ -21,6 +21,7 @@ var (
procTrackPopupMenu = moduser32.NewProc("TrackPopupMenu")
procDestroyMenu = moduser32.NewProc("DestroyMenu")
procAppendMenuW = moduser32.NewProc("AppendMenuW")
procCheckMenuItem = moduser32.NewProc("CheckMenuItem")
procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx")
procGetMessageW = moduser32.NewProc("GetMessageW")
procIsDialogMessage = moduser32.NewProc("IsDialogMessageW")
@ -104,6 +105,7 @@ const (
MF_GRAYED = 0x00000001
MF_DISABLED = 0x00000002
MF_SEPARATOR = 0x00000800
MF_UNCHECKED = 0x00000000
MF_CHECKED = 0x00000008
MF_POPUP = 0x00000010
MF_MENUBARBREAK = 0x00000020

View file

@ -32,3 +32,12 @@ func AppendMenu(menu HMENU, flags uintptr, id uintptr, text string) bool {
)
return ret != 0
}
func CheckMenuItem(menu HMENU, id int32, flags uint) uint {
ret, _, _ := procCheckMenuItem.Call(
uintptr(menu),
uintptr(id),
uintptr(flags),
)
return uint(ret)
}

View file

@ -6,11 +6,6 @@ import (
"github.com/wailsapp/wails/v2/pkg/menu/keys"
)
type MenuItemImpl interface {
SetChecked(bool)
SetLabel(string)
}
// MenuItem represents a menuitem contained in a menu
type MenuItem struct {
// Label is what appears as the menu text
@ -58,9 +53,6 @@ type MenuItem struct {
// Used for locking when removing elements
removeLock sync.Mutex
// Implementation of the runtime methods
Impl MenuItemImpl
}
// Parent returns the parent of the menu item.
@ -224,25 +216,54 @@ func (m *MenuItem) insertItemAtIndex(index int, target *MenuItem) bool {
return true
}
func (m *MenuItem) SetChecked(b bool) {
if m.Checked != b {
m.Checked = b
m.Impl.SetChecked(b)
}
}
func (m *MenuItem) SetLabel(name string) {
if m.Label == name {
return
}
m.Label = name
m.Impl.SetLabel(name)
}
func (m *MenuItem) IsSeparator() bool {
return m.Type == SeparatorType
}
func (m *MenuItem) IsCheckbox() bool {
return m.Type == CheckboxType
}
func (m *MenuItem) Disable() *MenuItem {
m.Disabled = true
return m
}
func (m *MenuItem) Enable() *MenuItem {
m.Disabled = false
return m
}
func (m *MenuItem) OnClick(click Callback) *MenuItem {
m.Click = click
return m
}
func (m *MenuItem) SetAccelerator(acc *keys.Accelerator) *MenuItem {
m.Accelerator = acc
return m
}
func (m *MenuItem) SetChecked(value bool) *MenuItem {
m.Checked = value
m.Type = CheckboxType
return m
}
func Label(label string) *MenuItem {
return &MenuItem{
Type: TextType,
Label: label,
}
}
// Text is a helper to create basic Text menu items
func Text(label string, accelerator *keys.Accelerator, click Callback) *MenuItem {
return &MenuItem{