-
Notifications
You must be signed in to change notification settings - Fork 24
/
gui.go
155 lines (135 loc) · 4.15 KB
/
gui.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
145
146
147
148
149
150
151
152
153
154
155
// Copyright (c) 2022, The Emergent Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package egui
//go:generate core generate -add-types
import (
"cogentcore.org/core/core"
"cogentcore.org/core/enums"
"cogentcore.org/core/events"
"cogentcore.org/core/styles"
_ "cogentcore.org/lab/gosl/slbool/slboolcore" // include to get gui views
"cogentcore.org/lab/lab"
"github.com/emer/emergent/v2/netview"
)
// GUI manages all standard elements of a simulation Graphical User Interface
type GUI struct {
lab.Browser
// how many cycles between updates of cycle-level plots
CycleUpdateInterval int
// true if the GUI is configured and running
Active bool `display:"-"`
// true if sim is running
IsRunning bool `display:"-"`
// flag to stop running
StopNow bool `display:"-"`
// NetViews are the created netviews.
NetViews []*netview.NetView
// displays Sim fields on left
SimForm *core.Form `display:"-"`
// Body is the content of the sim window
Body *core.Body `display:"-"`
// OnStop is called when running stopped through the GUI.
// Should update the network view.
OnStop func(mode, level enums.Enum)
}
// UpdateWindow triggers an update on window body,
// to be called from within the normal event processing loop.
// See GoUpdateWindow for version to call from separate goroutine.
func (gui *GUI) UpdateWindow() {
if gui.Toolbar != nil {
gui.Toolbar.Restyle()
}
gui.SimForm.Update()
gui.Body.Scene.NeedsRender()
// todo: could update other stuff but not really necessary
}
// GoUpdateWindow triggers an update on window body,
// for calling from a separate goroutine.
func (gui *GUI) GoUpdateWindow() {
gui.Body.Scene.AsyncLock()
defer gui.Body.Scene.AsyncUnlock()
gui.UpdateWindow()
}
// Stopped is called when a run method stops running,
// from a separate goroutine (do not call from main event loop).
// Updates the IsRunning flag and toolbar.
func (gui *GUI) Stopped(mode, level enums.Enum) {
gui.IsRunning = false
if gui.Body == nil {
return
}
if gui.OnStop != nil {
gui.OnStop(mode, level)
}
gui.GoUpdateWindow()
}
// MakeBody returns default window Body content
func (gui *GUI) MakeBody(sim any, appname, title, about string) {
core.NoSentenceCaseFor = append(core.NoSentenceCaseFor, "github.com/emer")
gui.Body = core.NewBody(appname).SetTitle(title)
// gui.Body.App().About = about
split := core.NewSplits(gui.Body)
split.Name = "split"
gui.Splits = split
gui.SimForm = core.NewForm(split).SetStruct(sim)
gui.SimForm.Name = "sim-form"
if tb, ok := sim.(core.ToolbarMaker); ok {
gui.Body.AddTopBar(func(bar *core.Frame) {
gui.Toolbar = core.NewToolbar(bar)
gui.Toolbar.Maker(gui.MakeToolbar)
gui.Toolbar.Maker(tb.MakeToolbar)
})
}
fform := core.NewFrame(split)
fform.Styler(func(s *styles.Style) {
s.Direction = styles.Column
s.Overflow.Set(styles.OverflowAuto)
s.Grow.Set(1, 1)
})
gui.Files = lab.NewDataTree(fform)
tabs := lab.NewTabs(split)
gui.Tabs = tabs
lab.CurTabber = tabs
tabs.Name = "tabs"
gui.Files.Tabber = tabs
split.SetTiles(core.TileSplit, core.TileSpan)
split.SetSplits(.2, .7, .8)
}
// AddNetView adds NetView in tab with given name
func (gui *GUI) AddNetView(tabName string) *netview.NetView {
nv := lab.NewTab(gui.Tabs, tabName, func(tab *core.Frame) *netview.NetView {
nv := netview.NewNetView(tab)
nv.Var = "Act"
// tb.OnFinal(events.Click, func(e events.Event) {
// nv.Current()
// nv.Update()
// })
gui.NetViews = append(gui.NetViews, nv)
return nv
})
return nv
}
// NetView returns the first created netview, or nil if none.
func (gui *GUI) NetView() *netview.NetView {
if len(gui.NetViews) == 0 {
return nil
}
return gui.NetViews[0]
}
// FinalizeGUI wraps the end functionality of the GUI
func (gui *GUI) FinalizeGUI(closePrompt bool) {
if closePrompt {
gui.Body.AddCloseDialog(func(d *core.Body) bool {
d.SetTitle("Close?")
core.NewText(d).SetType(core.TextSupporting).SetText("Are you sure you want to close?")
d.AddBottomBar(func(bar *core.Frame) {
d.AddOK(bar).SetText("Close").OnClick(func(e events.Event) {
gui.Body.Close()
})
})
return true
})
}
gui.Active = true
}