From ff32316084e11911462be420dd8310473b3d26fd Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Thu, 4 Jan 2024 23:28:55 -0600 Subject: ah, a much cleaner start to a debugger Finally there is some sense this debugger can finally be useful. It can be developed and worked on in isolation from the 'gui' package therefore it can call more sophisticated widget collections. 'gadgets' all moved to gadgets.BasicWindow() thank goodness all this code is isolated finally can finally rename the files first gadgets.BasicWindow() Signed-off-by: Jeff Carr --- debugGochan.go | 100 -------------------- debugGolang.go | 175 ----------------------------------- debugWidget.go | 281 --------------------------------------------------------- gochan.go | 102 +++++++++++++++++++++ golang.go | 176 ++++++++++++++++++++++++++++++++++++ main.go | 193 +++++++++++++++++++++++++++++++++++++++ mainWindow.go | 172 ----------------------------------- structs.go | 30 ++++-- widget.go | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 770 insertions(+), 734 deletions(-) delete mode 100644 debugGochan.go delete mode 100644 debugGolang.go delete mode 100644 debugWidget.go create mode 100644 gochan.go create mode 100644 golang.go create mode 100644 main.go delete mode 100644 mainWindow.go create mode 100644 widget.go diff --git a/debugGochan.go b/debugGochan.go deleted file mode 100644 index e21dda8..0000000 --- a/debugGochan.go +++ /dev/null @@ -1,100 +0,0 @@ -// https://www.digitalocean.com/community/tutorials/how-to-run-multiple-functions-concurrently-in-go -// who came up with the idea of making community tutorials. that was a good idea! - -package debugger - -import ( - "fmt" - "sync" - - "go.wit.com/log" - "go.wit.com/gui/gui" -) - -var debugWG *sync.WaitGroup -var debugNumberChan chan int - -func DebugGoChannels(n *gui.Node) { - var w, g *gui.Node - - w = n.NewWindow("Debug GO Channels") - w.Custom = w.StandardClose - - g = w.NewGroup("Channel stuff") - - // var debugWG sync.WaitGroup - g.NewButton("init()", func () { - if (debugNumberChan == nil) { - log.Log(true, "making debugNumberChan channel") - debugNumberChan = make(chan int) - } else { - log.Log(true, "debugNumberChan already made") - } - debugWG = new(sync.WaitGroup) - }) - g.NewButton("go printInt(x) (read x values off the channel)", func () { - debugWG.Add(1) - go printInt(2, "routine1") - debugWG.Add(1) - go printInt(2, "routine2") - }) - g.NewButton("sendNumber(2) (chan <- 2, 4)", func () { - debugWG.Add(1) - debugWG.Add(1) - go sendNumber(2) - go sendNumber(4) - }) - g.NewButton("sendNumber(1) (chan <- 7)", func () { - debugWG.Add(1) - go sendNumber(7) - }) - g.NewButton("send 4 numbers (chan <- int)", func () { - log.Log(true, "generateNumbers(4)") - go generateNumbers(4) - }) - g.NewButton("debugWG.Done()", func () { - log.Log(true, "ran debugWG.Done()") - debugWG.Done() - }) - g.NewButton("close chan", func () { - log.Log(true, "close() on", debugNumberChan) - close(debugNumberChan) - }) - g.NewButton("print", func () { - log.Log(true, "waitgroup counter is ?") - }) -} -func sendNumber(i int) { - log.Log(true, "START debugNumberChan <-", i, " (sending", i, "to channel)") - debugNumberChan <- i - debugWG.Wait() - log.Log(true, "END debugNumberChan sendNumber() done", i) -} - -func generateNumbers(total int) { - fmt.Printf("START generateNumbers()\n") - for idx := 1; idx <= total; idx++ { - log.Log(true, "ran debugNumberChan <= idx where idx =", idx) - fmt.Printf("S generateNumbers() sending %d to channel\n", idx) - debugNumberChan <- idx - // res, err := (<-r)() - fmt.Printf("E generateNumbers() sending %d to channel\n", idx) - } - debugWG.Wait() - fmt.Printf("END generateNumbers()\n") -} - -// i equals the number of times to read values from the channel -func printInt(i int, name string) { - tmp := 1 - log.Log(true, "START printInt", name, "read debugNumberChan()") - for num := range debugNumberChan { - log.Log(true, "printInt()",name, "read", num, "from channel") - debugWG.Done() - if (tmp == i) { - return - } - tmp += 1 - } - fmt.Printf("END printInt()", name, "read debugNumberChan\n") -} diff --git a/debugGolang.go b/debugGolang.go deleted file mode 100644 index 1cddf9a..0000000 --- a/debugGolang.go +++ /dev/null @@ -1,175 +0,0 @@ -package debugger - -import ( - "fmt" - "bytes" - // "os" - "runtime" - "runtime/debug" - "runtime/pprof" - - "go.wit.com/log" - "go.wit.com/gui/gui" -) - -func DebugGolangWindow(n *gui.Node) { - var newW, newB, g, og, outputTextbox *gui.Node - - newW = n.NewWindow("GO") - newW.Custom = newW.StandardClose - newB = newW.NewBox("hBox", true) - - g = newB.NewGroup("Language Internals") - - g.NewButton("ReadModuleInfo()", func () { - tmp, _ := debug.ReadBuildInfo() - outputTextbox.SetText(tmp.String()) - }) - g.NewButton("runtime.NumGoroutine()", func () { - buf := new(bytes.Buffer) - pprof.Lookup("goroutine").WriteTo(buf, 1) - outputTextbox.SetText(buf.String()) - - outputTextbox.AppendText(fmt.Sprintln("runtime.NumGoroutine() = ", runtime.NumGoroutine())) - }) - g.NewButton("pprof.Lookup(heap)", func () { - buf := new(bytes.Buffer) - pprof.Lookup("heap").WriteTo(buf, 1) - outputTextbox.SetText(buf.String()) - }) - g.NewButton("debug.PrintStack(current)", func () { - outputTextbox.SetText(string(debug.Stack())) - }) - g.NewButton("pprof.Lookup(goroutine)", func () { - buf := new(bytes.Buffer) - pprof.Lookup("goroutine").WriteTo(buf, 1) - outputTextbox.SetText(buf.String()) - }) - g.NewButton("pprof.Lookup(block)", func () { - buf := new(bytes.Buffer) - pprof.Lookup("block").WriteTo(buf, 1) - outputTextbox.SetText(buf.String()) - }) - g.NewButton("pprof.Lookup threadcreate", func () { - buf := new(bytes.Buffer) - pprof.Lookup("threadcreate").WriteTo(buf, 1) - outputTextbox.SetText(buf.String()) - }) - - g.NewButton("runtime.ReadMemStats()", func () { - outputTextbox.SetText(runtimeReadMemStats()) - }) - - g.NewButton("debug.FreeOSMemory()", func () { - var out string = "Before debug.FreeOSMemory():\n\n" - out += runtimeReadMemStats() - debug.FreeOSMemory() - out += "\n\nAfter debug.FreeOSMemory():\n\n" - out += runtimeReadMemStats() - outputTextbox.SetText(out) - }) - - g.NewButton("debug.ReadGCStats()", func () { - var tmp debug.GCStats - var out string - debug.ReadGCStats(&tmp) - log.Log(true, tmp) - out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection") - out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections") - out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections") - out += fmt.Sprintln("Pause:", tmp.Pause, "// []time.Duration pause history, most recent first") - out += fmt.Sprintln("PauseEnd:", tmp.Pause, "// []time.Time pause history, most recent first") - out += fmt.Sprintln("PauseQuantiles:", tmp.PauseQuantiles, "// []time.Duration") - outputTextbox.SetText(out) - }) - - g.NewButton("debug.SetTraceback('all')", func () { - debug.SetTraceback("all") - }) - - g.NewButton("panic()", func () { - panic("test") - }) - - g = newB.NewGroup("TODO: finish these") - - // g.NewLabel("TODO:") - - g.NewButton("runtime.Stack(true)", func () { - // TODO: https://stackoverflow.com/questions/61127053/how-to-list-all-the-running-goroutines-in-a-go-program - // func Stack(buf []byte, all bool) int - }) - - g.NewButton("debug.SetMemoryLimit(int)", func () { - // TODO: - //debug.SetMemoryLimit(1024 * 1024 * 100) - }) - - g.NewButton("debug.SetMaxStack(int bytes)", func () { - // default is apparently 1GB - }) - - g.NewButton("debug.SetMaxThreads(int)", func () { - // default is apparently 10,000 - }) - - g.NewButton("debug.SetTraceback('all')", func () { - debug.SetTraceback("all") - }) - - // deprecated (probably) by String() implementation within golang - g.NewButton("dumpModuleInfo() (deprecate)", func () { - outputTextbox.SetText(dumpModuleInfo()) - }) - - og = newB.NewGroup("output") - outputTextbox = og.NewTextbox("outputBox") - outputTextbox.Custom = func () { - log.Log(true, "custom TextBox() for golang output a =", outputTextbox.S) - } -} - -func runtimeReadMemStats() string { - var s runtime.MemStats - var out string - runtime.ReadMemStats(&s) - out += fmt.Sprintln("alloc:", s.Alloc, "bytes") - out += fmt.Sprintln("total-alloc:", s.TotalAlloc, "bytes") - out += fmt.Sprintln("sys:", s.Sys, "bytes") - out += fmt.Sprintln("lookups:", s.Lookups) - out += fmt.Sprintln("mallocs:", s.Mallocs) - out += fmt.Sprintln("frees:", s.Frees) - out += fmt.Sprintln("heap-alloc:", s.HeapAlloc, "bytes") - out += fmt.Sprintln("heap-sys:", s.HeapSys, "bytes") - out += fmt.Sprintln("heap-idle:", s.HeapIdle,"bytes") - out += fmt.Sprintln("heap-in-use:", s.HeapInuse, "bytes") - out += fmt.Sprintln("heap-released:", s.HeapReleased, "bytes") - out += fmt.Sprintln("heap-objects:", s.HeapObjects) - out += fmt.Sprintln("stack-in-use:", s.StackInuse, "bytes") - out += fmt.Sprintln("stack-sys", s.StackSys, "bytes") - out += fmt.Sprintln("next-gc: when heap-alloc >=", s.NextGC, "bytes") - out += fmt.Sprintln("last-gc:", s.LastGC, "ns") - out += fmt.Sprintln("gc-pause:", s.PauseTotalNs, "ns") - out += fmt.Sprintln("num-gc:", s.NumGC) - out += fmt.Sprintln("enable-gc:", s.EnableGC) - out += fmt.Sprintln("debug-gc:", s.DebugGC) - return out -} - -func dumpModuleInfo() string { - var out string - tmp, _ := debug.ReadBuildInfo() - if tmp == nil { - out += fmt.Sprintln("This wasn't compiled with go module support") - return "" - } - out += fmt.Sprintln("mod.Path = ", tmp.Path) - out += fmt.Sprintln("mod.Main.Path = ", tmp.Main.Path) - out += fmt.Sprintln("mod.Main.Version = ", tmp.Main.Version) - out += fmt.Sprintln("mod.Main.Sum = ", tmp.Main.Sum) - for _, value := range tmp.Deps { - out += fmt.Sprintln("\tmod.Path = ", value.Path) - out += fmt.Sprintln("\tmod.Version = ", value.Version) - } - return out -} diff --git a/debugWidget.go b/debugWidget.go deleted file mode 100644 index c6c953c..0000000 --- a/debugWidget.go +++ /dev/null @@ -1,281 +0,0 @@ -package debugger - -import ( - "strconv" - "errors" - - "go.wit.com/log" - "go.wit.com/gui/gui" -) - - -/* -func setActiveWidget(w *gui.Node) { - if (w == nil) { - log.Log(debugError, "setActiveWidget() was sent nil !!!") - return - } - activeWidget = w - log.Log(true, "The Widget is set to", w.id, w.Name) - if (activeLabel == nil) { - // the debug window doesn't exist yet so you can't display the change - // TODO: make a fake binary tree for this(?) - return - } - title := "ID =" + strconv.Itoa(w.id) + " " + w.Name - activeLabel.SetText(title) - activeLabelType.SetText("widget.Type = " + w.WidgetType.String()) - return -} -*/ - -func DebugWidgetWindow(w *gui.Node) { - var newW, newB *gui.Node - if (bugWidget != nil) { - // this window was already created. Just change the widget we are working against - setActiveWidget(w) - return - } - - newW = w.NewWindow("Widgets") - newW.Custom = newW.StandardClose - bugWidget = newW - newB = newW.NewBox("hBox", true) - - g := newB.NewGroup("widget:") - - g2 := g.NewGroup("widget:") - activeLabel = g2.NewLabel("undef") - g2 = g.NewGroup("type:") - activeLabelType = g2.NewLabel("undef") - g2 = g.NewGroup("New name:") - activeLabelNewName = g2.NewCombobox("newthing") - activeLabelNewName.AddText("penguin") - activeLabelNewName.AddText("snow") - activeLabelNewName.AddText("GO") - activeLabelNewName.AddText("debian") - activeLabelNewName.AddText("RiscV") - - g2 = g.NewGroup("At X:") - activeLabelNewX = g2.NewSpinner("tmp spinner", -1, 100) - - g2 = g.NewGroup("At Y:") - activeLabelNewY = g2.NewSpinner("tmp spinner", -1, 100) - - g2 = g.NewGroup("bool B:") - activeLabelNewB = g2.NewCheckbox("tmp bool") - - - // common things that should work against each widget - g = newB.NewGroup("common things") - g.NewButton("Enable()", func () { - activeWidget.Enable() - }) - g.NewButton("Disable()", func () { - activeWidget.Disable() - }) - g.NewButton("Show()", func () { - activeWidget.Show() - }) - g.NewButton("Hide()", func () { - activeWidget.Hide() - }) - g.NewButton("Dump()", func () { - activeWidget.Dump() - }) - - g = newB.NewGroup("add things") - debugAddWidgetButton(g) - g.NewLabel("experiments:") - debugAddWidgetButtons(g) - - g = newB.NewGroup("change things") - g.NewButton("AddText()", func () { - activeWidget.AddText(activeLabelNewName.S) - /* - activeWidget.S = activeLabelNewName.S - a := newAction(activeWidget, toolkit.AddText) - sendAction(a) - */ - }) - g.NewButton("SetText()", func () { - activeWidget.SetText(activeLabelNewName.S) - /* - activeWidget.S = activeLabelNewName.S - a := newAction(activeWidget, toolkit.SetText) - sendAction(a) - */ - }) - g.NewButton("Margin()", func () { - activeWidget.Margin() - /* - a := newAction(activeWidget, toolkit.Margin) - sendAction(a) - */ - }) - g.NewButton("Unmargin()", func () { - activeWidget.Unmargin() - }) - g.NewButton("Pad()", func () { - activeWidget.Pad() - }) - g.NewButton("Unpad()", func () { - activeWidget.Unpad() - }) - g.NewButton("Move(junk)", func () { - log.Warn("gui.Node Move() not implemented yet") - }) - g.NewButton("Delete()", func () { - activeWidget.Delete(activeWidget) - }) - - g = newB.NewGroup("not working?") - activeJunk = newB.NewGroup("junk:") - activeJunk.NewLabel("test junk") - - if (activeWidget == nil) { - setActiveWidget(myGui) - } -} - -func debugAddWidgetButtons(n *gui.Node) { - n.NewButton("Dropdown", func () { - a := activeWidget.NewDropdown("tmp dropdown") - a.AddText("this is better than tcl/tk") - a.AddText("make something for tim for qflow") - a.AddText("and for riscv") - a.Custom = func () { - log.Log(true, "custom dropdown() a =", a.Name, a.S) - } - }) - n.NewButton("Combobox", func () { - a := activeWidget.NewCombobox("tmp combobox") - a.AddText("mirrors.wit.com") - a.AddText("go.wit.com") - a.Custom = func () { - log.Log(true, "custom combobox() a =", a.Name, a.S) - } - }) - n.NewButton("Grid", func () { - // Grid numbering by (X,Y) - // ----------------------------- - // -- (1,1) -- (2,1) -- (3,1) -- - // -- (1,2) -- (2,1) -- (3,1) -- - // ----------------------------- - - // SetDebug(true) - debugGrid = activeWidget.NewGrid("tmp grid", 2, 3) - debugGridLabel = debugGrid.NewLabel("mirrors.wit.com") - /* - debugGrid.SetNext(0,1) - debugGrid.NewLabel("foo (0,1)") - debugGrid.SetNext(1,1) - debugGrid.NewLabel("foo (1,1)") - debugGrid.SetNext(2,1) - debugGrid.NewLabel("foo (2,1)") - */ - // SetDebug(false) - DebugWidgetWindow(debugGrid) - }) - n.NewButton("Image", func () { - activeWidget.NewImage("image") - }) - n.NewButton("Box(horizontal)", func () { - a := activeWidget.NewBox("hBox", true) - a.NewLabel("hBox") - a.NewLabel("hBox 2") - }) - n.NewButton("Box(vertical)", func () { - a := activeWidget.NewBox("vBox", false) - a.NewLabel("vBox") - a.NewLabel("vBox 2") - }) -} - -func debugAddWidgetButton(n *gui.Node) { - activeLabelNewType = n.NewDropdown("tmp dropdown") - activeLabelNewType.AddText("Window") - activeLabelNewType.AddText("Tab") - activeLabelNewType.AddText("Frame") - activeLabelNewType.AddText("Grid") - activeLabelNewType.AddText("Group") - activeLabelNewType.AddText("Box") - activeLabelNewType.AddText("Button") - activeLabelNewType.AddText("Checkbox") - activeLabelNewType.AddText("Dropdown") - activeLabelNewType.AddText("Combobox") - activeLabelNewType.AddText("Label") - activeLabelNewType.AddText("Textbox") - activeLabelNewType.AddText("Slider") - activeLabelNewType.AddText("Spinner") - activeLabelNewType.AddText("Image") - activeLabelNewType.AddText("Area") - activeLabelNewType.AddText("Form") - activeLabelNewType.AddText("Font") - activeLabelNewType.AddText("Color") - activeLabelNewType.AddText("Dialog") - - n.NewButton("Add", func () { - name := activeLabelNewName.S - newX := activeLabelNewX.I - newY := activeLabelNewY.I - newB := activeLabelNewB.B - - if (newY == -1) { - name = name + " (" + strconv.Itoa(activeWidget.NextW) + "," + strconv.Itoa(activeWidget.NextH) + ")" - } else { - activeWidget.SetNext(newX, newY) - name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")" - } - log.Log(true, "New Name =", name) - log.Log(true, "New Type =", activeLabelNewType.S) - log.Log(true, "New X =", newX) - log.Log(true, "New Y =", newY) - log.Log(true, "activeWidget.NextW =", activeWidget.NextW) - log.Log(true, "activeWidget.NextH =", activeWidget.NextH) - log.Log(true, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (W,H) =", activeWidget.NextW, activeWidget.NextH) - activeWidget.Dump() - - // activeWidget.X = newX - // activeWidget.Y = newY - - switch activeLabelNewType.S { - case "Grid": - activeWidget.NewGrid(name, newX, newY) - case "Group": - activeWidget.NewGroup(name) - case "Box": - activeWidget.NewBox(name, newB) - case "Button": - activeWidget.NewButton(name, func () { - log.Log(true, "got to button", name) - }) - case "Checkbox": - a := activeWidget.NewCheckbox(name) - a.Custom = func () { - log.Log(true, "custom checkox func a=", a.B) - } - case "Dropdown": - a := activeWidget.NewDropdown(name) - a.AddText(name + " yay") - a.AddText(name + " haha") - a.Custom = func () { - log.Log(true, "WTF a=", a.B) - } - case "Combobox": - a := activeWidget.NewCombobox(name) - a.AddText(name + " foo") - a.AddText(name + " bar") - case "Label": - activeWidget.NewLabel(name) - case "Textbox": - activeWidget.NewTextbox(name) - case "Slider": - activeWidget.NewSlider(name, newX, newY) - case "Spinner": - activeWidget.NewSpinner(name, newX, newY) - default: - log.Error(errors.New("make what type?"), activeLabelNewType.S) - } - }) -} diff --git a/gochan.go b/gochan.go new file mode 100644 index 0000000..3f62b24 --- /dev/null +++ b/gochan.go @@ -0,0 +1,102 @@ +// https://www.digitalocean.com/community/tutorials/how-to-run-multiple-functions-concurrently-in-go +// who came up with the idea of making community tutorials. that was a good idea! + +package debugger + +import ( + "fmt" + "sync" + + "go.wit.com/log" + "go.wit.com/gui/gui" + "go.wit.com/gui/gadgets" +) + +var debugWG *sync.WaitGroup +var debugNumberChan chan int + +func DebugGoChannels(p *gui.Node) *gadgets.BasicWindow { + var w *gadgets.BasicWindow + var g *gui.Node + + w = gadgets.NewBasicWindow(p, "Debug GO Channels") + g = w.Box().NewGroup("Channel stuff").Pad() + + // var debugWG sync.WaitGroup + g.NewButton("init()", func () { + if (debugNumberChan == nil) { + log.Log(true, "making debugNumberChan channel") + debugNumberChan = make(chan int) + } else { + log.Log(true, "debugNumberChan already made") + } + debugWG = new(sync.WaitGroup) + }) + g.NewButton("go printInt(x) (read x values off the channel)", func () { + debugWG.Add(1) + go printInt(2, "routine1") + debugWG.Add(1) + go printInt(2, "routine2") + }) + g.NewButton("sendNumber(2) (chan <- 2, 4)", func () { + debugWG.Add(1) + debugWG.Add(1) + go sendNumber(2) + go sendNumber(4) + }) + g.NewButton("sendNumber(1) (chan <- 7)", func () { + debugWG.Add(1) + go sendNumber(7) + }) + g.NewButton("send 4 numbers (chan <- int)", func () { + log.Log(true, "generateNumbers(4)") + go generateNumbers(4) + }) + g.NewButton("debugWG.Done()", func () { + log.Log(true, "ran debugWG.Done()") + debugWG.Done() + }) + g.NewButton("close chan", func () { + log.Log(true, "close() on", debugNumberChan) + close(debugNumberChan) + }) + g.NewButton("print", func () { + log.Log(true, "waitgroup counter is ?") + }) + return w +} + +func sendNumber(i int) { + log.Log(true, "START debugNumberChan <-", i, " (sending", i, "to channel)") + debugNumberChan <- i + debugWG.Wait() + log.Log(true, "END debugNumberChan sendNumber() done", i) +} + +func generateNumbers(total int) { + fmt.Printf("START generateNumbers()\n") + for idx := 1; idx <= total; idx++ { + log.Log(true, "ran debugNumberChan <= idx where idx =", idx) + fmt.Printf("S generateNumbers() sending %d to channel\n", idx) + debugNumberChan <- idx + // res, err := (<-r)() + fmt.Printf("E generateNumbers() sending %d to channel\n", idx) + } + debugWG.Wait() + fmt.Printf("END generateNumbers()\n") +} + +// i equals the number of times to read values from the channel +func printInt(i int, name string) { + tmp := 1 + log.Log(true, "START printInt", name, "read debugNumberChan()") + for num := range debugNumberChan { + log.Log(true, "printInt()",name, "read", num, "from channel") + debugWG.Done() + if (tmp == i) { + return + } + tmp += 1 + } + fmt.Printf("END printInt()", name, "read debugNumberChan\n") +} diff --git a/golang.go b/golang.go new file mode 100644 index 0000000..a037ca2 --- /dev/null +++ b/golang.go @@ -0,0 +1,176 @@ +package debugger + +import ( + "fmt" + "bytes" + // "os" + "runtime" + "runtime/debug" + "runtime/pprof" + + "go.wit.com/log" + "go.wit.com/gui/gui" + "go.wit.com/gui/gadgets" +) + +func DebugGolangWindow(p *gui.Node) *gadgets.BasicWindow { + var w *gadgets.BasicWindow + var g, og, outputTextbox *gui.Node + + w = gadgets.NewBasicWindow(p, "GO") + g = w.Box().NewGroup("Language Internals").Pad() + + g.NewButton("ReadModuleInfo()", func () { + tmp, _ := debug.ReadBuildInfo() + outputTextbox.SetText(tmp.String()) + }) + g.NewButton("runtime.NumGoroutine()", func () { + buf := new(bytes.Buffer) + pprof.Lookup("goroutine").WriteTo(buf, 1) + outputTextbox.SetText(buf.String()) + + outputTextbox.AppendText(fmt.Sprintln("runtime.NumGoroutine() = ", runtime.NumGoroutine())) + }) + g.NewButton("pprof.Lookup(heap)", func () { + buf := new(bytes.Buffer) + pprof.Lookup("heap").WriteTo(buf, 1) + outputTextbox.SetText(buf.String()) + }) + g.NewButton("debug.PrintStack(current)", func () { + outputTextbox.SetText(string(debug.Stack())) + }) + g.NewButton("pprof.Lookup(goroutine)", func () { + buf := new(bytes.Buffer) + pprof.Lookup("goroutine").WriteTo(buf, 1) + outputTextbox.SetText(buf.String()) + }) + g.NewButton("pprof.Lookup(block)", func () { + buf := new(bytes.Buffer) + pprof.Lookup("block").WriteTo(buf, 1) + outputTextbox.SetText(buf.String()) + }) + g.NewButton("pprof.Lookup threadcreate", func () { + buf := new(bytes.Buffer) + pprof.Lookup("threadcreate").WriteTo(buf, 1) + outputTextbox.SetText(buf.String()) + }) + + g.NewButton("runtime.ReadMemStats()", func () { + outputTextbox.SetText(runtimeReadMemStats()) + }) + + g.NewButton("debug.FreeOSMemory()", func () { + var out string = "Before debug.FreeOSMemory():\n\n" + out += runtimeReadMemStats() + debug.FreeOSMemory() + out += "\n\nAfter debug.FreeOSMemory():\n\n" + out += runtimeReadMemStats() + outputTextbox.SetText(out) + }) + + g.NewButton("debug.ReadGCStats()", func () { + var tmp debug.GCStats + var out string + debug.ReadGCStats(&tmp) + log.Log(true, tmp) + out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection") + out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections") + out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections") + out += fmt.Sprintln("Pause:", tmp.Pause, "// []time.Duration pause history, most recent first") + out += fmt.Sprintln("PauseEnd:", tmp.Pause, "// []time.Time pause history, most recent first") + out += fmt.Sprintln("PauseQuantiles:", tmp.PauseQuantiles, "// []time.Duration") + outputTextbox.SetText(out) + }) + + g.NewButton("debug.SetTraceback('all')", func () { + debug.SetTraceback("all") + }) + + g.NewButton("panic()", func () { + panic("test") + }) + + g = w.Box().NewGroup("TODO: finish these").Pad() + + // g.NewLabel("TODO:") + + g.NewButton("runtime.Stack(true)", func () { + // TODO: https://stackoverflow.com/questions/61127053/how-to-list-all-the-running-goroutines-in-a-go-program + // func Stack(buf []byte, all bool) int + }) + + g.NewButton("debug.SetMemoryLimit(int)", func () { + // TODO: + //debug.SetMemoryLimit(1024 * 1024 * 100) + }) + + g.NewButton("debug.SetMaxStack(int bytes)", func () { + // default is apparently 1GB + }) + + g.NewButton("debug.SetMaxThreads(int)", func () { + // default is apparently 10,000 + }) + + g.NewButton("debug.SetTraceback('all')", func () { + debug.SetTraceback("all") + }) + + // deprecated (probably) by String() implementation within golang + g.NewButton("dumpModuleInfo() (deprecate)", func () { + outputTextbox.SetText(dumpModuleInfo()) + }) + + og = w.Box().NewGroup("output").Pad() + outputTextbox = og.NewTextbox("outputBox") + outputTextbox.Custom = func () { + log.Log(true, "custom TextBox() for golang output a =", outputTextbox.S) + } + + return w +} + +func runtimeReadMemStats() string { + var s runtime.MemStats + var out string + runtime.ReadMemStats(&s) + out += fmt.Sprintln("alloc:", s.Alloc, "bytes") + out += fmt.Sprintln("total-alloc:", s.TotalAlloc, "bytes") + out += fmt.Sprintln("sys:", s.Sys, "bytes") + out += fmt.Sprintln("lookups:", s.Lookups) + out += fmt.Sprintln("mallocs:", s.Mallocs) + out += fmt.Sprintln("frees:", s.Frees) + out += fmt.Sprintln("heap-alloc:", s.HeapAlloc, "bytes") + out += fmt.Sprintln("heap-sys:", s.HeapSys, "bytes") + out += fmt.Sprintln("heap-idle:", s.HeapIdle,"bytes") + out += fmt.Sprintln("heap-in-use:", s.HeapInuse, "bytes") + out += fmt.Sprintln("heap-released:", s.HeapReleased, "bytes") + out += fmt.Sprintln("heap-objects:", s.HeapObjects) + out += fmt.Sprintln("stack-in-use:", s.StackInuse, "bytes") + out += fmt.Sprintln("stack-sys", s.StackSys, "bytes") + out += fmt.Sprintln("next-gc: when heap-alloc >=", s.NextGC, "bytes") + out += fmt.Sprintln("last-gc:", s.LastGC, "ns") + out += fmt.Sprintln("gc-pause:", s.PauseTotalNs, "ns") + out += fmt.Sprintln("num-gc:", s.NumGC) + out += fmt.Sprintln("enable-gc:", s.EnableGC) + out += fmt.Sprintln("debug-gc:", s.DebugGC) + return out +} + +func dumpModuleInfo() string { + var out string + tmp, _ := debug.ReadBuildInfo() + if tmp == nil { + out += fmt.Sprintln("This wasn't compiled with go module support") + return "" + } + out += fmt.Sprintln("mod.Path = ", tmp.Path) + out += fmt.Sprintln("mod.Main.Path = ", tmp.Main.Path) + out += fmt.Sprintln("mod.Main.Version = ", tmp.Main.Version) + out += fmt.Sprintln("mod.Main.Sum = ", tmp.Main.Sum) + for _, value := range tmp.Deps { + out += fmt.Sprintln("\tmod.Path = ", value.Path) + out += fmt.Sprintln("\tmod.Version = ", value.Version) + } + return out +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..bf18ed3 --- /dev/null +++ b/main.go @@ -0,0 +1,193 @@ +package debugger + +import ( + "os" + + "go.wit.com/log" + "go.wit.com/gui/gui" + "go.wit.com/gui/gadgets" + "go.wit.com/gui/gadgets/logsettings" +) + +/* + Creates a window helpful for debugging this package +*/ + +func DebugWindow(p *gui.Node) { + if (me != nil) { + me.bugWin.Toggle() + return + } + me = new(debuggerSettings) + me.myGui = p + + me.bugWin = gadgets.NewBasicWindow(p,"go.wit.com/gui debug window") + + DebugWindow2(me.bugWin.Box(), "Debug Tab") + // initialize the log settings window (does not display it) + + me.myLS = logsettings.New(me.myGui) + if ArgDebug() { + log.SetTmp() + } +} + +func DebugWindow2(newB *gui.Node, title string) *gui.Node { + var gr *gui.Node + +//////////////////////// main debug things ////////////////////////////////// + gr = newB.NewGroup("Debugging Windows:") + + gr.NewButton("logging", func () { + me.myLS.Toggle() + }) + gr.NewButton("Widgets Window", func () { + if me.widgets == nil { + me.widgets = DebugWidgetWindow(me.myGui) + me.widgets.Draw() + return + } + me.widgets.Toggle() + }) + + gr.NewLabel("Force Quit:") + + gr.NewButton("os.Exit()", func () { + os.Exit(0) + }) + +//////////////////////// window debugging things ////////////////////////////////// + gr = newB.NewGroup("list things") + + gr.NewButton("List toolkits", func () { + dropdownWindow(gr) + bugWin.ListToolkits() + }) + gr.NewButton("List Windows", func () { + dropdownWindow(gr) + }) + gr.NewButton("List Window Widgets", func () { + dropdownWindowWidgets(gr) + }) + + gr = newB.NewGroup("more things") + + gr.NewButton("Node.ListChildren(true)", func () { + if (activeWidget == nil) { + activeWidget = bugWin + } + activeWidget.ListChildren(true) + }) + + gr.NewButton("test conc", func () { + log.Log(true, "TODO: fix me") + // makeConc() + }) + + gr.NewButton("List Plugins", func () { + log.Log(true, "TODO: fix me") + /* + for _, aplug := range allPlugins { + log.Log(true, "Loaded plugin:", aplug.name, aplug.filename) + } + */ + }) + + gr.NewButton("load toolkit 'gocui'", func () { + bugWin.LoadToolkit("gocui") + }) + + gr.NewButton("load toolkit 'andlabs'", func () { + bugWin.LoadToolkit("andlabs") + }) + + gr = newB.NewGroup("Learn GO") + + gr.NewButton("GO Language Internals", func () { + if me.golang == nil { + me.golang = DebugGolangWindow(me.myGui) + me.golang.Draw() + return + } + if me.golang.Ready() { + me.golang.Toggle() + } + }) + gr.NewButton("GO Channels debug", func () { + if me.gochan == nil { + me.gochan = DebugGoChannels(me.myGui) + me.gochan.Draw() + return + } + if me.gochan.Ready() { + me.gochan.Toggle() + } + }) + + return newB +} + +func dropdownWindow(p *gui.Node) { + var mapWindows map[string]*gui.Node + mapWindows = make(map[string]*gui.Node) + + dd := p.NewDropdown("Window Dropdown") + dd.Custom = func() { + name := dd.S + activeWidget = mapWindows[name] + setActiveWidget(activeWidget) + log.Log(true, "The Window was set to", name) + } + log.Log(INFO, "dd =", dd) + if (activeWidget == nil) { + // the debug window doesn't exist yet so you can't display the change + // TODO: make a fake binary tree for this(?) + return + } + + // var last = "" + for _, child := range p.Children() { + log.Log(INFO, "\t\t", child.GetName()) + dd.AddDropdownName(child.GetName()) + // last = child.Name + mapWindows[child.GetName()] = child + if (activeWidget == nil) { + activeWidget = child + } + } + // dd.SetDropdownName(last) +} + +func dropdownWindowWidgets(p *gui.Node) { + var mapWindows map[string]*gui.Node + mapWindows = make(map[string]*gui.Node) + + dd := p.NewDropdown("Window Widgets Dropdown") + dd.Custom = func() { + name := dd.S + activeWidget = mapWindows[name] + setActiveWidget(activeWidget) + } + log.Log(INFO, "dd =", dd) + + // log.Log("dumpWidget() ", b, listChildrenDepth, defaultPadding, n.id, info) + + var addDropdowns func (*gui.Node) + addDropdowns = func (n *gui.Node) { + // s := n.dumpWidget(true) + s := n.GetName() + dd.AddDropdownName(s) + mapWindows[s] = n + + for _, child := range n.Children() { + addDropdowns(child) + } + } + + // list everything in the binary tree + addDropdowns(bugWin) +} + +func setActiveWidget(w *gui.Node) { + log.Warn("TODO: setActiveWidget()") +} diff --git a/mainWindow.go b/mainWindow.go deleted file mode 100644 index b40056c..0000000 --- a/mainWindow.go +++ /dev/null @@ -1,172 +0,0 @@ -package debugger - -import ( - "os" - - "go.wit.com/log" - "go.wit.com/gui/gui" - "go.wit.com/gui/gadgets/logsettings" -) - -/* - Creates a window helpful for debugging this package -*/ - -func DebugWindow(p *gui.Node) { - myGui = p - bugWin = myGui.NewWindow("go.wit.com/gui debug window") - bugWin.StandardClose() - bugTab = DebugWindow2(bugWin, "Debug Tab") - bugTab.StandardClose() - // initialize the log settings window (does not display it) - myLS = logsettings.New(myGui) - if ArgDebug() { - log.SetTmp() - } -} - -func DebugWindow2(n *gui.Node, title string) *gui.Node { - var newW, newB, gr *gui.Node - // var logSettings *gadgets.LogSettings - - // time.Sleep(1 * time.Second) - newW = n.NewWindow(title) - - newB = newW.NewBox("hBox", true) - -//////////////////////// main debug things ////////////////////////////////// - gr = newB.NewGroup("Debugging Windows:") - - gr.NewButton("logging", func () { - myLS.Show() - }) - gr.NewButton("Debug Widgets", func () { - DebugWidgetWindow(myGui) - }) - - gr.NewLabel("Force Quit:") - - gr.NewButton("os.Exit()", func () { - os.Exit(0) - }) - -//////////////////////// window debugging things ////////////////////////////////// - gr = newB.NewGroup("list things") - - gr.NewButton("List toolkits", func () { - dropdownWindow(gr) - bugWin.ListToolkits() - }) - gr.NewButton("List Windows", func () { - dropdownWindow(gr) - }) - gr.NewButton("List Window Widgets", func () { - dropdownWindowWidgets(gr) - }) - - gr = newB.NewGroup("more things") - - gr.NewButton("Node.ListChildren(true)", func () { - if (activeWidget == nil) { - activeWidget = bugWin - } - activeWidget.ListChildren(true) - }) - - gr.NewButton("test conc", func () { - log.Log(true, "TODO: fix me") - // makeConc() - }) - - gr.NewButton("List Plugins", func () { - log.Log(true, "TODO: fix me") - /* - for _, aplug := range allPlugins { - log.Log(true, "Loaded plugin:", aplug.name, aplug.filename) - } - */ - }) - - gr.NewButton("load toolkit 'gocui'", func () { - bugWin.LoadToolkit("gocui") - }) - - gr.NewButton("load toolkit 'andlabs'", func () { - bugWin.LoadToolkit("andlabs") - }) - - gr = newB.NewGroup("Learn GO") - - gr.NewButton("GO Language Internals", func () { - DebugGolangWindow(myGui) - }) - gr.NewButton("GO Channels debug", func () { - DebugGoChannels(myGui) - }) - - return newB -} - -func dropdownWindow(p *gui.Node) { - var mapWindows map[string]*gui.Node - mapWindows = make(map[string]*gui.Node) - - dd := p.NewDropdown("Window Dropdown") - dd.Custom = func() { - name := dd.S - activeWidget = mapWindows[name] - setActiveWidget(activeWidget) - log.Log(true, "The Window was set to", name) - } - log.Log(INFO, "dd =", dd) - if (activeWidget == nil) { - // the debug window doesn't exist yet so you can't display the change - // TODO: make a fake binary tree for this(?) - return - } - - // var last = "" - for _, child := range p.Children() { - log.Log(INFO, "\t\t", child.GetName()) - dd.AddDropdownName(child.GetName()) - // last = child.Name - mapWindows[child.GetName()] = child - if (activeWidget == nil) { - activeWidget = child - } - } - // dd.SetDropdownName(last) -} - -func dropdownWindowWidgets(p *gui.Node) { - var mapWindows map[string]*gui.Node - mapWindows = make(map[string]*gui.Node) - - dd := p.NewDropdown("Window Widgets Dropdown") - dd.Custom = func() { - name := dd.S - activeWidget = mapWindows[name] - setActiveWidget(activeWidget) - } - log.Log(INFO, "dd =", dd) - - // log.Log("dumpWidget() ", b, listChildrenDepth, defaultPadding, n.id, info) - - var addDropdowns func (*gui.Node) - addDropdowns = func (n *gui.Node) { - // s := n.dumpWidget(true) - s := n.GetName() - dd.AddDropdownName(s) - mapWindows[s] = n - - for _, child := range n.Children() { - addDropdowns(child) - } - } - - // list everything in the binary tree - addDropdowns(bugWin) -} - -func setActiveWidget(w *gui.Node) { -} diff --git a/structs.go b/structs.go index 8d4e9f9..8997887 100644 --- a/structs.go +++ b/structs.go @@ -2,17 +2,35 @@ package debugger import ( "go.wit.com/gui/gui" + "go.wit.com/gui/gadgets" "go.wit.com/gui/gadgets/logsettings" ) -// main debugging window -var myGui *gui.Node -var bugWin *gui.Node -var bugTab *gui.Node +var me *debuggerSettings + +type debuggerSettings struct { + ready bool + hidden bool + err error + + myGui *gui.Node -var myLS *logsettings.LogSettings + bugWin *gadgets.BasicWindow + widgets *gadgets.BasicWindow + golang *gadgets.BasicWindow + gochan *gadgets.BasicWindow -var mapWindows map[string]*gui.Node // tracks all windows that exist + myLS *logsettings.LogSettings + + mapWindows map[string]*gui.Node // tracks all windows that exist +} + +var bugWin *gui.Node +/* +// main debugging window +var bugTab *gui.Node +var myGui *gui.Node +*/ // global var for checking to see if this // window/tab for debugging a widget exists diff --git a/widget.go b/widget.go new file mode 100644 index 0000000..3f459a8 --- /dev/null +++ b/widget.go @@ -0,0 +1,275 @@ +package debugger + +import ( + "strconv" + "errors" + + "go.wit.com/log" + "go.wit.com/gui/gui" + "go.wit.com/gui/gadgets" +) + + +/* +func setActiveWidget(w *gui.Node) { + if (w == nil) { + log.Log(debugError, "setActiveWidget() was sent nil !!!") + return + } + activeWidget = w + log.Log(true, "The Widget is set to", w.id, w.Name) + if (activeLabel == nil) { + // the debug window doesn't exist yet so you can't display the change + // TODO: make a fake binary tree for this(?) + return + } + title := "ID =" + strconv.Itoa(w.id) + " " + w.Name + activeLabel.SetText(title) + activeLabelType.SetText("widget.Type = " + w.WidgetType.String()) + return +} +*/ + +func DebugWidgetWindow(p *gui.Node) *gadgets.BasicWindow { + var w *gadgets.BasicWindow + w = gadgets.NewBasicWindow(p, "Widgets") + + g := w.Box().NewGroup("widget:").Pad() + + g2 := g.NewGroup("widget:") + activeLabel = g2.NewLabel("undef") + g2 = g.NewGroup("type:") + activeLabelType = g2.NewLabel("undef") + g2 = g.NewGroup("New name:") + activeLabelNewName = g2.NewCombobox("newthing") + activeLabelNewName.AddText("penguin") + activeLabelNewName.AddText("snow") + activeLabelNewName.AddText("GO") + activeLabelNewName.AddText("debian") + activeLabelNewName.AddText("RiscV") + + g2 = g.NewGroup("At X:") + activeLabelNewX = g2.NewSpinner("tmp spinner", -1, 100) + + g2 = g.NewGroup("At Y:") + activeLabelNewY = g2.NewSpinner("tmp spinner", -1, 100) + + g2 = g.NewGroup("bool B:") + activeLabelNewB = g2.NewCheckbox("tmp bool") + + + // common things that should work against each widget + g = w.Box().NewGroup("common things") + g.NewButton("Enable()", func () { + activeWidget.Enable() + }) + g.NewButton("Disable()", func () { + activeWidget.Disable() + }) + g.NewButton("Show()", func () { + activeWidget.Show() + }) + g.NewButton("Hide()", func () { + activeWidget.Hide() + }) + g.NewButton("Dump()", func () { + activeWidget.Dump() + }) + + g = w.Box().NewGroup("add things") + debugAddWidgetButton(g) + g.NewLabel("experiments:") + debugAddWidgetButtons(g) + + g = w.Box().NewGroup("change things") + g.NewButton("AddText()", func () { + activeWidget.AddText(activeLabelNewName.S) + /* + activeWidget.S = activeLabelNewName.S + a := newAction(activeWidget, toolkit.AddText) + sendAction(a) + */ + }) + g.NewButton("SetText()", func () { + activeWidget.SetText(activeLabelNewName.S) + /* + activeWidget.S = activeLabelNewName.S + a := newAction(activeWidget, toolkit.SetText) + sendAction(a) + */ + }) + g.NewButton("Margin()", func () { + activeWidget.Margin() + /* + a := newAction(activeWidget, toolkit.Margin) + sendAction(a) + */ + }) + g.NewButton("Unmargin()", func () { + activeWidget.Unmargin() + }) + g.NewButton("Pad()", func () { + activeWidget.Pad() + }) + g.NewButton("Unpad()", func () { + activeWidget.Unpad() + }) + g.NewButton("Move(junk)", func () { + log.Warn("gui.Node Move() not implemented yet") + }) + g.NewButton("Delete()", func () { + activeWidget.Delete(activeWidget) + }) + + g = w.Box().NewGroup("not working?") + activeJunk = w.Box().NewGroup("junk:") + activeJunk.NewLabel("test junk") + + if (activeWidget == nil) { + setActiveWidget(me.myGui) + } + + return w +} + +func debugAddWidgetButtons(n *gui.Node) { + n.NewButton("Dropdown", func () { + a := activeWidget.NewDropdown("tmp dropdown") + a.AddText("this is better than tcl/tk") + a.AddText("make something for tim for qflow") + a.AddText("and for riscv") + a.Custom = func () { + log.Log(true, "custom dropdown() a =", a.Name, a.S) + } + }) + n.NewButton("Combobox", func () { + a := activeWidget.NewCombobox("tmp combobox") + a.AddText("mirrors.wit.com") + a.AddText("go.wit.com") + a.Custom = func () { + log.Log(true, "custom combobox() a =", a.Name, a.S) + } + }) + n.NewButton("Grid", func () { + // Grid numbering by (X,Y) + // ----------------------------- + // -- (1,1) -- (2,1) -- (3,1) -- + // -- (1,2) -- (2,1) -- (3,1) -- + // ----------------------------- + + // SetDebug(true) + debugGrid = activeWidget.NewGrid("tmp grid", 2, 3) + debugGridLabel = debugGrid.NewLabel("mirrors.wit.com") + /* + debugGrid.SetNext(0,1) + debugGrid.NewLabel("foo (0,1)") + debugGrid.SetNext(1,1) + debugGrid.NewLabel("foo (1,1)") + debugGrid.SetNext(2,1) + debugGrid.NewLabel("foo (2,1)") + */ + // SetDebug(false) + DebugWidgetWindow(debugGrid) + }) + n.NewButton("Image", func () { + activeWidget.NewImage("image") + }) + n.NewButton("Box(horizontal)", func () { + a := activeWidget.NewBox("hBox", true) + a.NewLabel("hBox") + a.NewLabel("hBox 2") + }) + n.NewButton("Box(vertical)", func () { + a := activeWidget.NewBox("vBox", false) + a.NewLabel("vBox") + a.NewLabel("vBox 2") + }) +} + +func debugAddWidgetButton(n *gui.Node) { + activeLabelNewType = n.NewDropdown("tmp dropdown") + activeLabelNewType.AddText("Window") + activeLabelNewType.AddText("Tab") + activeLabelNewType.AddText("Frame") + activeLabelNewType.AddText("Grid") + activeLabelNewType.AddText("Group") + activeLabelNewType.AddText("Box") + activeLabelNewType.AddText("Button") + activeLabelNewType.AddText("Checkbox") + activeLabelNewType.AddText("Dropdown") + activeLabelNewType.AddText("Combobox") + activeLabelNewType.AddText("Label") + activeLabelNewType.AddText("Textbox") + activeLabelNewType.AddText("Slider") + activeLabelNewType.AddText("Spinner") + activeLabelNewType.AddText("Image") + activeLabelNewType.AddText("Area") + activeLabelNewType.AddText("Form") + activeLabelNewType.AddText("Font") + activeLabelNewType.AddText("Color") + activeLabelNewType.AddText("Dialog") + + n.NewButton("Add", func () { + name := activeLabelNewName.S + newX := activeLabelNewX.I + newY := activeLabelNewY.I + newB := activeLabelNewB.B + + if (newY == -1) { + name = name + " (" + strconv.Itoa(activeWidget.NextW) + "," + strconv.Itoa(activeWidget.NextH) + ")" + } else { + activeWidget.SetNext(newX, newY) + name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")" + } + log.Log(true, "New Name =", name) + log.Log(true, "New Type =", activeLabelNewType.S) + log.Log(true, "New X =", newX) + log.Log(true, "New Y =", newY) + log.Log(true, "activeWidget.NextW =", activeWidget.NextW) + log.Log(true, "activeWidget.NextH =", activeWidget.NextH) + log.Log(true, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (W,H) =", activeWidget.NextW, activeWidget.NextH) + activeWidget.Dump() + + // activeWidget.X = newX + // activeWidget.Y = newY + + switch activeLabelNewType.S { + case "Grid": + activeWidget.NewGrid(name, newX, newY) + case "Group": + activeWidget.NewGroup(name) + case "Box": + activeWidget.NewBox(name, newB) + case "Button": + activeWidget.NewButton(name, func () { + log.Log(true, "got to button", name) + }) + case "Checkbox": + a := activeWidget.NewCheckbox(name) + a.Custom = func () { + log.Log(true, "custom checkox func a=", a.B) + } + case "Dropdown": + a := activeWidget.NewDropdown(name) + a.AddText(name + " yay") + a.AddText(name + " haha") + a.Custom = func () { + log.Log(true, "WTF a=", a.B) + } + case "Combobox": + a := activeWidget.NewCombobox(name) + a.AddText(name + " foo") + a.AddText(name + " bar") + case "Label": + activeWidget.NewLabel(name) + case "Textbox": + activeWidget.NewTextbox(name) + case "Slider": + activeWidget.NewSlider(name, newX, newY) + case "Spinner": + activeWidget.NewSpinner(name, newX, newY) + default: + log.Error(errors.New("make what type?"), activeLabelNewType.S) + } + }) +} -- cgit v1.2.3