diff --git a/cef/cef-sys-menu.go b/cef/cef-sys-menu.go index addec406..24382a1f 100644 --- a/cef/cef-sys-menu.go +++ b/cef/cef-sys-menu.go @@ -8,7 +8,12 @@ package cef -import "energye/systray" +import ( + "energye/systray" + "github.com/energye/golcl/energy/emfs" + "github.com/energye/golcl/energy/tools" + "io/ioutil" +) type MenuItemClick func() @@ -42,20 +47,41 @@ func (m *SysMenu) Add(menuItem *SysMenuItem) { m.items = append(m.items, menuItem) } -func (m *SysMenu) AddMenuItemSeparator() { +func (m *SysMenu) AddSeparator() { m.items = append(m.items, &SysMenuItem{isSeparator: true}) } -func (m *SysMenuItem) AddSubMenu(label string, action MenuItemClick) *SysMenuItem { +func (m *SysMenuItem) AddSubMenu(label string, click ...MenuItemClick) *SysMenuItem { if m.childMenu == nil { m.childMenu = &SysMenu{ items: make([]*SysMenuItem, 0, 0), } } - return m.childMenu.AddMenuItem(label, action) + if len(click) > 0 { + return m.childMenu.AddMenuItem(label, click[0]) + } + return m.childMenu.AddMenuItem(label, nil) } -func (m *SysMenuItem) SetIcon(v []byte) { +func (m *SysMenuItem) SetIconFS(iconResourcePath string) { + if emfs.IsExist(iconResourcePath) { + data, err := emfs.GetResources(iconResourcePath) + if err == nil { + m.SetIconBytes(data) + } + } +} + +func (m *SysMenuItem) SetIcon(iconResourcePath string) { + if tools.IsExist(iconResourcePath) { + data, err := ioutil.ReadFile(iconResourcePath) + if err == nil { + m.SetIconBytes(data) + } + } +} + +func (m *SysMenuItem) SetIconBytes(v []byte) { m.icon = v if m.menuItem != nil { m.menuItem.SetIcon(v) @@ -85,12 +111,14 @@ func (m *SysMenuItem) Checked() bool { } func (m *SysMenuItem) Check() { + m.checked = true if m.menuItem != nil { m.menuItem.Check() } } func (m *SysMenuItem) Uncheck() { + m.checked = false if m.menuItem != nil { m.menuItem.Uncheck() } @@ -159,6 +187,10 @@ func (m *SysMenuItem) Label() string { return m.label } +func (m *SysMenuItem) Click(fn MenuItemClick) { + m.click = fn +} + func itemForMenuItem(item *SysMenuItem, parent *systray.MenuItem) *systray.MenuItem { if item == nil || item.isSeparator { systray.AddSeparator() @@ -185,5 +217,8 @@ func itemForMenuItem(item *SysMenuItem, parent *systray.MenuItem) *systray.MenuI mItem.SetIcon(item.icon) } item.menuItem = mItem + if item.click != nil { + item.menuItem.Click(item.click) + } return mItem } diff --git a/cef/cef-tray-sys-commponent.go b/cef/cef-tray-sys-commponent.go index 48f45982..e5a66dd6 100644 --- a/cef/cef-tray-sys-commponent.go +++ b/cef/cef-tray-sys-commponent.go @@ -205,16 +205,22 @@ func (m *SysTray) Add(menuItem *SysMenuItem) { } //AddMenuItem 添加一个菜单项 -func (m *SysTray) AddMenuItem(label string, onClick MenuItemClick) *SysMenuItem { - return m.menu.AddMenuItem(label, onClick) +func (m *SysTray) AddMenuItem(label string, click ...MenuItemClick) *SysMenuItem { + if len(click) > 0 { + return m.menu.AddMenuItem(label, click[0]) + } + return m.menu.AddMenuItem(label, nil) } -//AddMenuItemSeparator 添加一个分隔线 -func (m *SysTray) AddMenuItemSeparator() { - m.menu.AddMenuItemSeparator() +//AddSeparator 添加一个分隔线 +func (m *SysTray) AddSeparator() { + m.menu.AddSeparator() } //NewMenuItem 创建一个新菜单项 -func (m *SysTray) NewMenuItem(label string, onClick MenuItemClick) *SysMenuItem { - return &SysMenuItem{label: label, click: onClick} +func (m *SysTray) NewMenuItem(label string, click ...MenuItemClick) *SysMenuItem { + if len(click) > 0 { + return &SysMenuItem{label: label, click: click[0]} + } + return &SysMenuItem{label: label} } diff --git a/example/dev-test/lcl-browser/lcl-browser.go b/example/dev-test/lcl-browser/lcl-browser.go index bc1ea972..cd3d2589 100644 --- a/example/dev-test/lcl-browser/lcl-browser.go +++ b/example/dev-test/lcl-browser/lcl-browser.go @@ -97,26 +97,49 @@ func sysTray(browserWindow cef.IBrowserWindow) { fmt.Println("SetOnClick") }) tray := sysTray.AsSysTray() - tray.AddMenuItem("1级菜单1", nil) - tray.AddMenuItemSeparator() - item := tray.AddMenuItem("1级菜单2", nil) - item.AddSubMenu("2级子菜单1", nil) - sub2Menu := item.AddSubMenu("2级子菜单2", nil) - sub2Menu.AddSubMenu("3级子菜单1", nil) + check := tray.AddMenuItem("check") + check.Check() + enable := tray.AddMenuItem("启用/禁用") + enable.Click(func() { + fmt.Println("启用/禁用 点击") + }) + tray.AddSeparator() + menuItem := tray.AddMenuItem("1级菜单1", func() { + fmt.Println("1级菜单1") + }) + menuItem.SetIconFS("resources/icon.ico") + tray.AddSeparator() + item := tray.AddMenuItem("1级菜单2") + item.AddSubMenu("2级子菜单1") + sub2Menu := item.AddSubMenu("2级子菜单2") + sub2Menu.AddSubMenu("3级子菜单1") + tray.AddSeparator() + tray.AddMenuItem("退出", func() { + fmt.Println("退出") + browserWindow.CloseBrowserWindow() + }) sysTray.Show() + //测试图标切换 go func() { var b bool for { - time.Sleep(time.Second) + time.Sleep(time.Second * 2) b = !b - fmt.Println("bool", b) if b { sysTray.SetHint(fmt.Sprintf("%d\n%v", time.Now().Second(), b)) sysTray.SetIconFS("resources/icon_1.ico") + menuItem.SetIconFS("resources/icon_1.ico") + enable.SetLabel(fmt.Sprintf("%d\n%v", time.Now().Second(), b)) + enable.Enable() + check.Check() } else { sysTray.SetHint(fmt.Sprintf("%d\n%v", time.Now().Second(), b)) sysTray.SetIconFS("resources/icon.ico") + menuItem.SetIconFS("resources/icon.ico") + enable.SetLabel(fmt.Sprintf("%d\n%v", time.Now().Second(), b)) + enable.Disable() + check.Uncheck() } } }() diff --git a/vendor/energye/systray/systray.go b/vendor/energye/systray/systray.go index 050fd529..2e836661 100644 --- a/vendor/energye/systray/systray.go +++ b/vendor/energye/systray/systray.go @@ -32,7 +32,7 @@ type IMenu interface { // Don't create it directly, use the one systray.AddMenuItem() returned type MenuItem struct { // ClickedCh is the channel which will be notified when the menu item is clicked - ClickedCh chan struct{} + click func() // id uniquely identify a menu item, not supposed to be modified id uint32 @@ -52,6 +52,10 @@ type MenuItem struct { parent *MenuItem } +func (item *MenuItem) Click(fn func()) { + item.click = fn +} + func (item *MenuItem) String() string { if item.parent == nil { return fmt.Sprintf("MenuItem[%d, %q]", item.id, item.title) @@ -62,7 +66,6 @@ func (item *MenuItem) String() string { // newMenuItem returns a populated MenuItem object func newMenuItem(title string, tooltip string, parent *MenuItem) *MenuItem { return &MenuItem{ - ClickedCh: make(chan struct{}), id: atomic.AddUint32(¤tID, 1), title: title, tooltip: tooltip, @@ -274,9 +277,7 @@ func systrayMenuItemSelected(id uint32) { log.Printf("systray error: no menu item with ID %d\n", id) return } - select { - case item.ClickedCh <- struct{}{}: - // in case no one waiting for the channel - default: + if item.click != nil { + item.click() } }