This repository has been archived by the owner on Dec 6, 2023. It is now read-only.
/
lists.go
144 lines (120 loc) · 3.14 KB
/
lists.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package z
import (
"strings"
)
type ISortable interface {
IsSortedPriorTo(interface{}) bool
}
type IListItem interface {
ISortable
}
type ListItemPredicate func(IListItem) bool
type ListItems []IListItem
func (me ListItems) Len() int { return len(me) }
func (me ListItems) Less(i int, j int) bool { return me[i].IsSortedPriorTo(me[j]) }
func (me ListItems) Swap(i, j int) { me[i], me[j] = me[j], me[i] }
type IList interface {
UnfilteredDesc() string
Count(ListFilters) int
FilterByID(string) *ListFilter
Filters() []*ListFilter
List(ListFilters) ListItems
}
type IListMenu interface {
IList
IMenuItems
ipcID(*ListFilter) IpcIDs
listItemsSubMenu(string, string, ListFilters) *Menu
ListItemToMenuItem(IListItem) *MenuItem
}
type ListFilters map[*ListFilter]bool
type ListFilter struct {
ID string
Disabled bool
Title string
Desc string
OnSrcLens func(*ListFilter, *SrcLens)
Pred ListItemPredicate
}
type ListBase struct {
impl IList
listFilters []*ListFilter
}
func (me *ListBase) init(impl IList) {
me.impl = impl
me.listFilters = []*ListFilter{
{Title: "All", Desc: me.impl.UnfilteredDesc()},
}
me.listFilters = append(me.listFilters, me.impl.Filters()...)
}
func (me *ListBase) Count(all ListFilters) int {
return len(me.impl.List(all))
}
func (me *ListBase) FilterByID(id string) *ListFilter {
for _, lf := range me.listFilters {
if lf.ID == id {
return lf
}
}
return nil
}
type ListMenuBase struct {
ListBase
impl IListMenu
cat string
fdesc string
items MenuItems
}
func (me *ListMenuBase) init(impl IListMenu, cat string, fdesc string) {
me.fdesc = fdesc
me.ListBase.init(impl)
me.cat, me.impl = cat, impl
for _, lf := range me.listFilters {
item := &MenuItem{Title: lf.Title, Desc: me.itemDesc(nil, lf)}
item.IpcID, item.IpcArgs = me.impl.ipcID(lf), lf.ID
me.items = append(me.items, item)
}
}
func (me *ListMenuBase) itemDesc(srcLens *SrcLens, lf *ListFilter) string {
if lf.OnSrcLens != nil && srcLens != nil {
lf.OnSrcLens(lf, srcLens)
}
return Strf(me.fdesc, Lang.Title, lf.Desc)
}
func (me *ListMenuBase) listItemsSubMenu(title string, desc string, filters ListFilters) *Menu {
listitems := me.impl.List(filters)
cat := me.cat
if len(listitems) == 1 && strings.HasSuffix(cat, "s") {
cat = cat[:len(cat)-1]
}
menu := &Menu{Desc: Strf("%d %s: %s (%s)", len(listitems), cat, title, desc)}
for _, listitem := range listitems {
if menuitem := me.impl.ListItemToMenuItem(listitem); menuitem != nil {
menu.Items = append(menu.Items, menuitem)
}
}
return menu
}
func (me *ListMenuBase) MenuCategory() string {
return me.cat
}
func (me *ListMenuBase) menuItems(srcLens *SrcLens) MenuItems {
const fhint = "(%v at last count)"
for _, item := range me.items {
fcount, filterid := "amount unknown", item.IpcArgs.(string)
var filters ListFilters
if filterid != "" {
lf := me.impl.FilterByID(filterid)
if lf.OnSrcLens != nil {
item.Desc = me.itemDesc(srcLens, lf)
}
filters = ListFilters{lf: true}
}
count := me.impl.Count(filters)
if count >= 0 {
fcount = Strf("%d", count)
}
item.Hint = Strf(fhint, fcount)
}
return me.items
}