diff options
Diffstat (limited to 'toolkit')
35 files changed, 1261 insertions, 435 deletions
diff --git a/toolkit/andlabs/append.go b/toolkit/andlabs/append.go index 811ffbc..4578c94 100644 --- a/toolkit/andlabs/append.go +++ b/toolkit/andlabs/append.go @@ -7,41 +7,35 @@ import ( _ "github.com/andlabs/ui/winmanifest" ) -// make new Group here -func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) { - - if (newt.tw != nil) { - if (newt.tw.Type == toolkit.Grid) { - log(true, "doAppend() going to attempt uiGrid") - // hack to add shit to a grid - button1 := ui.NewButton("a(0,2)") - newt.uiGrid.Append(button1, - 0, 2, 1, 1, - false, ui.AlignFill, false, ui.AlignFill) - button2 := ui.NewButton("a(1,2)") - newt.uiGrid.Append(button2, - 1, 2, 1, 1, - false, ui.AlignFill, false, ui.AlignFill) +// move all the append code here +func (t *andlabsT) doAppend(kind toolkit.WidgetType, newt *andlabsT, c *ui.Control) { + if (kind == toolkit.Grid) { + log(debugToolkit, "doAppend() attempt to append a ui.Control into a uiGrid") + // hack to add shit to a grid + button1 := ui.NewButton("a(0,2)") + newt.uiGrid.Append(button1, + 0, 2, 1, 1, + false, ui.AlignFill, false, ui.AlignFill) + button2 := ui.NewButton("a(1,2)") + newt.uiGrid.Append(button2, + 1, 2, 1, 1, + false, ui.AlignFill, false, ui.AlignFill) - if (t.uiBox != nil) { - log(true, "doAppend() on uiGrid to a uiBox") - if (newt.Name == "output") { - t.uiBox.Append(newt.uiGrid, true) - } else { + if (t.uiBox != nil) { + log(debugToolkit, "doAppend() on uiGrid to a uiBox") + if (newt.Name == "output") { + t.uiBox.Append(newt.uiGrid, true) + } else { t.uiBox.Append(newt.uiGrid, stretchy) - } - return } - log(true, "doAppend() on uiGrid failed") return } - } else { - log(true, "doAppend() newt.tw == nil ERROR on newt.Name =", newt.Name) + log(debugToolkit, "doAppend() on uiGrid failed") + return } - // hack to pass a group - if (c == nil) { - log(true, "attempting to doAppend() on a uiGroup") + if (kind == toolkit.Group) { + log(debugToolkit, "doAppend() attempt a uiGroup") if (t.uiBox != nil) { if (newt.Name == "output") { t.uiBox.Append(newt.uiGroup, true) @@ -52,20 +46,19 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) { } if (t.uiWindow != nil) { - log(true, "This is a raw window without a box. probably make a box here and add the group to that") - t.Dump(true) - newt.Dump(true) + log(debugToolkit, "This is a raw window without a box. probably make a box here and add the group to that") + newt.Dump(debugToolkit) t.uiBox = ui.NewHorizontalBox() t.uiWindow.SetChild(t.uiBox) - log(true, "tried to make a box", t.uiBox) + log(debugToolkit, "tried to make a box", t.uiBox) if (newt.Name == "output") { - log(true, "tried to t.uiBox.Append(*c, true)") + log(debugToolkit, "tried to t.uiBox.Append(*c, true)") if (t.uiBox == nil) { - log(true, "tried to t.uiBox.Append(*c, true)") + log(debugToolkit, "tried to t.uiBox.Append(*c, true)") } t.uiBox.Append(newt.uiGroup, true) } else { - log(true, "tried to t.uiBox.Append(*c, stretchy)") + log(debugToolkit, "tried to t.uiBox.Append(*c, stretchy)") t.uiBox.Append(newt.uiGroup, stretchy) } return @@ -75,7 +68,13 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) { log(debugError, "probably could just make a box here?") exit("internal wit/gui error") } - if (t.uiBox != nil) { + + if (kind == toolkit.Textbox) { + if (t.uiBox == nil) { + log(debugError, "NewTextbox() node.UiBox == nil. I can't add a range UI element without a place to put it") + log(debugError, "probably could just make a box here?") + exit("internal wit/gui error") + } // TODO: temporary hack to make the output textbox 'fullscreen' if (newt.Name == "output") { t.uiBox.Append(*c, true) @@ -84,11 +83,12 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) { } return } + if (t.uiWindow != nil) { - log(true, "This is a raw window without a box. probably make a box here and add the group to that") + log(debugToolkit, "This is a raw window without a box. probably make a box here and add the group to that") t.uiBox = ui.NewHorizontalBox() t.uiWindow.SetChild(t.uiBox) - log(true, "tried to make a box") + log(debugToolkit, "tried to make a box") if (newt.Name == "output") { t.uiBox.Append(*c, true) } else { diff --git a/toolkit/andlabs/button.go b/toolkit/andlabs/button.go index deb34fa..4ae791c 100644 --- a/toolkit/andlabs/button.go +++ b/toolkit/andlabs/button.go @@ -10,11 +10,11 @@ import ( func newButton(parentW *toolkit.Widget, w *toolkit.Widget) { var t, newt *andlabsT var b *ui.Button - log(debugToolkit, "gui.andlabs.NewButton()", w.Name) + log(debugToolkit, "newButton()", w.Name) t = mapToolkits[parentW] if (t == nil) { - log(debugToolkit, "go.andlabs.NewButton() toolkit struct == nil. name=", parentW.Name, w.Name) + log(debugToolkit, "newButton() toolkit struct == nil. name=", parentW.Name, w.Name) return } @@ -32,22 +32,32 @@ func newButton(parentW *toolkit.Widget, w *toolkit.Widget) { newt.commonChange(newt.tw) }) - log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box parent t:", w.Name) - log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box new t:", w.Name) + log(debugToolkit, "newButton() about to append to Box parent t:", w.Name) + log(debugToolkit, "newButton() about to append to Box new t:", w.Name) + if (debugToolkit) { + ShowDebug () + } if (t.uiBox != nil) { t.uiBox.Append(b, stretchy) } else if (t.uiWindow != nil) { t.uiWindow.SetChild(b) } else { - log(debugToolkit, "ERROR: wit/gui andlabs couldn't place this button in a box or a window") - log(debugToolkit, "ERROR: wit/gui andlabs couldn't place this button in a box or a window") + log(debugError, "ERROR: wit/gui andlabs couldn't place this button in a box or a window") + log(debugError, "ERROR: wit/gui andlabs couldn't place this button in a box or a window") return } mapWidgetsToolkits(w, newt) } +// This routine is very specific to this toolkit +// It's annoying and has to be copied to each widget when there are changes +// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten +// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here! +// but it's time to write direct GTK, QT, macos and windows toolkit plugins +// -- jcarr 2023/03/09 + func doButton(p *toolkit.Widget, c *toolkit.Widget) { if broken(c) { return @@ -58,18 +68,18 @@ func doButton(p *toolkit.Widget, c *toolkit.Widget) { } ct := mapToolkits[c] if (ct == nil) { - log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) return } if ct.broken() { - log(true, "Button() ct.broken", ct) + log(debugError, "Button() ct.broken", ct) return } if (ct.uiButton == nil) { - log(true, "Button() uiButton == nil", ct) + log(debugError, "Button() uiButton == nil", ct) return } - log(true, "Going to attempt:", c.Action) + log(debugToolkit, "Going to attempt:", c.Action) switch c.Action { case "Enable": ct.uiButton.Enable() @@ -82,6 +92,6 @@ func doButton(p *toolkit.Widget, c *toolkit.Widget) { case "Set": ct.uiButton.SetText(c.S) default: - log(true, "Can't do", c.Action, "to a Button") + log(debugError, "Can't do", c.Action, "to a Button") } } diff --git a/toolkit/andlabs/checkbox.go b/toolkit/andlabs/checkbox.go index 16e4eed..d28d3dc 100644 --- a/toolkit/andlabs/checkbox.go +++ b/toolkit/andlabs/checkbox.go @@ -70,7 +70,7 @@ func doCheckbox(p *toolkit.Widget, c *toolkit.Widget) { log(true, "checkbox() uiCheckbox == nil", ct) return } - log(true, "Going to attempt:", c.Action) + log(debugChange, "Going to attempt:", c.Action) switch c.Action { case "Enable": ct.uiCheckbox.Enable() @@ -80,10 +80,11 @@ func doCheckbox(p *toolkit.Widget, c *toolkit.Widget) { ct.uiCheckbox.Show() case "Hide": ct.uiCheckbox.Hide() - case "Set": + case "SetText": ct.uiCheckbox.SetText(c.S) + case "Set": ct.uiCheckbox.SetChecked(c.B) default: - log(true, "Can't do", c.Action, "to a checkbox") + log(debugError, "Can't do", c.Action, "to a checkbox") } } diff --git a/toolkit/andlabs/combobox.go b/toolkit/andlabs/combobox.go index 08e7148..3395406 100644 --- a/toolkit/andlabs/combobox.go +++ b/toolkit/andlabs/combobox.go @@ -80,7 +80,7 @@ func doCombobox(p *toolkit.Widget, c *toolkit.Widget) { log(true, "Combobox() uiEditableCombobox == nil", ct) return } - log(true, "Going to attempt:", c.Action) + log(debugChange, "Going to attempt:", c.Action) switch c.Action { case "Add": ct.AddComboboxName(c.S) @@ -95,6 +95,6 @@ func doCombobox(p *toolkit.Widget, c *toolkit.Widget) { case "Set": ct.uiEditableCombobox.SetText(c.S) default: - log(true, "Can't do", c.Action, "to a Combobox") + log(debugError, "Can't do", c.Action, "to a Combobox") } } diff --git a/toolkit/andlabs/common.go b/toolkit/andlabs/common.go index d2811cb..2e3997b 100644 --- a/toolkit/andlabs/common.go +++ b/toolkit/andlabs/common.go @@ -2,16 +2,9 @@ package main import ( "git.wit.org/wit/gui/toolkit" - "github.com/davecgh/go-spew/spew" +// "github.com/davecgh/go-spew/spew" ) -// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc -func init() { - // Can you pass values to a plugin init() ? Otherwise, there is no way to safely print - // log(debugToolkit, "gui/toolkit init() Setting defaultBehavior = true") - setDefaultBehavior(true) -} - func (t *andlabsT) commonChange(tw *toolkit.Widget) { log(debugChange, "commonChange() START widget =", t.Name, t.Type) if (tw == nil) { @@ -30,6 +23,7 @@ func (t *andlabsT) commonChange(tw *toolkit.Widget) { // TODO: probably this should not panic unless it's running in devel mode (?) // TODO: redo this now that WidgetType is used and send() is used to package plugins func (t *andlabsT) broken() bool { + /* if (t.parent != nil) { return false } @@ -52,6 +46,7 @@ func (t *andlabsT) broken() bool { t.Dump(debugToolkit) return false } + */ return false } func broken(w *toolkit.Widget) bool { @@ -79,123 +74,3 @@ func dump(p *toolkit.Widget, c *toolkit.Widget, b bool) { } ct.Dump(b) } - -func setMarginNew(w *toolkit.Widget, b bool) { - wt := mapToolkits[w] - log(true, "START setMarginNew", w.Name) - if (wt == nil) { - return - } - if (wt.uiGroup != nil) { - log(true, "uiGroup.SetMargined(true)") - wt.uiGroup.SetMargined(b) - } - if (wt.uiTab != nil) { - i := wt.uiTab.NumPages() - log(true, "tab.NumPages() =", i) - for i > 0 { - i -= 1 - log(true, "uiTab.SetMargined(true) for i =", i) - wt.uiTab.SetMargined(i, b) - } - } else { - log(true, "no uitab") - } - if (wt.uiWindow != nil) { - log(true, "uiWindow.SetMargined(true)") - wt.uiWindow.SetMargined(b) - } - log(true, "END setMarginNew", w.Name) -} - -func setMargin(p *toolkit.Widget, c *toolkit.Widget, b bool) { - log(true, "Starting to implement SetMargin here") - dump(p, c, true) - - setMarginNew(c, b) - setMarginNew(p, b) -} - -func (t *andlabsT) String() string { - return t.GetText() -} - -func (t *andlabsT) GetText() string { - log(debugToolkit, "GetText() Enter debugToolkit=", debugToolkit) - if (t.uiEntry != nil) { - log(debugToolkit, "uiEntry.Text() =", t.uiEntry.Text()) - return t.uiEntry.Text() - } - if (t.uiMultilineEntry != nil) { - log(debugToolkit, "uiMultilineEntry.Text() =", t.uiMultilineEntry.Text()) - text := t.uiMultilineEntry.Text() - log(debugToolkit, "uiMultilineEntry.Text() =", text) - t.text = text - return text - } - if (t.uiCombobox != nil) { - log(debugToolkit, "uiCombobox() =", t.text) - return t.text - } - return "" -} - -func (t *andlabsT) SetText(s string) bool { - log(debugToolkit, "Text() SetText() Enter") - if (t.uiEntry != nil) { - log(debugToolkit, "Value() =", t.uiEntry.Text) - t.uiEntry.SetText(s) - return true - } - if (t.uiMultilineEntry != nil) { - log(debugToolkit, "Value() =", t.uiMultilineEntry.Text) - t.uiMultilineEntry.SetText(s) - return true - } - return false -} - -func sanity(t *andlabsT) bool { - if (debugToolkit) { - log(debugToolkit, "Value() Enter") - scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) - } - if (t.uiEntry == nil) { - log(debugToolkit, "Value() =", t.uiEntry.Text) - return false - } - return true -} - -func (t *andlabsT) SetValue(i int) bool { - log(debugToolkit, "SetValue() START") - if (sanity(t)) { - return false - } - t.Dump(debugToolkit) - // panic("got to toolkit.SetValue") - return true -} - -func (t *andlabsT) Value() int { - if (debugToolkit) { - log(debugToolkit, "Value() Enter") - scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) - } - if (t == nil) { - log(debugToolkit, "Value() can not get value t == nil") - return 0 - } - if (t.uiSlider != nil) { - log(debugToolkit, "Value() =", t.uiSlider.Value) - return t.uiSlider.Value() - } - if (t.uiSpinbox != nil) { - log(debugToolkit, "Value() =", t.uiSpinbox.Value) - return t.uiSpinbox.Value() - } - log(debugToolkit, "Value() Could not find a ui element to get a value from") - return 0 -} diff --git a/toolkit/andlabs/debug.go b/toolkit/andlabs/debug.go index 8b11f8c..f2902ca 100644 --- a/toolkit/andlabs/debug.go +++ b/toolkit/andlabs/debug.go @@ -2,8 +2,6 @@ package main import "git.wit.org/wit/gui/toolkit" -// import "github.com/davecgh/go-spew/spew" - var defaultBehavior bool = true var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack? @@ -16,9 +14,8 @@ var margin bool // add space around the frames of windows var debugToolkit bool var debugChange bool var debugPlugin bool -var debugFlag bool +var debugFlags bool var debugError bool = true -// var DebugToolkit bool // This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc func setDefaultBehavior(s bool) { @@ -37,24 +34,12 @@ func setDefaultBehavior(s bool) { } } -/* -func SetDebugToolkit (s bool) { - debugToolkit = s - log(true, "debugToolkit =", debugToolkit) - log(true, "debugChange =", debugChange) -} - -func SetDebugChange (s bool) { - debugChange = s - log(true, "debugToolkit =", debugToolkit) - log(true, "debugChange =", debugChange) -} -*/ - func ShowDebug () { log(true, "debugToolkit =", debugToolkit) - log(true, "debugError =", debugError) log(true, "debugChange =", debugChange) + log(true, "debugPlugin =", debugPlugin) + log(true, "debugFlags =", debugFlags) + log(true, "debugError =", debugError) } func (t *andlabsT) Dump(b bool) { diff --git a/toolkit/andlabs/delete.go b/toolkit/andlabs/delete.go new file mode 100644 index 0000000..4232521 --- /dev/null +++ b/toolkit/andlabs/delete.go @@ -0,0 +1,56 @@ +package main + +// if you include more than just this import +// then your plugin might be doing something un-ideal (just a guess from 2023/02/27) +import "git.wit.org/wit/gui/toolkit" + +// delete the child widget from the parent +// p = parent, c = child +func destroy(p *toolkit.Widget, c *toolkit.Widget) { + log(true, "delete()", c.Name, c.Type) + + pt := mapToolkits[p] + ct := mapToolkits[c] + if (ct == nil) { + log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", c.Name, c.Type) + // this pukes out a whole universe of shit + // listMap() + return + } + + switch ct.Type { + case toolkit.Button: + log(true, "Should delete Button here:", c.Name) + log(true, "Parent:") + pt.Dump(true) + log(true, "Child:") + ct.Dump(true) + if (pt.uiBox == nil) { + log(true, "Don't know how to destroy this") + } else { + log(true, "Fuck it, destroy the whole box", pt.Name) + // pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent. + pt.uiBox.SetPadded(false) + pt.uiBox.Delete(4) + ct.uiButton.Disable() + // ct.uiButton.Hide() + ct.uiButton.Destroy() + } + + case toolkit.Window: + log(true, "Should delete Window here:", c.Name) + default: + log(true, "Don't know how to delete c =", c.Type, c.Name) + log(true, "Don't know how to delete pt =", pt.Type, pt.Name, pt.uiButton) + log(true, "Don't know how to delete ct =", ct.Type, ct.Name, ct.uiButton) + log(true, "Parent:") + pt.Dump(true) + log(true, "Child:") + ct.Dump(true) + log(true, "Fuckit, let's destroy a button", c.Name, c.Type) + if (ct.uiButton != nil) { + pt.uiBox.Delete(4) + ct.uiButton.Destroy() + } + } +} diff --git a/toolkit/andlabs/dropdown.go b/toolkit/andlabs/dropdown.go index 57642e0..35d391b 100644 --- a/toolkit/andlabs/dropdown.go +++ b/toolkit/andlabs/dropdown.go @@ -48,7 +48,7 @@ func (t *andlabsT) AddDropdownName(title string) { // If this is the first menu added, set the dropdown to it if (t.c == 0) { log(debugChange, "THIS IS THE FIRST Dropdown", title) - t.uiCombobox.SetSelected(1) + t.uiCombobox.SetSelected(0) } t.c = t.c + 1 } @@ -105,18 +105,18 @@ func doDropdown(p *toolkit.Widget, c *toolkit.Widget) { } ct := mapToolkits[c] if (ct == nil) { - log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) return } if ct.broken() { - log(true, "Dropdown() ct.broken", ct) + log(debugError, "Dropdown() ct.broken", ct) return } if (ct.uiCombobox == nil) { - log(true, "Dropdown() uiCombobox == nil", ct) + log(debugError, "Dropdown() uiCombobox == nil", ct) return } - log(true, "Going to attempt:", c.Action) + log(debugChange, "Going to attempt:", c.Action) switch c.Action { case "Add": ct.AddDropdownName(c.S) @@ -131,7 +131,29 @@ func doDropdown(p *toolkit.Widget, c *toolkit.Widget) { ct.uiCombobox.Hide() case "Set": ct.uiCombobox.SetSelected(1) + case "SetText": + var orig int + var i int = -1 + var s string + orig = ct.uiCombobox.Selected() + log(debugError, "TODO: set a Dropdown by the name selected =", orig, ct.c, c.S) + // try to find the string + for i, s = range ct.val { + log(debugError, "i, s", i, s) + if (c.S == s) { + ct.uiCombobox.SetSelected(i) + return + } + } + // if i == -1, then there are not any things in the menu to select + if (i == -1) { + return + } + // if the string was never set, then set the dropdown to the last thing added to the menu + if (orig == -1) { + ct.uiCombobox.SetSelected(i) + } default: - log(true, "Can't do", c.Action, "to a Dropdown") + log(debugError, "Can't do", c.Action, "to a Dropdown") } } diff --git a/toolkit/andlabs/grid.go b/toolkit/andlabs/grid.go index 8d09152..47a70e3 100644 --- a/toolkit/andlabs/grid.go +++ b/toolkit/andlabs/grid.go @@ -36,29 +36,7 @@ func newGrid(parentW *toolkit.Widget, w *toolkit.Widget) { newt.uiGrid = c newt.uiBox = t.uiBox newt.tw = w - t.doAppend(newt, nil) - /* - if (defaultBehavior) { - t.uiBox.Append(c, stretchy) - } - - button1 := ui.NewButton("a(0,0)") - c.Append(button1, - 0, 0, 1, 1, - false, ui.AlignFill, false, ui.AlignFill) - - button2 := ui.NewButton("a(1,0)") - c.Append(button2, - 1, 0, 1, 1, - false, ui.AlignFill, false, ui.AlignFill) - */ - - // Append(child Control, - // left, top int, - // xspan, yspan int, - // hexpand bool, halign Align, - // vexpand bool, valign Align) { - + t.doAppend(toolkit.Grid, newt, nil) mapWidgetsToolkits(w, newt) } @@ -72,19 +50,18 @@ func doGrid(p *toolkit.Widget, c *toolkit.Widget) { } ct := mapToolkits[c] if (ct == nil) { - log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) return } if ct.broken() { - log(true, "Grid() ct.broken", ct) + log(debugError, "Grid() ct.broken", ct) return } if (ct.uiGrid == nil) { - - log(true, "Grid() uiGrid == nil", ct) + log(debugError, "Grid() uiGrid == nil", ct) return } - log(true, "Going to attempt:", c.Action) + log(debugChange, "Going to attempt:", c.Action) switch c.Action { case "Enable": ct.uiGrid.Enable() @@ -93,10 +70,22 @@ func doGrid(p *toolkit.Widget, c *toolkit.Widget) { case "Show": ct.uiGrid.Show() case "Hide": + log(debugError, "trying Hide on grid") ct.uiGrid.Hide() + case "SetMargin": + log(debugError, "trying SetMargin on grid") + ct.uiGrid.SetPadded(c.B) case "Set": - log(true, "Can I use 'Set' to place a *Node in a Grid?") + log(debugError, "Can I use 'Set' to place a *Node in a Grid?") + /* + case "AddGrid": + log(true, "how do I add a thing to a grid?") + dump(p, c, true) + newt.uiGrid.Append(button1, + 0, 2, 1, 1, + false, ui.AlignFill, false, ui.AlignFill) + */ default: - log(true, "Can't do", c.Action, "to a Grid") + log(debugError, "Can't do", c.Action, "to a Grid") } } diff --git a/toolkit/andlabs/group.go b/toolkit/andlabs/group.go index 903cb4f..717da42 100644 --- a/toolkit/andlabs/group.go +++ b/toolkit/andlabs/group.go @@ -8,8 +8,7 @@ import ( ) func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) { - // log(debugToolkit, "gui.andlabs.NewGroup()", w.Name) - log(true, "NewGroup()", w.Name) + log(debugToolkit, "NewGroup()", w.Name) t := mapToolkits[parentW] if (t == nil) { @@ -31,31 +30,7 @@ func (t *andlabsT) rawGroup(title string) *andlabsT { g.SetMargined(margin) newt.uiGroup = g - t.doAppend(&newt, nil) - /* - if (t.uiBox != nil) { - // TODO: temporary hack to make the output textbox 'fullscreen' - if (newt.Name == "output") { - t.uiBox.Append(g, true) - } else { - t.uiBox.Append(g, stretchy) - } - } else if (t.uiWindow != nil) { - log(true, "This is a raw window without a box. probably make a box here and add the group to that") - t.uiBox = ui.NewHorizontalBox() - t.uiWindow.SetChild(t.uiBox) - log(true, "tried to make a box") - if (newt.Name == "output") { - t.uiBox.Append(g, true) - } else { - t.uiBox.Append(g, stretchy) - } - } else { - log(debugError, "NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") - log(debugError, "probably could just make a box here?") - exit("internal wit/gui error") - } - */ + t.doAppend(toolkit.Group, &newt, nil) hbox := ui.NewVerticalBox() hbox.SetPadded(padded) @@ -67,3 +42,56 @@ func (t *andlabsT) rawGroup(title string) *andlabsT { return &newt } + +// This routine is very specific to this toolkit +// It's annoying and has to be copied to each widget when there are changes +// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten +// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here! +// but it's time to write direct GTK, QT, macos and windows toolkit plugins +// -- jcarr 2023/03/09 + +func doGroup(p *toolkit.Widget, c *toolkit.Widget) { + if broken(c) { + return + } + log(debugChange, "Going to attempt:", c.Action) + if (c.Action == "New") { + newGroup(p, c) + return + } + ct := mapToolkits[c] + if (ct == nil) { + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + return + } + if ct.broken() { + log(debugError, "Group() ct.broken", ct) + return + } + if (ct.uiGroup == nil) { + log(debugError, "Label() uiGroup == nil", ct) + return + } + switch c.Action { + case "Enable": + ct.uiGroup.Enable() + case "Disable": + ct.uiGroup.Disable() + case "Show": + ct.uiGroup.Show() + case "Hide": + ct.uiGroup.Hide() + case "Get": + c.S = ct.uiGroup.Title() + case "Set": + ct.uiGroup.SetTitle(c.S) + case "SetText": + ct.uiGroup.SetTitle(c.S) + case "SetMargin": + ct.uiGroup.SetMargined(c.B) + case "Destroy": + ct.uiGroup.Destroy() + default: + log(debugError, "Can't do", c.Action, "to a Group") + } +} diff --git a/toolkit/andlabs/label.go b/toolkit/andlabs/label.go index fca9abb..6fa4baa 100644 --- a/toolkit/andlabs/label.go +++ b/toolkit/andlabs/label.go @@ -39,29 +39,36 @@ func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) { mapWidgetsToolkits(w, newt) } +// This routine is very specific to this toolkit +// It's annoying and has to be copied to each widget when there are changes +// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten +// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here! +// but it's time to write direct GTK, QT, macos and windows toolkit plugins +// -- jcarr 2023/03/09 + func doLabel(p *toolkit.Widget, c *toolkit.Widget) { if broken(c) { return } + log(debugChange, "Going to attempt:", c.Action) if (c.Action == "New") { newLabel(p, c) return } ct := mapToolkits[c] if (ct == nil) { - log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) return } if ct.broken() { - log(true, "Label() ct.broken", ct) + log(debugError, "Label() ct.broken", ct) return } if (ct.uiLabel == nil) { - log(true, "Label() uiLabel == nil", ct) + log(debugError, "Label() uiLabel == nil", ct) return } - log(true, "Going to attempt:", c.Action) switch c.Action { case "Enable": ct.uiLabel.Enable() @@ -71,9 +78,11 @@ func doLabel(p *toolkit.Widget, c *toolkit.Widget) { ct.uiLabel.Show() case "Hide": ct.uiLabel.Hide() + case "SetText": + ct.uiLabel.SetText(c.S) case "Set": ct.uiLabel.SetText(c.S) default: - log(true, "Can't do", c.Action, "to a Label") + log(debugError, "Can't do", c.Action, "to a Label") } } diff --git a/toolkit/andlabs/log.go b/toolkit/andlabs/log.go index 98b4e54..43b90cb 100644 --- a/toolkit/andlabs/log.go +++ b/toolkit/andlabs/log.go @@ -103,12 +103,12 @@ func log(a ...any) { if (a[0] == false) { return } - a[0] = "WIT/GUI/Toolkit" + a[0] = "GUI/Toolkit/Andlabs" } if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) { // a = a[1:] - a[0] = "WIT/GUI/Toolkit" + a[0] = "GUI/Toolkit/Andlabs" if (debugToolkit) { scs := spew.ConfigState{MaxDepth: 1} scs.Dump(a) diff --git a/toolkit/andlabs/main.go b/toolkit/andlabs/main.go index 20bbd8b..c719352 100644 --- a/toolkit/andlabs/main.go +++ b/toolkit/andlabs/main.go @@ -16,11 +16,6 @@ func Main(f func()) { log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") ui.Main( func() { log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") - log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") - log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") - log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") - log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") - log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)") // time.Sleep(1 * time.Second) // NewWindow2("helloworld2", 200, 100) f() @@ -37,17 +32,22 @@ func Main(f func()) { // func Queue(f func()) { log(debugToolkit, "Sending function to ui.QueueMain()") - log(true, "using gui.Queue() in this plugin DOES BREAK. TODO: wrap this") + log(debugPlugin, "using gui.Queue() in this plugin DOES BREAK. TODO: solve this with channels") ui.QueueMain(f) } +// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc func Init() { log(debugToolkit, "Init()") + // Can you pass values to a plugin init() ? Otherwise, there is no way to safely print + // log(debugToolkit, "gui/toolkit init() Setting defaultBehavior = true") + setDefaultBehavior(true) mapWidgets = make(map[*andlabsT]*toolkit.Widget) mapToolkits = make(map[*toolkit.Widget]*andlabsT) } +// TODO: properly exit the plugin since Quit() doesn't do it func Quit() { log(debugToolkit, "Quit() TODO: close the toolkit cleanly") } diff --git a/toolkit/andlabs/plugin.go b/toolkit/andlabs/plugin.go index 8b75766..8cac830 100644 --- a/toolkit/andlabs/plugin.go +++ b/toolkit/andlabs/plugin.go @@ -26,31 +26,33 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) { } log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type) + /* if (c.Action == "SetMargin") { - log(true, "need to implement SetMargin here") - setMargin(p, c, c.B) + log(debugError, "need to implement SetMargin here") + setMargin(c, c.B) return } + */ switch c.Type { case toolkit.Window: - newWindow(c) + doWindow(c) case toolkit.Tab: - newTab(p, c) + doTab(p, c) case toolkit.Group: - newGroup(p, c) + doGroup(p, c) case toolkit.Button: doButton(p, c) case toolkit.Checkbox: doCheckbox(p, c) case toolkit.Label: - newLabel(p, c) + doLabel(p, c) case toolkit.Textbox: doTextbox(p, c) case toolkit.Slider: - newSlider(p, c) + doSlider(p, c) case toolkit.Spinner: - newSpinner(p, c) + doSpinner(p, c) case toolkit.Dropdown: doDropdown(p, c) case toolkit.Combobox: @@ -58,79 +60,32 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) { case toolkit.Grid: doGrid(p, c) case toolkit.Flag: - log(debugFlag, "plugin Send() flag parent =", p.Name, p.Type) - log(debugFlag, "plugin Send() flag child =", c.Name, c.Type) - log(debugFlag, "plugin Send() flag child.Action =", c.Action) - log(debugFlag, "plugin Send() flag child.S =", c.S) - log(debugFlag, "plugin Send() flag child.B =", c.B) - log(debugFlag, "plugin Send() what to flag?") + // log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type) + // log(debugFlags, "plugin Send() flag child =", c.Name, c.Type) + // log(debugFlags, "plugin Send() flag child.Action =", c.Action) + // log(debugFlags, "plugin Send() flag child.S =", c.S) + // log(debugFlags, "plugin Send() flag child.B =", c.B) + // log(debugFlags, "plugin Send() what to flag?") // should set the checkbox to this value switch c.S { - case "Error": - debugError = c.B case "Toolkit": debugToolkit = c.B case "Change": debugChange = c.B + case "Plugin": + debugPlugin = c.B + case "Flags": + debugFlags = c.B + case "Error": + debugError = c.B case "Show": ShowDebug() default: log(debugError, "Can't set unknown flag", c.S) } default: - log(true, "plugin Send() unknown parent =", p.Name, p.Type) - log(true, "plugin Send() unknown child =", c.Name, c.Type) - log(true, "plugin Send() Don't know how to do", c.Type, "yet") - } -} - -// delete the child widget from the parent -// p = parent, c = child -func destroy(p *toolkit.Widget, c *toolkit.Widget) { - log(true, "delete()", c.Name, c.Type) - - pt := mapToolkits[p] - ct := mapToolkits[c] - if (ct == nil) { - log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", c.Name, c.Type) - // this pukes out a whole universe of shit - // listMap() - return - } - - switch ct.Type { - case toolkit.Button: - log(true, "Should delete Button here:", c.Name) - log(true, "Parent:") - pt.Dump(true) - log(true, "Child:") - ct.Dump(true) - if (pt.uiBox == nil) { - log(true, "Don't know how to destroy this") - } else { - log(true, "Fuck it, destroy the whole box", pt.Name) - // pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent. - pt.uiBox.SetPadded(false) - pt.uiBox.Delete(4) - ct.uiButton.Disable() - // ct.uiButton.Hide() - ct.uiButton.Destroy() - } - - case toolkit.Window: - log(true, "Should delete Window here:", c.Name) - default: - log(true, "Don't know how to delete c =", c.Type, c.Name) - log(true, "Don't know how to delete pt =", pt.Type, pt.Name, pt.uiButton) - log(true, "Don't know how to delete ct =", ct.Type, ct.Name, ct.uiButton) - log(true, "Parent:") - pt.Dump(true) - log(true, "Child:") - ct.Dump(true) - log(true, "Fuckit, let's destroy a button", c.Name, c.Type) - if (ct.uiButton != nil) { - pt.uiBox.Delete(4) - ct.uiButton.Destroy() - } + log(debugError, "plugin Send() unknown parent =", p.Name, p.Type) + log(debugError, "plugin Send() unknown child =", c.Name, c.Type) + log(debugError, "plugin Send() Don't know how to do", c.Type, "yet") } } diff --git a/toolkit/andlabs/slider.go b/toolkit/andlabs/slider.go index f75947a..f31bc25 100644 --- a/toolkit/andlabs/slider.go +++ b/toolkit/andlabs/slider.go @@ -35,13 +35,60 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT { func newSlider(parentW *toolkit.Widget, w *toolkit.Widget) { var newt *andlabsT - log(debugToolkit, "gui.andlabs.NewTab()", w.Name) + log(debugToolkit, "newSlider()", w.Name) t := mapToolkits[parentW] if (t == nil) { - log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name) + log(debugError, "newSlider() ERROR toolkit struct == nil. name=", parentW.Name, w.Name) return } newt = t.newSlider(w) mapWidgetsToolkits(w, newt) } + +// This routine is very specific to this toolkit +// It's annoying and has to be copied to each widget when there are changes +// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten +// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here! +// but it's time to write direct GTK, QT, macos and windows toolkit plugins +// -- jcarr 2023/03/09 + +func doSlider(p *toolkit.Widget, c *toolkit.Widget) { + if broken(c) { + return + } + log(debugChange, "Going to attempt:", c.Action) + if (c.Action == "New") { + newSlider(p, c) + return + } + ct := mapToolkits[c] + if (ct == nil) { + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + return + } + if ct.broken() { + log(debugError, "Slider() ct.broken", ct) + return + } + if (ct.uiSlider == nil) { + log(debugError, "Label() uiSlider == nil", ct) + return + } + switch c.Action { + case "Enable": + ct.uiSlider.Enable() + case "Disable": + ct.uiSlider.Disable() + case "Show": + ct.uiSlider.Show() + case "Hide": + ct.uiSlider.Hide() + case "Set": + ct.uiSlider.SetValue(c.I) + case "Get": + c.I = ct.uiSlider.Value() + default: + log(debugError, "Can't do", c.Action, "to a Slider") + } +} diff --git a/toolkit/andlabs/spinner.go b/toolkit/andlabs/spinner.go index 2ee556c..2e87541 100644 --- a/toolkit/andlabs/spinner.go +++ b/toolkit/andlabs/spinner.go @@ -36,9 +36,56 @@ func newSpinner(parentW *toolkit.Widget, w *toolkit.Widget) { t := mapToolkits[parentW] if (t == nil) { - log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name) + log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name) return } newt = t.newSpinner(w) mapWidgetsToolkits(w, newt) } + +// This routine is very specific to this toolkit +// It's annoying and has to be copied to each widget when there are changes +// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten +// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here! +// but it's time to write direct GTK, QT, macos and windows toolkit plugins +// -- jcarr 2023/03/09 + +func doSpinner(p *toolkit.Widget, c *toolkit.Widget) { + if broken(c) { + return + } + log(debugChange, "Going to attempt:", c.Action) + if (c.Action == "New") { + newSpinner(p, c) + return + } + ct := mapToolkits[c] + if (ct == nil) { + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + return + } + if ct.broken() { + log(debugError, "Spinner() ct.broken", ct) + return + } + if (ct.uiSpinbox == nil) { + log(debugError, "Label() uiSpinbox == nil", ct) + return + } + switch c.Action { + case "Enable": + ct.uiSpinbox.Enable() + case "Disable": + ct.uiSpinbox.Disable() + case "Show": + ct.uiSpinbox.Show() + case "Hide": + ct.uiSpinbox.Hide() + case "Set": + ct.uiSpinbox.SetValue(c.I) + case "Get": + c.I = ct.uiSpinbox.Value() + default: + log(debugError, "Can't do", c.Action, "to a Spinbox") + } +} diff --git a/toolkit/andlabs/tab.go b/toolkit/andlabs/tab.go index aaac102..9dcd3fa 100644 --- a/toolkit/andlabs/tab.go +++ b/toolkit/andlabs/tab.go @@ -130,3 +130,53 @@ func newTab(parentW *toolkit.Widget, w *toolkit.Widget) { newt = t.newTab(w.Name) mapWidgetsToolkits(w, newt) } + +func doTab(p *toolkit.Widget, c *toolkit.Widget) { + if broken(c) { + return + } + if (c.Action == "New") { + newTab(p, c) + return + } + ct := mapToolkits[c] + if (ct == nil) { + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + return + } + if ct.broken() { + log(debugError, "Tab() ct.broken", ct) + return + } + if (ct.uiTab == nil) { + + log(debugError, "Tab() uiTab == nil", ct) + return + } + log(debugChange, "Going to attempt:", c.Action) + switch c.Action { + case "Enable": + ct.uiTab.Enable() + case "Disable": + ct.uiTab.Disable() + case "Show": + ct.uiTab.Show() + case "Hide": + ct.uiTab.Hide() + case "Get": + c.I = ct.uiTab.NumPages() + case "Add": + log(true, "how do I add a tab here in doTab()?") + dump(p, c, true) + case "SetMargin": + i := ct.uiTab.NumPages() + log(true, "tab.NumPages() =", i) + for i > 0 { + i -= 1 + log(true, "uiTab.SetMargined(true) for i =", i) + ct.uiTab.SetMargined(i, c.B) + } + default: + log(debugError, "Can't do", c.Action, "to a Tab") + } +} diff --git a/toolkit/andlabs/textbox.go b/toolkit/andlabs/textbox.go index ddc27a4..9f7c3b4 100644 --- a/toolkit/andlabs/textbox.go +++ b/toolkit/andlabs/textbox.go @@ -95,11 +95,11 @@ func doTextbox(p *toolkit.Widget, c *toolkit.Widget) { } ct := mapToolkits[c] if (ct == nil) { - log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) return } if ct.broken() { - log(true, "Textbox() ct.broken", ct) + log(debugError, "Textbox() ct.broken", ct) return } if (ct.uiMultilineEntry == nil) { @@ -124,7 +124,7 @@ func (t *andlabsT) doSimpleAction() { } else if (t.uiMultilineEntry != nil) { t.uiMultilineEntry.Enable() } else { - log(true, "don't know what to enable", t.Name) + log(debugError, "don't know what to enable", t.Name) } case "Disable": if (t.uiEntry != nil) { @@ -132,12 +132,14 @@ func (t *andlabsT) doSimpleAction() { } else if (t.uiMultilineEntry != nil) { t.uiMultilineEntry.Disable() } else { - log(true, "don't know what to disable", t.Name) + log(debugError, "don't know what to disable", t.Name) } case "Show": t.uiMultilineEntry.Show() case "Hide": t.uiMultilineEntry.Hide() + case "SetText": + t.uiMultilineEntry.SetText(t.tw.S) case "Set": t.uiMultilineEntry.SetText(t.tw.S) default: diff --git a/toolkit/andlabs/widget.go b/toolkit/andlabs/widget.go index 58f8514..2ea15d1 100644 --- a/toolkit/andlabs/widget.go +++ b/toolkit/andlabs/widget.go @@ -16,7 +16,7 @@ func listMap(b bool) { for t, w := range mapWidgets { log(b, "andlabs =", t.Name, "widget =", w.Name) } - log(debugToolkit, "listMap() HERE mapToolkits()") + log(b, "listMap() HERE mapToolkits()") for w, t := range mapToolkits { log(b, "andlabs =", t, "widget =", w.Name) t.Dump(b) @@ -40,12 +40,12 @@ func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) { log(true, "mapToolkits[w] is set, but mapWidgets[t] is nil") panic("WTF mapWidgets[t] == nil") } - log(true, "mapToolkits[w] is", tw) + log(debugToolkit, "mapToolkits[w] is", tw) if (tw == nil) { - log(true, "BAD map? mapWidgets[w] tw == nil") + log(debugError, "BAD map? mapWidgets[w] tw == nil") } else { - log(true, "BAD map? mapWidgets[w] is", tw) - tw.Dump(true) + log(debugError, "BAD map? mapWidgets[w] is", tw) + tw.Dump(debugError) } } @@ -57,10 +57,10 @@ func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) { panic("WTF mapToolkits[w] == nil") } if (wt == nil) { - log(true, "BAD map? mapWidgets[t] wt == nil") + log(debugError, "BAD map? mapWidgets[t] wt == nil") } else { - log(true, "BAD map? mapWidgets[t] is", wt) - widgetDump(true, wt) + log(debugError, "BAD map? mapWidgets[t] is", wt) + widgetDump(debugError, wt) } } log(debugToolkit, "map of widget worked", w.Type, ",", w.Name, ",", w.Action) diff --git a/toolkit/andlabs/window.go b/toolkit/andlabs/window.go index 40cd410..8251e30 100644 --- a/toolkit/andlabs/window.go +++ b/toolkit/andlabs/window.go @@ -53,3 +53,47 @@ func (t *andlabsT) SetWindowTitle(title string) { log(debugToolkit, "Setting the window title", title) } } + +func doWindow(c *toolkit.Widget) { + if broken(c) { + return + } + if (c.Action == "New") { + newWindow(c) + return + } + ct := mapToolkits[c] + if (ct == nil) { + log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c) + return + } + if (ct.uiWindow == nil) { + log(debugError, "Window() uiWindow == nil", ct) + return + } + log(debugChange, "Going to attempt:", c.Action) + switch c.Action { + case "Show": + ct.uiWindow.Show() + case "Hide": + ct.uiWindow.Hide() + case "Enable": + ct.uiWindow.Enable() + case "Disable": + ct.uiWindow.Disable() + case "Get": + c.S = ct.uiWindow.Title() + case "Set": + ct.uiWindow.SetTitle(c.S) + case "SetText": + ct.uiWindow.SetTitle(c.S) + case "SetMargin": + ct.uiWindow.SetMargined(c.B) + case "SetBorder": + ct.uiWindow.SetBorderless(c.B) + case "Delete": + ct.uiWindow.Destroy() + default: + log(debugError, "Can't do", c.Action, "to a Window") + } +} diff --git a/toolkit/democui/Makefile b/toolkit/democui/Makefile new file mode 100644 index 0000000..6f3f7d9 --- /dev/null +++ b/toolkit/democui/Makefile @@ -0,0 +1,11 @@ +all: plugin + ldd ../democui.so + +build: + GO111MODULE="off" go build + +plugin: + GO111MODULE="off" go build -buildmode=plugin -o ../democui.so + +objdump: + objdump -t ../democui.so |less diff --git a/toolkit/democui/debug.go b/toolkit/democui/debug.go new file mode 100644 index 0000000..817ee6e --- /dev/null +++ b/toolkit/democui/debug.go @@ -0,0 +1,107 @@ +package main + +import "git.wit.org/wit/gui/toolkit" + +var defaultBehavior bool = true + +var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack? +var canvas bool // if set to true, the windows are a raw canvas +var menubar bool // for windows +var stretchy bool // expand things like buttons to the maximum size +var padded bool // add space between things like buttons +var margin bool // add space around the frames of windows + +var debugToolkit bool +var debugChange bool +var debugPlugin bool +var debugFlags bool +var debugError bool = true + +// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc +func setDefaultBehavior(s bool) { + defaultBehavior = s + if (defaultBehavior) { + log(debugToolkit, "Setting this toolkit to use the default behavior.") + log(debugToolkit, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.") + stretchy = false + padded = true + menubar = true + margin = true + canvas = false + bookshelf = true // 99% of the time, things make a vertical stack of objects + } else { + log(debugToolkit, "This toolkit is set to ignore the default behavior.") + } +} + +func ShowDebug () { + log(true, "debugToolkit =", debugToolkit) + log(true, "debugChange =", debugChange) + log(true, "debugPlugin =", debugPlugin) + log(true, "debugFlags =", debugFlags) + log(true, "debugError =", debugError) +} + +/* +func (t *gocuiT) Dump(b bool) { + if ! b { + return + } + log(b, "Name = ", t.Name, t.Width, t.Height) + if (t.uiBox != nil) { + log(b, "uiBox =", t.uiBox) + } + if (t.uiButton != nil) { + log(b, "uiButton =", t.uiButton) + } + if (t.uiCombobox != nil) { + log(b, "uiCombobox =", t.uiCombobox) + } + if (t.uiWindow != nil) { + log(b, "uiWindow =", t.uiWindow) + } + if (t.uiTab != nil) { + log(b, "uiTab =", t.uiTab) + } + if (t.uiGroup != nil) { + log(b, "uiGroup =", t.uiGroup) + } + if (t.uiEntry != nil) { + log(b, "uiEntry =", t.uiEntry) + } + if (t.uiMultilineEntry != nil) { + log(b, "uiMultilineEntry =", t.uiMultilineEntry) + } + if (t.uiSlider != nil) { + log(b, "uiSlider =", t.uiSlider) + } + if (t.uiCheckbox != nil) { + log(b, "uiCheckbox =", t.uiCheckbox) + } + widgetDump(b, t.tw) +} +*/ + +func widgetDump(b bool, w *toolkit.Widget) { + if (w == nil) { + log(b, "widget = nil") + return + } + + log(b, "widget.Name =", w.Name) + log(b, "widget.Action =", w.Action) + log(b, "widget.Type =", w.Type) + log(b, "widget.Custom =", w.Custom) + log(b, "widget.B =", w.B) + log(b, "widget.I =", w.I) + log(b, "widget.Width =", w.Width) + log(b, "widget.Height =", w.Height) + log(b, "widget.X =", w.X) + log(b, "widget.Y =", w.Y) +} + +/* +func GetDebugToolkit () bool { + return debugToolkit +} +*/ diff --git a/toolkit/democui/log.go b/toolkit/democui/log.go new file mode 100644 index 0000000..afd1280 --- /dev/null +++ b/toolkit/democui/log.go @@ -0,0 +1,135 @@ +// +// version v1.3 +// +// I like things to be easy. +// +// combining logging inside of a gui made me do this +// +// this means all the log settings are in one place. it should allow +// things to be over-ridden externally to the library +// but still allow command line --args to pass debugging settings +// +// I also have a generic sleep() and exit() in here because it's simple +// +// Usage: +// +// log("something", foo, bar) +// var DEBUG bool = true +// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing +// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging! +// +package main + +import ( + "os" + golog "log" + "time" + "reflect" + "github.com/davecgh/go-spew/spew" +) + +var LOGOFF bool = false // turn this off, all logging stops +var WARN bool +var INFO bool + +type spewt struct { + a bool +} + +var SPEW spewt + + +/* + sleep() # you know what this does? sleeps for 1 second. yep. dump. easy. + sleep(.1) # you know what this does? yes, it sleeps for 1/10th of a second +*/ +func sleep(a ...any) { + if (a == nil) { + time.Sleep(time.Second) + return + } + + log(true, "sleep", a[0]) + + switch a[0].(type) { + case int: + time.Sleep(time.Duration(a[0].(int)) * time.Second) + case float64: + time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond) + default: + log("sleep a[0], type = ", a[0], reflect.TypeOf(a[0])) + } +} + +/* + exit() # yep. exits. I guess everything must be fine + exit(3) # I guess 3 it is then + exit("dont like apples") # ok. I'll make a note of that +*/ +func exit(a ...any) { + log(true, "exit", a) + //if (a) { + // os.Exit(a) + //} + os.Exit(0) +} + +/* + I've spent, am spending, too much time thinking about 'logging'. 'log', 'logrus', 'zap', whatever. + I'm not twitter. i don't give a fuck about how many nanoseconds it takes to log. Anyway, this + implementation is probably faster than all of those because you just set one bool to FALSE + and it all stops. + Sometimes I need to capture to stdout, sometimes stdout can't + work because it doesn't exist for the user. This whole thing is a PITA. Then it's spread + over 8 million references in every .go file. I'm tapping out and putting + it in one place. here it is. Also, this makes having debug levels really fucking easy. + You can define whatever level of logging you want from anywhere (command line) etc. + + log() # doesn't do anything + log(stuff) # sends it to whatever log you define in a single place. here is the place +*/ + +func log(a ...any) { + if (LOGOFF) { + return + } + + if (a == nil) { + return + } + var tbool bool + if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) { + if (a[0] == false) { + return + } + a[0] = "GUI/Toolkit/gocui" + } + + if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) { + // a = a[1:] + a[0] = "GUI/Toolkit/gocui" + if (debugToolkit) { + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(a) + // spew.Dump(a) + } + return + } + + golog.Println(a...) +} + +func logindent(depth int, format string, a ...interface{}) { + var tabs string + for i := 0; i < depth; i++ { + tabs = tabs + format + } + + // newFormat := tabs + strconv.Itoa(depth) + " " + format + newFormat := tabs + format + log(debugToolkit, newFormat, a) +} + +func setOutput(f *os.File) { + golog.SetOutput(f) +} diff --git a/toolkit/gocui/orig/mouse.go b/toolkit/democui/mouse.go index 7c77b14..efda307 100644 --- a/toolkit/gocui/orig/mouse.go +++ b/toolkit/democui/mouse.go @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package toolkit +package main import ( "errors" "fmt" - "log" "os" "github.com/awesome-gocui/gocui" @@ -30,26 +29,26 @@ func mouseClick(name string) { // log.Println("g.Close()") // g.Close() - log.Println("Found andlabs Running custom function for the mouse click") + log("Found andlabs Running custom function for the mouse click") Custom(name) // panic("got andlabs") } func Init() { - log.Println("start Init()") + log("start Init()") f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) if err != nil { - log.Fatalf("error opening file: %v", err) + exit("error opening file: %v", err) } defer f.Close() - log.SetOutput(f) - log.Println("This is a test log entry") + setOutput(f) + log("This is a test log entry") g, err = gocui.NewGui(gocui.OutputNormal, true) if err != nil { - log.Panicln(err) + exit(err) } g.Cursor = true @@ -58,19 +57,19 @@ func Init() { g.SetManagerFunc(layout) if err := keybindings(g); err != nil { - log.Panicln(err) + exit(err) } - log.Println("exit Init()") + log("exit Init()") } func StartConsoleMouse() { defer g.Close() - log.Println("start Main()") + log("start Main()") if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) { - log.Panicln(err) + exit(err) } - log.Println("exit Main()") + log("exit Main()") } func layout(g *gocui.Gui) error { diff --git a/toolkit/democui/plugin.go b/toolkit/democui/plugin.go new file mode 100644 index 0000000..0b26f8f --- /dev/null +++ b/toolkit/democui/plugin.go @@ -0,0 +1,113 @@ +package main + +import ( + // if you include more than just this import + // then your plugin might be doing something un-ideal (just a guess from 2023/02/27) + "git.wit.org/wit/gui/toolkit" + + "github.com/awesome-gocui/gocui" +) + +// This is a map between the widgets in wit/gui and the internal structures of gocui +var viewWidget map[*gocui.View]*toolkit.Widget +var stringWidget map[string]*toolkit.Widget + +func Quit() { + g.Close() +} + +// This lists out the know mappings +func listMap() { + for v, w := range viewWidget { + log("view =", v.Name, "widget name =", w.Name) + } + for s, w := range stringWidget { + log("string =", s, "widget =", w) + } +} + + +// +// This should be called ? +// Pass() ? +// This handles all interaction between the wit/gui package (what golang knows about) +// and this plugin that talks to the OS and does scary and crazy things to make +// a GUI on whatever OS or whatever GUI toolkit you might have (GTK, QT, WASM, libcurses) +// +// Once you are here, you should be in a protected goroutine created by the golang wit/gui package +// +// TODO: make sure you can't escape this goroutine +// +func Send(p *toolkit.Widget, c *toolkit.Widget) { + if (p == nil) { + log(debugPlugin, "Send() parent = nil") + } else { + log(debugPlugin, "Send() parent =", p.Name, ",", p.Type) + } + log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type) + + /* + if (c.Action == "SetMargin") { + log(debugError, "need to implement SetMargin here") + setMargin(c, c.B) + return + } + */ + + switch c.Type { + /* + case toolkit.Window: + // doWindow(c) + case toolkit.Tab: + // doTab(p, c) + case toolkit.Group: + newGroup(p, c) + case toolkit.Button: + newButton(p, c) + case toolkit.Checkbox: + // doCheckbox(p, c) + case toolkit.Label: + // doLabel(p, c) + case toolkit.Textbox: + // doTextbox(p, c) + case toolkit.Slider: + // doSlider(p, c) + case toolkit.Spinner: + // doSpinner(p, c) + case toolkit.Dropdown: + // doDropdown(p, c) + case toolkit.Combobox: + // doCombobox(p, c) + case toolkit.Grid: + // doGrid(p, c) + */ + case toolkit.Flag: + // log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type) + // log(debugFlags, "plugin Send() flag child =", c.Name, c.Type) + // log(debugFlags, "plugin Send() flag child.Action =", c.Action) + // log(debugFlags, "plugin Send() flag child.S =", c.S) + // log(debugFlags, "plugin Send() flag child.B =", c.B) + // log(debugFlags, "plugin Send() what to flag?") + // should set the checkbox to this value + switch c.S { + case "Toolkit": + debugToolkit = c.B + case "Change": + debugChange = c.B + case "Plugin": + debugPlugin = c.B + case "Flags": + debugFlags = c.B + case "Error": + debugError = c.B + case "Show": + ShowDebug() + default: + log(debugError, "Can't set unknown flag", c.S) + } + default: + log(debugError, "plugin Send() unknown parent =", p.Name, p.Type) + log(debugError, "plugin Send() unknown child =", c.Name, c.Type) + log(debugError, "plugin Send() Don't know how to do", c.Type, "yet") + } +} diff --git a/toolkit/gocui/button.go b/toolkit/gocui/button.go index 5b41c48..355dc30 100644 --- a/toolkit/gocui/button.go +++ b/toolkit/gocui/button.go @@ -3,17 +3,15 @@ package main import ( "errors" "fmt" - "log" "strings" "github.com/awesome-gocui/gocui" "git.wit.org/wit/gui/toolkit" ) -func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) { - log.Println("gui.gocui.AddButton()", w.Name) +func newButton(parentW *toolkit.Widget, w *toolkit.Widget) { + log(true, "AddButton()", w.Name) addButton(w.Name) - // viewWidget[v] = w stringWidget[w.Name] = w listMap() } @@ -25,11 +23,11 @@ func addButton(name string) *gocui.View { } v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0) if err == nil { - log.Println("wit/gui internal plugin error", err) + log("wit/gui internal plugin error", err) return nil } if !errors.Is(err, gocui.ErrUnknownView) { - log.Println("wit/gui internal plugin error", err) + log("wit/gui internal plugin error", err) return nil } @@ -39,10 +37,10 @@ func addButton(name string) *gocui.View { currentView, err := baseGui.SetCurrentView(name) if err != nil { - log.Println("wit/gui internal plugin error", err) + log("wit/gui internal plugin error", err) return nil } - log.Println("wit/gui addbutton() current view name =", currentView.Name()) + log("wit/gui addbutton() current view name =", currentView.Name()) views = append(views, name) curView = len(views) - 1 diff --git a/toolkit/gocui/debug.go b/toolkit/gocui/debug.go new file mode 100644 index 0000000..817ee6e --- /dev/null +++ b/toolkit/gocui/debug.go @@ -0,0 +1,107 @@ +package main + +import "git.wit.org/wit/gui/toolkit" + +var defaultBehavior bool = true + +var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack? +var canvas bool // if set to true, the windows are a raw canvas +var menubar bool // for windows +var stretchy bool // expand things like buttons to the maximum size +var padded bool // add space between things like buttons +var margin bool // add space around the frames of windows + +var debugToolkit bool +var debugChange bool +var debugPlugin bool +var debugFlags bool +var debugError bool = true + +// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc +func setDefaultBehavior(s bool) { + defaultBehavior = s + if (defaultBehavior) { + log(debugToolkit, "Setting this toolkit to use the default behavior.") + log(debugToolkit, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.") + stretchy = false + padded = true + menubar = true + margin = true + canvas = false + bookshelf = true // 99% of the time, things make a vertical stack of objects + } else { + log(debugToolkit, "This toolkit is set to ignore the default behavior.") + } +} + +func ShowDebug () { + log(true, "debugToolkit =", debugToolkit) + log(true, "debugChange =", debugChange) + log(true, "debugPlugin =", debugPlugin) + log(true, "debugFlags =", debugFlags) + log(true, "debugError =", debugError) +} + +/* +func (t *gocuiT) Dump(b bool) { + if ! b { + return + } + log(b, "Name = ", t.Name, t.Width, t.Height) + if (t.uiBox != nil) { + log(b, "uiBox =", t.uiBox) + } + if (t.uiButton != nil) { + log(b, "uiButton =", t.uiButton) + } + if (t.uiCombobox != nil) { + log(b, "uiCombobox =", t.uiCombobox) + } + if (t.uiWindow != nil) { + log(b, "uiWindow =", t.uiWindow) + } + if (t.uiTab != nil) { + log(b, "uiTab =", t.uiTab) + } + if (t.uiGroup != nil) { + log(b, "uiGroup =", t.uiGroup) + } + if (t.uiEntry != nil) { + log(b, "uiEntry =", t.uiEntry) + } + if (t.uiMultilineEntry != nil) { + log(b, "uiMultilineEntry =", t.uiMultilineEntry) + } + if (t.uiSlider != nil) { + log(b, "uiSlider =", t.uiSlider) + } + if (t.uiCheckbox != nil) { + log(b, "uiCheckbox =", t.uiCheckbox) + } + widgetDump(b, t.tw) +} +*/ + +func widgetDump(b bool, w *toolkit.Widget) { + if (w == nil) { + log(b, "widget = nil") + return + } + + log(b, "widget.Name =", w.Name) + log(b, "widget.Action =", w.Action) + log(b, "widget.Type =", w.Type) + log(b, "widget.Custom =", w.Custom) + log(b, "widget.B =", w.B) + log(b, "widget.I =", w.I) + log(b, "widget.Width =", w.Width) + log(b, "widget.Height =", w.Height) + log(b, "widget.X =", w.X) + log(b, "widget.Y =", w.Y) +} + +/* +func GetDebugToolkit () bool { + return debugToolkit +} +*/ diff --git a/toolkit/gocui/gocui.go b/toolkit/gocui/gocui.go index 0d7c5a5..0a302bc 100644 --- a/toolkit/gocui/gocui.go +++ b/toolkit/gocui/gocui.go @@ -7,7 +7,6 @@ package main import ( "errors" "fmt" - "log" "os" "git.wit.org/wit/gui/toolkit" @@ -34,17 +33,20 @@ var ( func Init() { baseGui, err = gocui.NewGui(gocui.OutputNormal, true) if err != nil { - log.Panicln(err) + exit(err) } baseGui.Highlight = true baseGui.SelFgColor = gocui.ColorRed baseGui.SelFrameColor = gocui.ColorRed + baseGui.Cursor = true + baseGui.Mouse = true + baseGui.SetManagerFunc(layout) if err := initKeybindings(baseGui); err != nil { - log.Panicln(err) + exit(err) } viewWidget = make(map[*gocui.View]*toolkit.Widget) @@ -54,17 +56,17 @@ func Init() { outf, err = os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) if err != nil { - log.Fatalf("error opening file: %v", err) + exit("error opening file: %v", err) } // hmm. where to put this? // defer outf.Close() - log.SetOutput(outf) - log.Println("This is a test log entry") + setOutput(outf) + log("This is a test log entry") } func Queue(f func()) { - log.Println("QUEUEEEEE") + log("QUEUEEEEE") f() } @@ -79,7 +81,7 @@ func Main(f func()) { // addButton("test 3") f() if err := baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) { - log.Panicln(err) + exit(err) } baseGui.Close() os.Exit(0) diff --git a/toolkit/gocui/group.go b/toolkit/gocui/group.go index 7cea346..2d8600c 100644 --- a/toolkit/gocui/group.go +++ b/toolkit/gocui/group.go @@ -1,18 +1,16 @@ package main import ( - "log" - "git.wit.org/wit/gui/toolkit" ) -func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) { +func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) { if (parentW == nil) { - log.Println("wit/gui plugin error. parent widget == nil") + log(debugError, "plugin error. parent widget == nil") return } if (w == nil) { - log.Println("wit/gui plugin error. widget == nil") + log(debugPlugin, "plugin error. widget == nil") return } if (w.Name == "") { @@ -21,18 +19,18 @@ func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) { if (w.Name == "") { w.Name = "nil newGroup" } - log.Println("gui.gocui.AddGroup", w.Name) + log("AddGroup", w.Name) addGroup(w.Name) stringWidget[w.Name] = w } func addGroup(name string) { - log.Println("addGroup() START name =", name) - log.Println("addGroup() START groupSize =", groupSize, "currentY =", currentY, "currentX =", currentX) + log("addGroup() START name =", name) + log("addGroup() START groupSize =", groupSize, "currentY =", currentY, "currentX =", currentX) currentY = 2 currentX += groupSize + 5 groupSize = 0 - log.Println("addGroup() START, RESET Y = 3, RESET X = ", currentX) + log("addGroup() START, RESET Y = 3, RESET X = ", currentX) } diff --git a/toolkit/gocui/keybindings.go b/toolkit/gocui/keybindings.go index 3443320..43dbf47 100644 --- a/toolkit/gocui/keybindings.go +++ b/toolkit/gocui/keybindings.go @@ -5,17 +5,12 @@ package main import ( -// "errors" -// "fmt" - "log" -// "strings" - "github.com/awesome-gocui/gocui" "git.wit.org/wit/gui/toolkit" ) func initKeybindings(g *gocui.Gui) error { - log.Println("got to initKeybindings") + log("got to initKeybindings") if err := g.SetKeybinding("", 'q', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit @@ -54,7 +49,7 @@ func initKeybindings(g *gocui.Gui) error { } if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - log.Println("tab", v.Name()) + log("tab", v.Name()) return nextView(g, true) }); err != nil { return err @@ -73,27 +68,27 @@ func initKeybindings(g *gocui.Gui) error { } if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - log.Println("down", v.Name()) + log("down", v.Name()) return moveView(g, v, 0, delta) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - log.Println("up", v.Name()) + log("up", v.Name()) return moveView(g, v, 0, -delta) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyEnter, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - log.Println("enter", v.Name()) + log("enter", v.Name()) var w *toolkit.Widget w = stringWidget[v.Name()] if (w == nil) { - log.Println("COULD NOT FIND WIDGET", v.Name()) + log("COULD NOT FIND WIDGET", v.Name()) } else { - log.Println("FOUND WIDGET!", w) + log("FOUND WIDGET!", w) if (w.Custom != nil) { w.Custom() return nil @@ -123,14 +118,14 @@ func initKeybindings(g *gocui.Gui) error { } if err := g.SetKeybinding("", 'h', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - log.Println("help", v.Name()) + log("help", v.Name()) tmp, _ := g.SetViewOnTop("help") - log.Println("help 2", tmp.Name()) + log("help 2", tmp.Name()) // g.SetView("help", 2, 2, 30, 15, 0); g.SetCurrentView("help") // moveView(g, tmp, 0, -delta) if err := g.DeleteView("help"); err != nil { - log.Fatalln("gocui SetKeybinding()", err) + exit("gocui SetKeybinding()", err) } return nil }); err != nil { diff --git a/toolkit/gocui/log.go b/toolkit/gocui/log.go new file mode 100644 index 0000000..afd1280 --- /dev/null +++ b/toolkit/gocui/log.go @@ -0,0 +1,135 @@ +// +// version v1.3 +// +// I like things to be easy. +// +// combining logging inside of a gui made me do this +// +// this means all the log settings are in one place. it should allow +// things to be over-ridden externally to the library +// but still allow command line --args to pass debugging settings +// +// I also have a generic sleep() and exit() in here because it's simple +// +// Usage: +// +// log("something", foo, bar) +// var DEBUG bool = true +// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing +// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging! +// +package main + +import ( + "os" + golog "log" + "time" + "reflect" + "github.com/davecgh/go-spew/spew" +) + +var LOGOFF bool = false // turn this off, all logging stops +var WARN bool +var INFO bool + +type spewt struct { + a bool +} + +var SPEW spewt + + +/* + sleep() # you know what this does? sleeps for 1 second. yep. dump. easy. + sleep(.1) # you know what this does? yes, it sleeps for 1/10th of a second +*/ +func sleep(a ...any) { + if (a == nil) { + time.Sleep(time.Second) + return + } + + log(true, "sleep", a[0]) + + switch a[0].(type) { + case int: + time.Sleep(time.Duration(a[0].(int)) * time.Second) + case float64: + time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond) + default: + log("sleep a[0], type = ", a[0], reflect.TypeOf(a[0])) + } +} + +/* + exit() # yep. exits. I guess everything must be fine + exit(3) # I guess 3 it is then + exit("dont like apples") # ok. I'll make a note of that +*/ +func exit(a ...any) { + log(true, "exit", a) + //if (a) { + // os.Exit(a) + //} + os.Exit(0) +} + +/* + I've spent, am spending, too much time thinking about 'logging'. 'log', 'logrus', 'zap', whatever. + I'm not twitter. i don't give a fuck about how many nanoseconds it takes to log. Anyway, this + implementation is probably faster than all of those because you just set one bool to FALSE + and it all stops. + Sometimes I need to capture to stdout, sometimes stdout can't + work because it doesn't exist for the user. This whole thing is a PITA. Then it's spread + over 8 million references in every .go file. I'm tapping out and putting + it in one place. here it is. Also, this makes having debug levels really fucking easy. + You can define whatever level of logging you want from anywhere (command line) etc. + + log() # doesn't do anything + log(stuff) # sends it to whatever log you define in a single place. here is the place +*/ + +func log(a ...any) { + if (LOGOFF) { + return + } + + if (a == nil) { + return + } + var tbool bool + if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) { + if (a[0] == false) { + return + } + a[0] = "GUI/Toolkit/gocui" + } + + if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) { + // a = a[1:] + a[0] = "GUI/Toolkit/gocui" + if (debugToolkit) { + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(a) + // spew.Dump(a) + } + return + } + + golog.Println(a...) +} + +func logindent(depth int, format string, a ...interface{}) { + var tabs string + for i := 0; i < depth; i++ { + tabs = tabs + format + } + + // newFormat := tabs + strconv.Itoa(depth) + " " + format + newFormat := tabs + format + log(debugToolkit, newFormat, a) +} + +func setOutput(f *os.File) { + golog.SetOutput(f) +} diff --git a/toolkit/gocui/plugin.go b/toolkit/gocui/plugin.go index 5be26f3..2b01acc 100644 --- a/toolkit/gocui/plugin.go +++ b/toolkit/gocui/plugin.go @@ -1,8 +1,8 @@ package main import ( - "log" - + // if you include more than just this import + // then your plugin might be doing something un-ideal (just a guess from 2023/02/27) "git.wit.org/wit/gui/toolkit" "github.com/awesome-gocui/gocui" @@ -19,10 +19,97 @@ func Quit() { // This lists out the know mappings func listMap() { for v, w := range viewWidget { - log.Println("view =", v.Name, "widget name =", w.Name) + log("view =", v.Name, "widget name =", w.Name) } for s, w := range stringWidget { - log.Println("string =", s, "widget =", w) + log("string =", s, "widget =", w) } } + +// +// This should be called ? +// Pass() ? +// This handles all interaction between the wit/gui package (what golang knows about) +// and this plugin that talks to the OS and does scary and crazy things to make +// a GUI on whatever OS or whatever GUI toolkit you might have (GTK, QT, WASM, libcurses) +// +// Once you are here, you should be in a protected goroutine created by the golang wit/gui package +// +// TODO: make sure you can't escape this goroutine +// +func Send(p *toolkit.Widget, c *toolkit.Widget) { + if (p == nil) { + log(debugPlugin, "Send() parent = nil") + } else { + log(debugPlugin, "Send() parent =", p.Name, ",", p.Type) + } + log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type) + + /* + if (c.Action == "SetMargin") { + log(debugError, "need to implement SetMargin here") + setMargin(c, c.B) + return + } + */ + + switch c.Type { + /* + case toolkit.Window: + // doWindow(c) + case toolkit.Tab: + // doTab(p, c) + */ + case toolkit.Group: + newGroup(p, c) + case toolkit.Button: + newButton(p, c) + /* + case toolkit.Checkbox: + // doCheckbox(p, c) + case toolkit.Label: + // doLabel(p, c) + case toolkit.Textbox: + // doTextbox(p, c) + case toolkit.Slider: + // doSlider(p, c) + case toolkit.Spinner: + // doSpinner(p, c) + case toolkit.Dropdown: + // doDropdown(p, c) + case toolkit.Combobox: + // doCombobox(p, c) + case toolkit.Grid: + // doGrid(p, c) + */ + case toolkit.Flag: + // log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type) + // log(debugFlags, "plugin Send() flag child =", c.Name, c.Type) + // log(debugFlags, "plugin Send() flag child.Action =", c.Action) + // log(debugFlags, "plugin Send() flag child.S =", c.S) + // log(debugFlags, "plugin Send() flag child.B =", c.B) + // log(debugFlags, "plugin Send() what to flag?") + // should set the checkbox to this value + switch c.S { + case "Toolkit": + debugToolkit = c.B + case "Change": + debugChange = c.B + case "Plugin": + debugPlugin = c.B + case "Flags": + debugFlags = c.B + case "Error": + debugError = c.B + case "Show": + ShowDebug() + default: + log(debugError, "Can't set unknown flag", c.S) + } + default: + log(debugError, "plugin Send() unknown parent =", p.Name, p.Type) + log(debugError, "plugin Send() unknown child =", c.Name, c.Type) + log(debugError, "plugin Send() Don't know how to do", c.Type, "yet") + } +} diff --git a/toolkit/gocui/views.go b/toolkit/gocui/views.go index defe2b2..8b17acf 100644 --- a/toolkit/gocui/views.go +++ b/toolkit/gocui/views.go @@ -7,7 +7,6 @@ package main import ( "errors" "fmt" - "log" "strings" "github.com/awesome-gocui/gocui" @@ -71,11 +70,11 @@ func moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error { if err != nil { return err } - log.Println(x0, y0, x1, y1) + log(x0, y0, x1, y1) if _, err := g.SetView(name, x0+dx, y0+dy, x1+dx, y1+dy, 0); err != nil { return err } x0, y0, x1, y1, err = g.ViewPosition(name) - log.Println(x0, y0, x1, y1) + log(x0, y0, x1, y1) return nil } diff --git a/toolkit/gocui/window.go b/toolkit/gocui/window.go index b2d241d..67948d6 100644 --- a/toolkit/gocui/window.go +++ b/toolkit/gocui/window.go @@ -1,18 +1,16 @@ package main import ( - "log" - "git.wit.org/wit/gui/toolkit" ) func NewWindow(w *toolkit.Widget) { if (w == nil) { - log.Println("wit/gui plugin error. widget == nil") + log("wit/gui plugin error. widget == nil") return } if (w.Name == "") { w.Name = "nil newWindow" } - log.Println("gui.gocui.AddWindow", w.Name) + log("gui.gocui.AddWindow", w.Name) } diff --git a/toolkit/widget.go b/toolkit/widget.go index 9241d5a..30169ba 100644 --- a/toolkit/widget.go +++ b/toolkit/widget.go @@ -11,18 +11,26 @@ package toolkit // Event() seems like a good name. // Could a protobuf be used here? (Can functions be passed?) type Widget struct { - Name string // "New", "Delete", "Set", aka something to do - Action string // "New", "Delete", "Set", aka something to do - // Type string // after lots of back and forth, a simple string + Name string + Action string // "New", "Delete", "Set", aka something to do Type WidgetType + // This function is how you interact with the toolkit + // latest attempt. seems to work so far (2023/02/28) + // Hopefully this will be the barrier between the goroutines + // TODO: move this interaction to channels + Custom func() + + // re-adding an id to test channels + id int + // This is how the values are passed back and forth // values from things like checkboxes & dropdown's // The string is also used to set the button name B bool I int - // maybe safe if there is correctly working Custom() between goroutines - // (still probably not, almost certainly not) + // maybe safe if there is correctly working Custom() between goroutines? + // (still probably not, almost certainly not. not possible. layer violation?) S string // not safe to have 'S' // This GUI is intended for simple things @@ -38,10 +46,6 @@ type Widget struct { // Make widgets fill up the space available Expand bool - - // latest attempt. seems to work so far (2023/02/28) - // Hopefully this will be the barrier between the goroutines - Custom func() } type WidgetType int @@ -62,6 +66,8 @@ const ( Slider Spinner Grid + Box + Image Flag ) @@ -93,6 +99,10 @@ func (s WidgetType) String() string { return "Spinner" case Grid: return "Grid" + case Box: + return "Box" + case Image: + return "Image" case Flag: return "Flag" case Unknown: @@ -100,3 +110,15 @@ func (s WidgetType) String() string { } return "GuiToolkitTUndefinedType" } + +// this is hopefully just used in a very few places for +// debuging the interaction between go apps and the underlying +// toolkits. Hopefully this is less prone to problems and can +// detect memory leaks, threading problems, memory allocation & mapping errors, etc +func (w *Widget) GetId() int { + return w.id +} + +func (w *Widget) SetId(i int) { + w.id = i +} |
