This repository has been archived by the owner on Jan 25, 2022. It is now read-only.
forked from caseymrm/menuet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
menuitem.go
99 lines (88 loc) · 2.3 KB
/
menuitem.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package menuet
import (
"log"
"strings"
"time"
"github.com/caseymrm/askm"
)
// ItemType represents what type of menu item this is
type ItemType string
const (
// Regular is a normal item with text and optional callback
Regular ItemType = ""
// Separator is a horizontal line
Separator = "separator"
// Root is the top level menu directly off the menubar
Root = "root"
// TODO: StartAtLogin, Quit, Image, Spinner, etc
)
// MenuItem represents one item in the dropdown
type MenuItem struct {
Type ItemType
Text string
Image string // In Resources dir or URL, should have height 16
FontSize int // Default: 14
FontWeight FontWeight
State bool // shows checkmark when set
Clicked func() `json:"-"`
Children func() []MenuItem `json:"-"`
}
type internalItem struct {
Unique string
ParentUnique string
HasChildren bool
Clickable bool
MenuItem
}
func (a *Application) children(unique string) []internalItem {
a.visibleMenuItemsMutex.RLock()
item, ok := a.visibleMenuItems[unique]
a.visibleMenuItemsMutex.RUnlock()
if strings.HasSuffix(unique, ":root") {
// Create synthetic item
item.Unique = unique
item.Type = Root
item.Children = a.Children
ok = true
}
if !ok {
log.Printf("Item not found for children: %s", unique)
}
var items []MenuItem
if item.Children != nil {
items = item.Children()
}
internalItems := make([]internalItem, len(items))
for ind, item := range items {
a.visibleMenuItemsMutex.Lock()
newUnique := askm.ArbitraryKeyNotInMap(a.visibleMenuItems)
internal := internalItem{
Unique: newUnique,
ParentUnique: unique,
MenuItem: item,
}
if internal.Children != nil {
internal.HasChildren = true
}
if internal.Clicked != nil {
internal.Clickable = true
}
a.visibleMenuItems[newUnique] = internal
internalItems[ind] = internal
a.visibleMenuItemsMutex.Unlock()
}
return internalItems
}
func (a *Application) menuClosed(unique string) {
go func() {
// We receive menuClosed before clicked, so wait a second before discarding the data just in case
time.Sleep(100 * time.Millisecond)
a.visibleMenuItemsMutex.Lock()
for itemUnique, item := range a.visibleMenuItems {
if item.ParentUnique == unique {
delete(a.visibleMenuItems, itemUnique)
}
}
a.visibleMenuItemsMutex.Unlock()
}()
}