Compare commits

..

50 Commits

Author SHA1 Message Date
Jeff Carr cb3047ab09 quiet output related to expected init() conditions 2025-03-10 04:37:21 -05:00
Jeff Carr bdb93a7b57 andlabs is unstable. need to switch to protobuf 2025-03-05 03:43:38 -06:00
Jeff Carr 8a71fc4012 maybe this will get fyne to work 2025-03-04 01:57:44 -06:00
Jeff Carr cd62709b64 work on tables 2025-02-24 11:00:23 -06:00
Jeff Carr 8ced00be79 build was wrong 2025-02-22 07:18:14 -06:00
Jeff Carr 3184badaec re-disable INFO flag 2025-02-21 18:31:42 -06:00
Jeff Carr 5b9eca7ac0 rm debugging printf 2025-02-21 16:55:26 -06:00
Jeff Carr 3e0b8c3df5 andlabs keeps panic'ing 2025-02-21 13:57:18 -06:00
Jeff Carr b64bf96606 debugging init() 2025-02-13 22:28:59 -06:00
Jeff Carr a264a7d121 add Disable() and Enable() 2025-02-13 21:04:25 -06:00
Jeff Carr 5530d2c6ad subbed in table() 2025-02-13 20:33:04 -06:00
Jeff Carr a16207bd1e stubbed in tables 2025-02-13 20:11:53 -06:00
Jeff Carr 514b39e382 better filename 2025-02-13 14:27:32 -06:00
Jeff Carr 0c0c42ecbb works again 2025-02-13 14:27:13 -06:00
Jeff Carr 9babe64e41 minor 2025-02-12 16:03:23 -06:00
Jeff Carr 17cff379fa clean was not complete 2025-01-09 21:16:04 -06:00
Jeff Carr 331e75e348 more correct build 2024-12-06 01:50:45 -06:00
Jeff Carr 6f08f22ca8 closer to purer plugin testing 2024-12-05 19:08:29 -06:00
Jeff Carr 9d965ee05a minor 2024-12-05 17:43:11 -06:00
Jeff Carr d14f8985e0 no .so 2024-12-03 00:47:13 -06:00
Jeff Carr 2246f8852a use this until 'package plugin' works 2024-12-02 05:16:42 -06:00
Jeff Carr ac6a348f54 add 'make install' for testing 2024-12-01 00:49:52 -06:00
Jeff Carr 03cc26d91f sets go list .Doc to 'plugin' 2024-11-28 22:58:26 -06:00
Jeff Carr c5ecf7ca32 avoid window in window crash. TODO: make it work
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-15 08:15:38 -06:00
Jeff Carr c6f9119c2e part of doc cleanups 2024-02-13 16:16:37 -06:00
Jeff Carr dac22688e2 ignore binary from autotypist automation
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-12 21:35:18 -06:00
Jeff Carr 142be47d3a more node state fixes
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-09 03:44:21 -06:00
Jeff Carr 695f116eec debugging output cleanups
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-07 07:31:28 -06:00
Jeff Carr 99a42bf88b dump old code
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-07 06:58:13 -06:00
Jeff Carr 9aafc45c0b fix textbox
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-05 15:04:01 -06:00
Jeff Carr 1e98d2607b use the new tree functions
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-05 12:06:17 -06:00
Jeff Carr fea47363e0 releases finally work
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-01 16:28:36 -06:00
Jeff Carr 12bfdd93da still debugging nil updates
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-02-01 12:00:02 -06:00
Jeff Carr 366ce47ed8 release automation
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-30 16:15:31 -06:00
Jeff Carr 15df92f123 this probably has to be golang since it uses proprietary OS toolkits
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-30 10:32:00 -06:00
Jeff Carr a3c149cfbc new release
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-28 22:54:56 -06:00
Jeff Carr 890e294a90 remove old code and notes
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 16:10:22 -06:00
Jeff Carr f8059d51d3 release automation
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 13:13:07 -06:00
Jeff Carr e1cd1a27a3 nocui works
release automation testing
    try to track disable state

Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 10:03:01 -06:00
Jeff Carr fbd035f5be release automation failure
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-26 11:22:03 -06:00
Jeff Carr 8a497bf538 new gui release
more quiet output
    allow disabling of more errors
    sets the text on window open
    checkbox state works

Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-26 11:18:01 -06:00
Jeff Carr c017dc9be0 new gui release
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-24 21:48:37 -06:00
Jeff Carr dc8e819e01 go mod new tree
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-21 11:34:17 -06:00
Jeff Carr 40f819c3a2 more logging updates
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-21 11:30:12 -06:00
Jeff Carr 4f3255c681 go mod automation work
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-20 20:57:25 -06:00
Jeff Carr 54a01b3bf1 ignore deletes when they are already deleted
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-19 20:35:33 -06:00
Jeff Carr d15fa1cf88 work on handling Direction
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-19 18:12:30 -06:00
Jeff Carr f48b950655 things are moving to widget.State
pass borderless
    windows correctly destroy themselves from the binary tree
    checkbox state cleanups

Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-19 12:18:11 -06:00
Jeff Carr c2a563ae37 cleanups after node work
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-19 02:52:57 -06:00
Jeff Carr d9a04e92fc new go mod
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-19 00:03:46 -06:00
34 changed files with 624 additions and 634 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*.swp
*.so
go.mod
go.sum
andlabs

1
.plugin Normal file
View File

@ -0,0 +1 @@
// plugin

27
LICENSE Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,13 +1,34 @@
all: plugin
VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d)
plugin:
GO111MODULE="off" go build -v -x -buildmode=plugin -o ../andlabs.so
all: clean goimports vet andlabs.so
andlabs.so:
GO111MODULE=off go build -v -x -buildmode=plugin -o andlabs.so \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
install: clean
go build -v -buildmode=plugin -o ~/go/lib/andlabs-${VERSION}.so \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
cd ~/go/lib && ln -f -s andlabs-${VERSION}.so andlabs.so
clean:
rm -f andlabs andlabs.*so
goget:
GO111MODULE="off" go get -v -t -u
goimports:
goimports -w *.go
vet:
@GO111MODULE=off go vet
@echo this go plugin builds okay
redomod:
rm -f go.*
goimports -w *.go
GO111MODULE= go mod init
GO111MODULE= go mod tidy

3
README.md Normal file
View File

@ -0,0 +1,3 @@
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
// Windows doesn't support plugins. How can I keep andlabs and only compile it on windows?
// https://forum.heroiclabs.com/t/setting-up-goland-to-compile-plugins-on-windows/594/5

236
action.go
View File

@ -1,8 +1,6 @@
package main
import (
"errors"
"go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
@ -14,57 +12,80 @@ import (
// and that there already a widget created
func notNew(n *tree.Node) bool {
if n == nil {
log.Warn("ready() n = nil")
log.Log(ERROR, "notNew() n = nil")
return true
}
if n.TK != nil {
log.Warn("ready() n.TK = nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "notNew() n.TK = nil", n.WidgetId, n.GetProgName())
return true
}
if n.Parent == nil {
log.Warn("ready() n.Parent = nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "notNew() n.Parent = nil", n.WidgetId, n.GetProgName())
return true
}
if n.Parent.TK == nil {
log.Warn("ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
log.Warn("ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
if n.Parent.WidgetId == 0 {
// this is normal if the widget type is a window
if n.WidgetType == widget.Window {
return true
}
}
log.Log(ERROR, "notNew() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "notNew() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
return true
}
// this means you can add a new widgets
return false
}
func tkbad(n *tree.Node) bool {
if n == nil {
log.Log(ERROR, "tkbad() n = nil")
return true
}
if n.TK == nil {
log.Log(ERROR, "tkbad() n.TK = nil", n.WidgetId, n.GetProgName())
return true
}
return false
}
// this makes sure widget and it's parent exists
func ready(n *tree.Node) bool {
if n == nil {
log.Warn("ready() n = nil")
log.Log(ERROR, "ready() n = nil")
return false
}
if n.TK == nil {
log.Warn("ready() n.TK = nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "ready() n.TK = nil", n.WidgetId, n.GetProgName())
return false
}
if n.Parent == nil {
log.Warn("ready() n.Parent = nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "ready() n.Parent = nil", n.WidgetId, n.GetProgName())
return false
}
if n.Parent.TK == nil {
log.Warn("ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
log.Warn("ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
if n.Parent.WidgetId == 0 {
// this is normal if the widget type is a window
if n.WidgetType == widget.Window {
return false
}
return true
}
func (n *node) ready() bool {
if n == nil {
return false
}
if n.tk == nil {
log.Log(ERROR, "ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
return false
}
return true
}
func hide(n *tree.Node) {
show(n, false)
}
func show(n *tree.Node, b bool) {
if tkbad(n) {
return
}
var tk *guiWidget
tk = n.TK.(*guiWidget)
// tk = getTK(n)
@ -82,15 +103,12 @@ func show(n *tree.Node, b bool) {
}
}
func enable(n *tree.Node, b bool) {
var tk *guiWidget
tk = n.TK.(*guiWidget)
if n == nil {
panic("WHAT? enable was passed nil. How does this even happen?")
}
if tk == nil {
func realEnable(n *tree.Node, b bool) {
if !ready(n) {
return
}
var tk *guiWidget
tk = n.TK.(*guiWidget)
if tk.uiControl == nil {
return
}
@ -101,10 +119,13 @@ func enable(n *tree.Node, b bool) {
}
}
func (n *node) pad(b bool) {
log.Warn("pad() on WidgetId =", n.WidgetId)
func pad(n *tree.Node, b bool) {
if tkbad(n) {
return
}
log.Log(ANDLABS, "pad() on WidgetId =", n.WidgetId)
t := n.tk
t := n.TK.(*guiWidget)
if t == nil {
log.Log(ERROR, "pad() toolkit struct == nil. for", n.WidgetId)
return
@ -123,130 +144,69 @@ func (n *node) pad(b bool) {
case widget.Box:
t.uiBox.SetPadded(b)
default:
log.Log(ERROR, "TODO: implement pad() for", n.WidgetType, n.progname)
log.Log(ERROR, "TODO: implement pad() for", n.WidgetType, n.GetProgName())
}
}
func (n *node) move(newParent *node) {
p := n.parent
func showWidget(n *tree.Node) {
log.Info("not implemented in andlabs yet")
// widgetDelete(n)
}
switch p.WidgetType {
case widget.Group:
case widget.Tab:
// tabSetMargined(tParent.uiTab, true)
case widget.Window:
// t.uiWindow.SetBorderless(false)
case widget.Grid:
// t.uiGrid.SetPadded(true)
case widget.Box:
log.Log(INFO, "TODO: move() where =", p.ParentId)
log.Log(INFO, "TODO: move() for widget =", n.WidgetId)
stretchy = true
if p.tk.uiBox != nil {
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
}
default:
log.Log(ERROR, "TODO: need to implement move() for type =", n.WidgetType)
log.Log(ERROR, "TODO: need to implement move() for where =", p.ParentId)
log.Log(ERROR, "TODO: need to implement move() for widget =", n.WidgetId)
}
func hideWidget(n *tree.Node) {
widgetDelete(n)
}
func widgetDelete(n *tree.Node) {
log.Log(NOW, "widgetDelete()", n.WidgetId)
log.Log(ANDLABS, "widgetDelete()", n.WidgetId, n.WidgetType)
var tk *guiWidget
tk = n.TK.(*guiWidget)
if n.WidgetType == widget.Window {
log.Warn("DESTROY uiWindow here")
log.Warn("NEED TO REMOVE n from parent.Children")
log.Log(ANDLABS, "DESTROY uiWindow here")
log.Log(ANDLABS, "DESTROY NEED TO REMOVE n from parent.Children")
if tk.uiWindow != nil {
tk.uiWindow.Destroy()
tk.uiWindow = nil
n.DeleteNode()
}
}
func processAction(a *widget.Action) {
log.Log(INFO, "processAction() START a.ActionType =", a.ActionType, "a.Value", a.Value)
if a.ActionType == widget.ToolkitInit {
Init()
return
}
switch a.WidgetType {
case widget.Root:
if me.treeRoot == nil {
log.Log(INFO, "processAction() found the treeRoot")
me.treeRoot = me.myTree.AddNode(a)
// n.DeleteNode()
} else {
log.Warn("processAction() Something terrible has happened")
log.Warn("processAction() treeNode was sent an action", a.ActionType, a)
log.Log(ANDLABS, "DESTROY can't destroy TODO:", n.WidgetId, n.WidgetType)
}
return
}
log.Warn("andlabs processAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId, a.ActionType)
switch a.WidgetType {
case widget.Flag:
log.Log(ERROR, "processAction() RE-IMPLEMENT LOG FLAGS")
return
}
if me.treeRoot == nil {
panic("me.treeRoot == nil")
}
if a.ActionType == widget.Add {
add(a)
return
}
n := me.treeRoot.FindWidgetId(a.WidgetId)
if n == nil {
log.Error(errors.New("andlabs processAction() ERROR findWidgetId found nil"), a.ActionType, a.WidgetType)
log.Log(NOW, "processAction() ERROR findWidgetId found nil for id =", a.WidgetId)
log.Log(NOW, "processAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
log.Log(NOW, "processAction() ERROR findWidgetId found nil for id =", a.WidgetId)
me.treeRoot.ListWidgets()
return
panic("findWidgetId found nil for id = " + string(a.WidgetId))
}
if a.ActionType == widget.Dump {
log.Log(NOW, "processAction() Dump =", a.ActionType, a.WidgetType, n.State.ProgName)
return
}
switch a.ActionType {
case widget.Delete:
widgetDelete(n)
case widget.Show:
show(n, true)
case widget.Hide:
show(n, false)
case widget.Enable:
enable(n, true)
case widget.Disable:
log.Warn("andlabs got disable for", n.WidgetId, n.State.ProgName)
enable(n, false)
case widget.Get:
setText(n, a)
case widget.GetText:
switch a.WidgetType {
case widget.Textbox:
a.Value = n.State.Value
}
case widget.Set:
setText(n, a)
case widget.SetText:
setText(n, a)
case widget.AddText:
addText(n, a)
default:
log.Log(ERROR, "processAction() Unknown =", a.ActionType, a.WidgetType)
}
log.Log(INFO, "processAction() END =", a.ActionType, a.WidgetType)
}
func SetTitle(n *tree.Node, s string) {
SetText(n, s)
}
func SetLabel(n *tree.Node, s string) {
SetText(n, s)
}
func SetText(n *tree.Node, s string) {
if n == nil {
log.Log(WARN, "Tree Error: Add() sent n == nil")
return
}
if n.TK == nil {
log.Log(WARN, "SetText() Tree sent an action on a widget we didn't seem to have.", n.WidgetId)
return
}
setText(n, s)
log.Log(ANDLABS, "SetText() (new)", n.WidgetType, n.String(), s)
}
func AddText(n *tree.Node, s string) {
if n == nil {
log.Log(WARN, "Tree Error: Add() sent n == nil")
return
}
if n.TK == nil {
log.Log(WARN, "AddText() Tree sent an action on a widget we didn't seem to have.", n.WidgetId)
return
}
log.Log(ANDLABS, "AddText()", n.WidgetType, n.String())
// w := n.TK.(*guiWidget)
// w.AddText(s)
addText(n, s)
}

73
add.go
View File

@ -2,70 +2,81 @@ package main
import (
"go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
)
func add(a *widget.Action) {
log.Warn("andlabs add()", a.WidgetId, a.State.ProgName)
if a.WidgetType == widget.Root {
if me.treeRoot == nil {
me.treeRoot = me.myTree.AddNode(a)
}
return
}
n := me.myTree.AddNode(a)
func add(n *tree.Node) {
p := n.Parent
switch n.WidgetType {
case widget.Window:
log.Warn("SPEEDY Add window", n.WidgetId, n.GetProgName())
newWindow(p, n)
return
case widget.Group:
log.Warn("SPEEDY Add Group", n.WidgetId, n.GetProgName())
newGroup(p, n)
return
case widget.Grid:
newGrid(n)
return
case widget.Box:
newBox(n)
return
/*
case widget.Tab:
newTab(n)
return
*/
case widget.Label:
newLabel(p, n)
return
case widget.Button:
newButton(p, n)
return
case widget.Checkbox:
newCheckbox(p, n)
return
setChecked(n, n.State.Checked)
case widget.Spinner:
newSpinner(p, n)
return
case widget.Slider:
newSlider(p, n)
return
case widget.Dropdown:
newDropdown(p, n)
return
// setText(n, n.State.DefaultS)
case widget.Combobox:
newCombobox(p, n)
return
// setText(n, n.State.DefaultS)
case widget.Textbox:
newTextbox(p, n)
return
// setText(n, n.State.DefaultS)
/*
case widget.Image:
newImage(p, n)
return
*/
default:
log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.State.ProgName)
log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.ProgName())
}
}
func newAdd(n *tree.Node) {
if n == nil {
log.Log(WARN, "Tree Error: Add() sent n == nil")
return
}
if n.WidgetType == widget.Root {
me.treeRoot = n
return
}
if me.treeRoot == nil {
panic("test")
}
add(n)
if n.TK == nil {
if n.WidgetId == 1 || n.WidgetId == 2 {
// this is normal at plugin init() time
} else {
// this probably shouldn't be happening
log.Log(WARN, "newAdd() Tree sent an action on a widget we didn't seem to have.", n.WidgetId, n.WidgetType, n.ProgName())
}
// Probably something went wrong and we should reset / redraw everything?
n.TK = initWidget(n)
}
// show(n, !a.State.Hidden)
if n.Hidden() {
hide(n)
} else {
if n.State.Enable {
// nothing to do
} else {
realEnable(n, false)
}
}
}

View File

@ -6,39 +6,23 @@ import (
"go.wit.com/widget"
)
func compareStrings(n *tree.Node, ss []string) {
}
// func (n *node) addText(a *widget.Action) {
func addText(n *tree.Node, a *widget.Action) {
func realAddText(n *tree.Node, s string) {
var tk *guiWidget
tk = n.TK.(*guiWidget)
log.Warn("andlabs addText() START with a.Value =", a.Value)
log.Log(ANDLABS, "addText() START with s =", s)
if tk == nil {
log.Log(ERROR, "addText error. tk == nil", n.State.ProgName, n.WidgetId)
return
}
log.Warn("andlabs addText() Attempt on", n.WidgetType, "with", a.Value)
log.Log(ANDLABS, "addText() Attempt on", n.WidgetType, "with", s)
switch n.WidgetType {
case widget.Dropdown:
for i, s := range a.State.Strings {
log.Warn("andlabs a.State.Strings =", i, s)
_, ok := n.Strings[s]
// If the key exists
if ok {
log.Warn("andlabs a.State.Strings is here", i, s)
} else {
log.Warn("andlabs is not here", i, s)
addDropdownName(n, s)
// TODO: make numbers
n.Strings[s] = 21
}
}
case widget.Combobox:
addComboboxName(n, widget.GetString(a.Value))
addComboboxName(n, s)
default:
log.Log(ERROR, "plugin Send() Don't know how to addText on", n.WidgetType, "yet", a.ActionType)
log.Log(ERROR, "addText() doesn't work on", n.WidgetType)
}
log.Log(CHANGE, "addText() END with a.Value =", a.Value)
log.Log(ANDLABS, "addText() END with =", s)
}

33
box.go
View File

@ -31,26 +31,25 @@ func newBox(n *tree.Node) {
}
/*
rawBox -- hack to arbitrarily add a box in andlabs to work
around the problem that a "group" can not have one entry in it
TODO: fix this so that a box is "added on demand" that is,
if "go.wit.com/gui" sends you a 2nd thing to add to a group,
automatically add a box then. The problem with this, is the macos, windows and linux gtk
will panic on a move when an chind object is disasociated from the group
I haven't had time to try to debug this, so, instead, it's just probably better to always
add a box here. There doesn't seem to be any real issue with forcing a box to be inserted
into the toolkits that is "outside" the binary tree of widgets. This only means, that on
a destroy of the tree, this box must be checked
rawBox -- hack to arbitrarily add a box in andlabs to work
around the problem that a "group" can not have one entry in it
TODO: fix this so that a box is "added on demand" that is,
if "go.wit.com/gui" sends you a 2nd thing to add to a group,
automatically add a box then. The problem with this, is the macos, windows and linux gtk
will panic on a move when an chind object is disasociated from the group
I haven't had time to try to debug this, so, instead, it's just probably better to always
add a box here. There doesn't seem to be any real issue with forcing a box to be inserted
into the toolkits that is "outside" the binary tree of widgets. This only means, that on
a destroy of the tree, this box must be checked
even that is a probably not senario however since clicking on the close box in the toolkit
has the operating system destroy everything in the window. it may or may not be possible
to control that behavior. at this time, it's "undetermined" and the best course of action
is to detect the window is destroyed and then remove all the toolkit information
from all the nodes in the binary tree
even that is a probably not senario however since clicking on the close box in the toolkit
has the operating system destroy everything in the window. it may or may not be possible
to control that behavior. at this time, it's "undetermined" and the best course of action
is to detect the window is destroyed and then remove all the toolkit information
from all the nodes in the binary tree
TODO: handle user killing/closing a window using the OS
TODO: handle user killing/closing a window using the OS
*/
// func (n *node) rawBox() *ui.Box {
func rawBox(n *tree.Node) *ui.Box {
var box *ui.Box

View File

@ -7,7 +7,6 @@ import (
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
// func (p *node) newButton(n *node) {
func newButton(p *tree.Node, n *tree.Node) {
if notNew(n) {
return
@ -22,7 +21,7 @@ func newButton(p *tree.Node, n *tree.Node) {
newt.parent = ptk
b.OnClicked(func(*ui.Button) {
me.myTree.DoUserEvent(n)
me.myTree.SendUserEvent(n)
})
n.TK = newt

View File

@ -1,7 +1,9 @@
package main
import (
"go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
@ -17,8 +19,11 @@ func newCheckbox(p *tree.Node, n *tree.Node) {
newt.uiControl = newt.uiCheckbox
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
n.SetValue(newt.checked())
me.myTree.DoUserEvent(n)
var b bool
b = newt.checked()
n.State.Checked = b
log.Log(ANDLABS, "Checkbox is now =", b)
me.myTree.SendUserEvent(n)
})
n.TK = newt
@ -28,3 +33,12 @@ func newCheckbox(p *tree.Node, n *tree.Node) {
func (t *guiWidget) checked() bool {
return t.uiCheckbox.Checked()
}
func realSetChecked(n *tree.Node, b bool) {
if n.WidgetType != widget.Checkbox {
}
var tk *guiWidget
tk = n.TK.(*guiWidget)
tk.uiCheckbox.SetChecked(b)
}

View File

@ -23,24 +23,22 @@ func newCombobox(p, n *tree.Node) {
newt.val = make(map[int]string)
cb.OnChanged(func(spin *ui.EditableCombobox) {
n.SetValue(spin.Text())
log.Warn("combobox changed =" + spin.Text() + ".")
me.myTree.DoUserEvent(n)
n.State.CurrentS = spin.Text()
log.Log(ANDLABS, "combobox changed ="+spin.Text()+".")
me.myTree.SendUserEvent(n)
})
n.TK = newt
place(p, n)
log.Warn("add combobox entries on create:", n.State.Strings)
log.Warn("add combobox entries on create:", n.State.Strings)
log.Warn("add combobox entries on create:", n.State.Strings)
log.Log(ANDLABS, "add combobox entries on create:", n.State.Strings)
// add the initial combobox entries
for i, s := range n.State.Strings {
log.Warn("add combobox entries on create", n.GetProgName(), i, s)
log.Log(ANDLABS, "add combobox entries on create progname:", n.GetProgName(), "State.Strings =", i, s)
addComboboxName(n, s)
}
cur := n.String()
log.Warn("add combobox: TODO: set default value on create", n.GetProgName(), cur)
cur := n.CurrentS()
log.Log(ANDLABS, "add combobox: set default value on create to", cur)
setComboboxName(n, cur)
}
@ -50,7 +48,7 @@ func addComboboxName(n *tree.Node, s string) {
}
var tk *guiWidget
tk = n.TK.(*guiWidget)
log.Log(INFO, "addComboboxName()", n.WidgetId, "add:", s)
log.Log(ANDLABS, "addComboboxName()", n.WidgetId, "add:", s)
tk.uiEditableCombobox.Append(s)
if tk.val == nil {
@ -61,7 +59,7 @@ func addComboboxName(n *tree.Node, s string) {
// If this is the first menu added, set the dropdown to it
if tk.c == 0 {
log.Log(INFO, "THIS IS THE FIRST combobox", s)
log.Log(ANDLABS, "addComboboxName() first string:", s)
tk.uiEditableCombobox.SetText(s)
}
tk.c = tk.c + 1
@ -73,7 +71,7 @@ func setComboboxName(n *tree.Node, s string) bool {
}
var tk *guiWidget
tk = n.TK.(*guiWidget)
log.Log(INFO, "SetComboboxName()", n.WidgetId, ",", s)
log.Log(ANDLABS, "SetComboboxName()", n.WidgetId, ",", s)
tk.uiEditableCombobox.SetText(s)
return false
}

View File

@ -1,61 +0,0 @@
package main
import (
"go.wit.com/widget"
)
type node struct {
parent *node
children []*node
WidgetId int // widget ID
WidgetType widget.WidgetType
ParentId int // parent ID
state widget.State
// a reference name for programming and debuggign. Must be unique
progname string
// the text used for button labesl, window titles, checkbox names, etc
label string
// horizontal means layout widgets like books on a bookshelf
// vertical means layout widgets like books in a stack
// direction widget.Orientation
direction widget.Orientation
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
value any
strings []string
// This is used for things like a slider(0,100)
X int
Y int
// This is for the grid size & widget position
W int
H int
AtW int
AtH int
vals []string // dropdown menu items
// horizontal bool `default:false`
hasTabs bool // does the window have tabs?
currentTab bool // the visible tab
// the internal plugin toolkit structure
// in the gtk plugin, it has gtk things like margin & border settings
// in the text console one, it has text console things like colors for menus & buttons
tk *guiWidget
}
/*
func (n *node) doUserEvent() {
log.Log(ERROR, "doUserEvent() ERROR")
}
*/

View File

@ -6,13 +6,16 @@ import (
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 = false
var debugChange bool = false
var debugPlugin bool = false
@ -21,23 +24,9 @@ var debugFlags bool = false
var debugGrid bool = false
var debugNow bool = true
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.Log(NOW, "Setting this toolkit to use the default behavior.")
log.Log(NOW, "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.Log(NOW, "This toolkit is set to ignore the default behavior.")
}
}
func (t *guiWidget) Dump(b bool) {
if !b {
@ -75,46 +64,3 @@ func (t *guiWidget) Dump(b bool) {
log.Log(NOW, "uiCheckbox =", t.uiCheckbox)
}
}
/*
func GetDebugToolkit () bool {
return debugToolkit
}
*/
func (n *node) dumpWidget(b bool) {
var info, d string
if n == nil {
log.Log(ERROR, "dumpWidget() node == nil")
return
}
info = n.WidgetType.String()
d = string(n.WidgetId) + " " + info + " " + n.progname
var tabs string
for i := 0; i < listChildrenDepth; i++ {
tabs = tabs + defaultPadding
}
log.Log(NOW, tabs+d)
}
var defaultPadding string = " "
var listChildrenDepth int = 0
func (n *node) listChildren(dump bool) {
if n == nil {
return
}
n.dumpWidget(dump)
if len(n.children) == 0 {
return
}
for _, child := range n.children {
listChildrenDepth += 1
child.listChildren(dump)
listChildrenDepth -= 1
}
}

View File

@ -1,54 +0,0 @@
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 (
"go.wit.com/log"
"go.wit.com/widget"
)
// delete the child widget from the parent
// p = parent, c = child
func (n *node) destroy() {
pId := n.parent.WidgetId
cId := n.WidgetId
log.Log(NOW, "delete()", pId, cId)
pt := n.parent.tk
ct := n.tk
if ct == nil {
log.Log(NOW, "delete FAILED (ct = mapToolkit[c] == nil) for c", pId, cId)
// this pukes out a whole universe of shit
// listMap()
return
}
switch n.WidgetType {
case widget.Button:
log.Log(NOW, "Should delete Button here:", n.progname)
log.Log(NOW, "Parent:")
pt.Dump(true)
log.Log(NOW, "Child:")
ct.Dump(true)
if pt.uiBox == nil {
log.Log(NOW, "Don't know how to destroy this")
} else {
log.Log(NOW, "Fuck it, destroy the whole box", n.parent.progname)
// 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 widget.Window:
log.Log(NOW, "Should delete Window here:", n.progname)
default:
log.Log(NOW, "Fuckit, let's destroy a button")
if ct.uiButton != nil {
pt.uiBox.Delete(4)
ct.uiButton.Destroy()
}
}
}

View File

@ -27,29 +27,27 @@ func newDropdown(p, n *tree.Node) {
i := spin.Selected()
if newt.val == nil {
log.Log(ERROR, "make map didn't work")
n.SetValue("map did not work. ui.Combobox error")
n.State.CurrentS = "map did not work. ui.Combobox error"
} else {
n.SetValue(newt.val[i])
n.State.CurrentS = newt.val[i]
}
me.myTree.DoUserEvent(n)
me.myTree.SendUserEvent(n)
})
n.TK = newt
place(p, n)
log.Warn("add dropdown entries on create:", n.State.Strings)
log.Warn("add dropdown entries on create:", n.State.Strings)
log.Warn("add dropdown entries on create:", n.State.Strings)
log.Log(ANDLABS, "add dropdown entries on create:", n.State.Strings)
if n.State.Strings == nil {
return
}
// add the initial dropdown entries
for i, s := range n.State.Strings {
log.Warn("add dropdown: add entries on create", n.GetProgName(), i, s)
log.Log(ANDLABS, "add dropdown: add entries on create", n.GetProgName(), i, s)
addDropdownName(n, s)
}
cur := n.String()
log.Warn("add dropdown: set default value on create", n.GetProgName(), cur)
log.Log(ANDLABS, "add dropdown: set default value on create", n.GetProgName(), cur)
setDropdownName(n, cur)
}
@ -95,12 +93,12 @@ func setDropdownName(n *tree.Node, s string) bool {
for i, tmp := range tk.val {
if s == tmp {
n.SetValue(s)
n.State.CurrentS = s
setDropdownInt(n, i)
log.Warn("SetDropdownInt() worked", tmp, i)
log.Log(ANDLABS, "SetDropdownInt() worked", tmp, i)
return true
}
}
log.Warn("SetDropdownName() failed", s)
log.Log(WARN, "SetDropdownName() failed", s, n.WidgetId, n.GetProgName())
return false
}

View File

@ -11,12 +11,10 @@ import (
var NOW *log.LogFlag
var INFO *log.LogFlag
var SPEW *log.LogFlag
var WARN *log.LogFlag
var ERROR *log.LogFlag
var CHANGE *log.LogFlag
var TOOLKIT *log.LogFlag
var ANDLABS *log.LogFlag
func init() {
full := "go.wit.com/toolkits/andlabs"
@ -26,9 +24,9 @@ func init() {
INFO = log.NewFlag("INFO", false, full, short, "normal debugging stuff")
WARN = log.NewFlag("WARN", true, full, short, "bad things")
SPEW = log.NewFlag("SPEW", false, full, short, "spew stuff")
ERROR = log.NewFlag("ERROR", false, full, short, "toolkit errors")
CHANGE = log.NewFlag("ERROR", false, full, short, "show when the user does things")
TOOLKIT = log.NewFlag("ERROR", false, full, short, "andlabs specific stuff")
full = "go.wit.com/gui"
short = "andlabs"
ERROR = log.NewFlag("ERROR", false, full, short, "andlab toolkit errors")
ANDLABS = log.NewFlag("ANDLABS", false, full, short, "andlabs specific stuff")
}

12
go.mod
View File

@ -1,12 +0,0 @@
module go.wit.com/toolkits/andlabs
go 1.21.4
require (
go.wit.com/dev/andlabs/ui v0.0.1
go.wit.com/log v0.5.5
go.wit.com/toolkits/tree v0.0.3
go.wit.com/widget v1.1.5
)
require go.wit.com/dev/davecgh/spew v1.1.4 // indirect

10
go.sum
View File

@ -1,10 +0,0 @@
go.wit.com/dev/andlabs/ui v0.0.1 h1:SowOybLBu/qUOqp905EZikz5/iPa3GpmnCAPzNOYajM=
go.wit.com/dev/andlabs/ui v0.0.1/go.mod h1:mlKEEe05ZJURzjh1LtjzdGMHVbJm9a7BUaVpA9cHxsM=
go.wit.com/dev/davecgh/spew v1.1.4 h1:C9hj/rjlUpdK+E6aroyLjCbS5MFcyNUOuP1ICLWdNek=
go.wit.com/dev/davecgh/spew v1.1.4/go.mod h1:sihvWmnQ/09FWplnEmozt90CCVqBtGuPXM811tgfhFA=
go.wit.com/log v0.5.5 h1:bK3b94uVKgev4jB5wg06FnvCFBEapQICTSH2YW+CWr4=
go.wit.com/log v0.5.5/go.mod h1:BaJBfHFqcJSJLXGQ9RHi3XVhPgsStxSMZRlaRxW4kAo=
go.wit.com/toolkits/tree v0.0.3 h1:bhPCKBEuZ3uxUC5saU5AF3uotvTVyt6NMgeG0BDg7CI=
go.wit.com/toolkits/tree v0.0.3/go.mod h1:n4F2seonm1aYMml+YGOpCqWo0bkFwT/RH834J6f5/iE=
go.wit.com/widget v1.1.5 h1:jx5hJ2WLZJnCcvMuaLHegzpNlzwo+0kOkzsRkzRiB30=
go.wit.com/widget v1.1.5/go.mod h1:I8tnD3x3ECbB/CRNnLCdC+uoyk7rK0AEkzK1bQYSqoQ=

View File

@ -1,5 +1,6 @@
package main
/*
import (
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
@ -18,6 +19,7 @@ func (p *node) newImage(n *node) {
n.tk = newt
// p.place(n)
}
*/
/*
if (a.Name == "image") {

175
init.go Normal file
View File

@ -0,0 +1,175 @@
// plugin
package main
import (
"runtime/debug"
"sync"
"go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
// the _ means we only need this for the init()
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
// sent via -ldflags
var VERSION string
var BUILDTIME string
var PLUGIN string = "andlabs"
var uiMainUndef bool = true
var uiMain sync.Once
var muAction sync.Mutex
/*
func newaction(n *tree.Node, atype widget.ActionType) {
ui.QueueMain(func() {
newAction(n, atype)
})
}
*/
func queueAdd(n *tree.Node) {
ui.QueueMain(func() {
newAdd(n)
})
}
func enableWidget(n *tree.Node) {
ui.QueueMain(func() {
realEnable(n, true)
})
}
func disableWidget(n *tree.Node) {
ui.QueueMain(func() {
realEnable(n, false)
})
}
func setTitle(n *tree.Node, s string) {
ui.QueueMain(func() {
SetText(n, s)
})
}
func setLabel(n *tree.Node, s string) {
ui.QueueMain(func() {
realSetText(n, s)
})
}
func setText(n *tree.Node, s string) {
ui.QueueMain(func() {
realSetText(n, s)
})
}
func addText(n *tree.Node, s string) {
ui.QueueMain(func() {
realAddText(n, s)
})
}
func setChecked(n *tree.Node, b bool) {
ui.QueueMain(func() {
realSetChecked(n, b)
})
}
func toolkitClose() {
ui.QueueMain(func() {
ui.Quit()
})
}
/*
func queueMain(currentA widget.Action) {
// this never happends
defer func() {
if r := recover(); r != nil {
log.Log("YAHOOOO Recovered in queueMain() application:", r)
log.Println("Recovered from panic:", r)
log.Println("Stack trace:")
debug.PrintStack()
me.myTree.SendToolkitPanic()
}
}()
// andlabs puts this inside the gofunction over there
// probably this should be changed around here
// and only andlabs stuff should be sent there?
// it's easier to code it this way however
// also, if it dies here, it get's caught
// usually, this is where it dies
log.Log(ANDLABS, "about to send action into the andlabs ui.QueueMain()")
ui.QueueMain(func() {
processAction(&currentA)
})
}
*/
func guiMain() {
defer func() {
if r := recover(); r != nil {
log.Log(WARN, "YAHOOOO Recovered in guiMain application:", r)
log.Log(WARN, "Recovered from panic:", r)
log.Log(WARN, "Stack trace:")
debug.PrintStack()
me.myTree.SendToolkitPanic()
return
}
}()
ui.Main(func() {
// this is a bad hack for now.
// a better way would be to spawn ui.Main on the first actual window
// that is supposed to be displayed
placeholderUI()
me.myTree.InitOK()
// if nothing is working, run this instead to make
// sure you have something
// demoUI()
})
}
func Init() {
log.Log(WARN, "Init() TODO: move init() to here")
}
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func initPlugin() {
log.Log(INFO, "Init() START")
log.Log(INFO, "Init()")
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
// log.Log(INFO, "init() Setting defaultBehavior = true")
// setDefaultBehavior(true)
me.myTree = initTree()
// me.ok = true // this tells init() it's okay to work with gocui
/*
me.myTree = tree.New()
me.myTree.PluginName = "andlabs"
// me.myTree.ActionFromChannel = queueMain
me.myTree.NodeAction = queueAction
me.myTree.Add = queueAdd
me.myTree.SetTitle = queueSetTitle
me.myTree.SetLabel = queueSetLabel
me.myTree.SetText = queueSetText
me.myTree.AddText = queueAddText
me.myTree.SetChecked = queueSetChecked
me.myTree.ToolkitClose = queueToolkitClose
*/
// TODO: this is messed up. run ui.Main() from the first add? Initialize it with an empty thing first?
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
// actually, this probably breaks the macos build
go guiMain()
}
func main() {
}

86
main.go
View File

@ -1,86 +0,0 @@
package main
import (
"runtime/debug"
"sync"
"go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
"go.wit.com/dev/andlabs/ui"
// the _ means we only need this for the init()
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
var uiMainUndef bool = true
var uiMain sync.Once
var muAction sync.Mutex
func queueMain(currentA widget.Action) {
/*
// this never happends
defer func() {
if r := recover(); r != nil {
log.Warn("YAHOOOO Recovered in queueMain() application:", r)
log.Println("Recovered from panic:", r)
log.Println("Stack trace:")
debug.PrintStack()
me.myTree.DoToolkitPanic()
}
}()
*/
// andlabs puts this inside the gofunction over there
// probably this should be changed around here
// and only andlabs stuff should be sent there?
// it's easier to code it this way however
// also, if it dies here, it get's caught
// usually, this is where it dies
ui.QueueMain(func() {
processAction(&currentA)
})
}
func guiMain() {
defer func() {
if r := recover(); r != nil {
log.Warn("YAHOOOO Recovered in guiMain application:", r)
log.Println("Recovered from panic:", r)
log.Println("Stack trace:")
debug.PrintStack()
me.myTree.DoToolkitPanic()
return
}
}()
ui.Main(func() {
// this is a bad hack for now.
// a better way would be to spawn ui.Main on the first actual window
// that is supposed to be displayed
placeholderUI()
})
}
func Init() {
log.Warn("Init() TODO: move init() to here")
}
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func init() {
log.Log(INFO, "Init() START")
log.Log(INFO, "Init()")
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
// log.Log(INFO, "init() Setting defaultBehavior = true")
setDefaultBehavior(true)
me.myTree = tree.New()
me.myTree.PluginName = "andlabs"
me.myTree.ActionFromChannel = queueMain
// TODO: this is messed up. run ui.Main() from the first add? Initialize it with an empty thing first?
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
// actually, this probably breaks the macos build
go guiMain()
}
func main() {
}

View File

@ -2,6 +2,9 @@ package main
import (
// "os"
"os"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
@ -37,48 +40,60 @@ import (
// -----------------------------
func place(p *tree.Node, n *tree.Node) bool {
log.Warn("SPEEDY newplace() 1 START", n.WidgetId, n.GetProgName(), n.GetLabel(), n.String())
log.Warn("SPEEDY newplace() n.State.Strings =", n.State.Strings)
log.Log(INFO, "place() 1 START", n.WidgetType, n.GetProgName(), n.GetLabel())
if !ready(n) {
log.Warn("place() 1 START not ready()")
if p == nil {
log.Log(WARN, "place() parent == nil")
os.Exit(-1)
return false
}
if n == nil {
log.Log(WARN, "place() node == nil")
os.Exit(-1)
return false
}
if !ready(n) {
if n.WidgetType == widget.Window {
// TODO: figure out window in window placement
return true
}
log.Log(ERROR, "place() 1 START not ready()", n.WidgetType, n.GetProgName(), n.GetLabel())
return false
}
log.Log(INFO, "place() 1 START ready()")
var tk, ptk *guiWidget
tk = n.TK.(*guiWidget)
ptk = p.TK.(*guiWidget)
log.Warn("SPEEDY newplace() 2 START", n.WidgetId, n.GetProgName(), n.GetLabel())
if ptk == nil {
log.Log(ERROR, "ptk == nil", p.GetProgName(), p.ParentId, p.WidgetType, ptk)
log.Log(ERROR, "n = ", n.GetProgName(), n.ParentId, n.WidgetType, tk)
log.Warn("SPEEDY ptk == nil", n.WidgetId, n.GetProgName())
log.Log(ERROR, "SPEEDY ptk == nil", n.WidgetId, n.GetProgName())
log.Sleep(1)
panic("ptk == nil")
}
// p.DumpWidget("parent: ")
// n.DumpWidget("child: ")
log.Log(INFO, "place() switch", p.WidgetType)
log.Warn("SPEEDY newplace() before switch", n.WidgetId, n.GetProgName())
// log.Log(WARN, "place() switch", p.WidgetType, n.WidgetId, n.GetProgName())
switch p.WidgetType {
case widget.Grid:
tk.gridX = n.State.GridOffset.X - 1
tk.gridY = n.State.GridOffset.Y - 1
log.Warn("place() on Grid at gridX,gridY", tk.gridX, tk.gridY)
// log.Log(WARN, "place() on Grid at gridX,gridY", tk.gridX, tk.gridY)
ptk.uiGrid.Append(tk.uiControl,
tk.gridX, tk.gridY, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
return true
case widget.Group:
if ptk.uiBox == nil {
log.Log(WARN, "place() andlabs hack group to use add a box", n.GetProgName(), n.WidgetType)
log.Log(ANDLABS, "place() andlabs hack group to use add a box", n.GetProgName(), n.WidgetType)
n.State.Direction = widget.Vertical
ptk.uiBox = rawBox(n)
ptk.uiGroup.SetChild(ptk.uiBox)
}
if n.WidgetType == widget.Textbox {
ptk.uiBox.Append(tk.uiControl, true)
} else {
ptk.uiBox.Append(tk.uiControl, stretchy)
ptk.uiBox.Append(tk.uiControl, n.State.Expand)
}
return true
case widget.Tab:
@ -91,30 +106,30 @@ func place(p *tree.Node, n *tree.Node) bool {
panic("tk.uiControl == nil")
}
log.Log(ERROR, "CHECK LOGIC ON THIS. APPENDING directly into a window without a tab")
// log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() node=", n.WidgetId, n.GetProgName(), n.Text, n.WidgetType)
// log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.GetProgName(), p.Text, p.WidgetType)
// panic("tk.uiControl == nil")
ptk.uiTab.Append(widget.GetString(n.State.Value), tk.uiControl)
ptk.uiTab.Append(n.State.Label, tk.uiControl)
ptk.boxC += 1
return true
case widget.Box:
log.Warn("SPEEDY Add Something to Box", n.WidgetId, n.GetProgName())
log.Log(INFO, "place() uiBox =", ptk.uiBox)
log.Log(INFO, "place() uiControl =", tk.uiControl)
if n.WidgetType == widget.Textbox {
ptk.uiBox.Append(tk.uiControl, true)
} else {
ptk.uiBox.Append(tk.uiControl, stretchy)
ptk.uiBox.Append(tk.uiControl, n.State.Expand)
}
ptk.boxC += 1
return true
case widget.Window:
log.Warn("SPEEDY Add Something to Window", n.WidgetId, n.GetProgName())
log.Log(INFO, "Adding Something to Window", n.WidgetId, n.GetProgName())
if n.WidgetType == widget.Window {
log.Log(INFO, "TODO: make window in a window a tab", n.WidgetId, n.GetProgName())
return true
}
ptk.uiWindow.SetChild(tk.uiControl)
return true
default:
log.Log(ERROR, "place() how? Parent =", p.WidgetId, p.WidgetType)
}
log.Warn("SPEEDY newplace() return", n.WidgetId, n.GetProgName())
log.Log(ERROR, "newplace() returned without doing anything", n.WidgetId, n.GetProgName())
return false
}

View File

@ -6,22 +6,20 @@ import (
"go.wit.com/widget"
)
// func (n *node) setText(a *widget.Action) {
func setText(n *tree.Node, a *widget.Action) {
name := widget.GetString(a.Value)
func realSetText(n *tree.Node, name string) {
// name := widget.GetString(a.Value)
var tk *guiWidget
tk = n.TK.(*guiWidget)
log.Log(CHANGE, "setText() START with text =", name)
log.Log(ANDLABS, "setText() START with text =", name, n.WidgetType)
if tk == nil {
log.Log(ERROR, "setText error. tk == nil", n.GetProgName(), n.WidgetId)
return
}
log.Log(CHANGE, "setText() Attempt on", n.WidgetType, "with", name)
switch n.WidgetType {
case widget.Window:
log.Warn("setText() Attempt to set the title to", name)
log.Log(ANDLABS, "setText() Attempt to set the title to", name)
tk.uiWindow.SetTitle(name)
case widget.Tab:
case widget.Group:
@ -29,6 +27,7 @@ func setText(n *tree.Node, a *widget.Action) {
case widget.Checkbox:
tk.uiCheckbox.SetText(name)
case widget.Textbox:
log.Log(ANDLABS, "setText() on Textbox START with text =", name)
if tk.uiEntry != nil {
tk.uiEntry.SetText(name)
}
@ -40,21 +39,21 @@ func setText(n *tree.Node, a *widget.Action) {
case widget.Button:
tk.uiButton.SetText(name)
case widget.Slider:
log.Log(ERROR, "setText() on slider unknown", a.ActionType, "on checkbox", n.GetProgName())
log.Log(ERROR, "setText() on slider unknown", n.GetProgName())
case widget.Spinner:
log.Log(ERROR, "setText() on spinner unknown", a.ActionType, "on checkbox", n.GetProgName())
log.Log(ERROR, "setText() on spinner unknown", n.GetProgName())
case widget.Dropdown:
var orig int
var i int = -1
var s string
orig = tk.uiCombobox.Selected()
log.Log(CHANGE, "try to set the Dropdown to", name, "from", orig)
log.Log(ANDLABS, "try to set the Dropdown to", name, "from", orig)
// try to find the string
for i, s = range tk.val {
log.Log(CHANGE, "i, s", i, s)
log.Log(ANDLABS, "i, s", i, s)
if name == s {
tk.uiCombobox.SetSelected(i)
log.Log(CHANGE, "setText() Dropdown worked.", name)
log.Log(ANDLABS, "setText() Dropdown worked.", name)
return
}
}
@ -70,7 +69,7 @@ func setText(n *tree.Node, a *widget.Action) {
case widget.Combobox:
tk.uiEditableCombobox.SetText(name)
default:
log.Log(ERROR, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
log.Log(ERROR, "plugin Send() Don't know how to setText on", n.WidgetType, "yet")
}
log.Log(CHANGE, "setText() END with name =")
log.Log(ANDLABS, "setText() END with name =")
}

View File

@ -22,8 +22,8 @@ func newSlider(p, n *tree.Node) {
newt.uiControl = s
s.OnChanged(func(spin *ui.Slider) {
n.SetValue(newt.uiSlider.Value())
me.myTree.DoUserEvent(n)
n.State.CurrentI = newt.uiSlider.Value()
me.myTree.SendUserEvent(n)
})
n.TK = newt

View File

@ -18,8 +18,8 @@ func newSpinner(p, n *tree.Node) {
newt.uiControl = s
s.OnChanged(func(s *ui.Spinbox) {
n.SetValue(newt.uiSpinbox.Value())
me.myTree.DoUserEvent(n)
n.State.CurrentI = newt.uiSpinbox.Value()
me.myTree.SendUserEvent(n)
})
n.TK = newt

View File

@ -1,15 +1,15 @@
package main
import (
"sync"
"go.wit.com/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
// var andlabs map[int]*andlabsT
// var callback func(int) bool
// var callback chan toolkit.Action
var initOnce sync.Once // run initPlugin() only once
// It's probably a terrible idea to call this 'me'
var me config

25
tab.go
View File

@ -2,7 +2,6 @@ package main
import (
"go.wit.com/log"
"go.wit.com/widget"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
@ -20,6 +19,7 @@ I work around this by always sending a Toolkit that is a tab
once there is one. If you send a Window here, it will replace
any existing tabs rather than adding a new one
*/
/*
func (p *node) newTab(n *node) {
var newt *guiWidget
@ -32,16 +32,16 @@ func (p *node) newTab(n *node) {
}
t := p.tk
log.Log(TOOLKIT, "newTab() START", n.WidgetId, n.ParentId)
log.Log(ANDLABS, "newTab() START", n.WidgetId, n.ParentId)
if t.uiTab == nil {
// this means you have to make a new tab
log.Log(TOOLKIT, "newTab() GOOD. This should be the first tab:", n.WidgetId, n.ParentId)
log.Log(ANDLABS, "newTab() GOOD. This should be the first tab:", n.WidgetId, n.ParentId)
newt = rawTab(t.uiWindow, widget.GetString(n.value))
t.uiTab = newt.uiTab
} else {
// this means you have to append a tab
log.Log(TOOLKIT, "newTab() GOOD. This should be an additional tab:", n.WidgetId, n.ParentId)
log.Log(ANDLABS, "newTab() GOOD. This should be an additional tab:", n.WidgetId, n.ParentId)
if n.WidgetType == widget.Tab {
// andlabs doesn't have multiple tab widgets so make a fake one?
// this makes a guiWidget internal structure with the parent values
@ -55,6 +55,7 @@ func (p *node) newTab(n *node) {
n.tk = newt
}
*/
// This sets _all_ the tabs to Margin = true
//
@ -62,18 +63,16 @@ func (p *node) newTab(n *node) {
func tabSetMargined(tab *ui.Tab, b bool) {
c := tab.NumPages()
for i := 0; i < c; i++ {
log.Log(TOOLKIT, "SetMargined", i, b)
log.Log(ANDLABS, "SetMargined", i, b)
tab.SetMargined(i, b)
}
}
func rawTab(w *ui.Window, name string) *guiWidget {
var newt guiWidget
log.Log(TOOLKIT, "rawTab() START", name)
log.Log(ANDLABS, "rawTab() START", name)
if w == nil {
log.Log(ERROR, "UiWindow == nil. I can't add a tab without a window")
log.Log(ERROR, "UiWindow == nil. I can't add a tab without a window")
log.Log(ERROR, "UiWindow == nil. I can't add a tab without a window")
// sleep(1)
return nil
@ -83,19 +82,20 @@ func rawTab(w *ui.Window, name string) *guiWidget {
w.SetChild(tab)
newt.uiTab = tab
newt.uiControl = tab
log.Log(TOOLKIT, "rawTab() END", name)
log.Log(ANDLABS, "rawTab() END", name)
return &newt
}
/*
func (t *guiWidget) appendTab(name string) *guiWidget {
var newT guiWidget
log.Log(TOOLKIT, "appendTab() ADD", name)
log.Log(ANDLABS, "appendTab() ADD", name)
if t.uiTab == nil {
log.Log(TOOLKIT, "UiWindow == nil. I can't add a widget without a place to put it")
log.Log(ANDLABS, "UiWindow == nil. I can't add a widget without a place to put it")
panic("should never have happened. wit/gui/toolkit has ui.Tab == nil")
}
log.Log(TOOLKIT, "appendTab() START name =", name)
log.Log(ANDLABS, "appendTab() START name =", name)
var hbox *ui.Box
if defaultBehavior {
@ -115,3 +115,4 @@ func (t *guiWidget) appendTab(name string) *guiWidget {
newT.uiBox = hbox
return &newT
}
*/

13
table.go Normal file
View File

@ -0,0 +1,13 @@
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
package main
import (
"go.wit.com/lib/protobuf/guipb"
"go.wit.com/log"
)
func showTable(t *guipb.Table) {
log.Info("should show table here")
}

View File

@ -17,19 +17,21 @@ func newTextbox(p, n *tree.Node) {
e := ui.NewEntry()
newt.uiEntry = e
newt.uiControl = e
newt.uiEntry.SetText(n.State.DefaultS)
e.OnChanged(func(spin *ui.Entry) {
n.SetValue(spin.Text())
me.myTree.DoUserEvent(n)
n.State.CurrentS = spin.Text()
me.myTree.SendUserEvent(n)
})
} else {
e := ui.NewNonWrappingMultilineEntry()
newt.uiMultilineEntry = e
newt.uiControl = e
newt.uiMultilineEntry.SetText(n.State.DefaultS)
e.OnChanged(func(spin *ui.MultilineEntry) {
n.SetValue(spin.Text())
me.myTree.DoUserEvent(n)
n.State.CurrentS = spin.Text()
me.myTree.SendUserEvent(n)
})
}
n.TK = newt

31
tree.go
View File

@ -1,31 +0,0 @@
package main
/*
This code should be common to all gui plugins
There are some helper functions that are probably going to be
the same everywhere. Mostly due to handling the binary tree structure
and the channel communication
For now, it's just a symlink to the 'master' version in
./toolkit/nocui/common.go
*/
import (
"go.wit.com/widget"
)
// Other goroutines must use this to access the GUI
//
// You can not acess / process the GUI thread directly from
// other goroutines. This is due to the nature of how
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
//
// this sets the channel to send user events back from the plugin
func Callback(guiCallback chan widget.Action) {
me.myTree.Callback(guiCallback)
}
func PluginChannel() chan widget.Action {
return me.myTree.PluginChannel()
}

79
treeInit.go Normal file
View File

@ -0,0 +1,79 @@
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
/*
DO NOT EDIT THIS FILE
this file is the same for every GUI toolkit plugin
when you are making a new GUI toolkit plugin for
a specific toolkit, you just need to define these
functions.
for example, in the "gocui" toolkit, the functions
below are what triggers the "gocui" GO package
to draw labels, buttons, windows, etc
If you are starting out trying to make a new GUI toolkit,
all you have to do is copy this file over. Then
work on making these functions. addWidget(), setText(), etc.
That's it!
*/
package main
/*
This is reference code for toolkit developers
This is how information is passed in GO back to the application
via the GO 'plugin' concept
TODO: switch this to protocol buffers
*/
import (
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
)
// Other goroutines must use this to access the GUI
//
// You can not acess / process the GUI thread directly from
// other goroutines. This is due to the nature of how
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
//
// this sets the channel to send user events back from the plugin
func Callback(guiCallback chan widget.Action) {
me.myTree.Callback(guiCallback)
}
func PluginChannel() chan widget.Action {
initOnce.Do(initPlugin)
return me.myTree.PluginChannel()
}
func FrozenChannel() chan widget.Action {
return me.myTree.FrozenChannel()
}
func initTree() *tree.TreeInfo {
t := tree.New()
t.PluginName = PLUGIN
t.Add = newAdd
t.SetTitle = setTitle
t.SetLabel = setLabel
t.SetText = setText
t.AddText = addText
t.Enable = enableWidget
t.Disable = disableWidget
t.Show = showWidget
t.Hide = hideWidget
t.SetChecked = setChecked
t.ToolkitClose = toolkitClose
t.ShowTable = showTable
return t
}

View File

@ -99,5 +99,5 @@ func demoUI() {
})
// this is messed up.
// mainWindow.Show()
mainWindow.Show()
}

View File

@ -3,10 +3,10 @@ package main
import (
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
"go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
"go.wit.com/toolkits/tree"
)
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
@ -21,31 +21,25 @@ func newWindow(p, n *tree.Node) {
var newt *guiWidget
newt = new(guiWidget)
// menubar bool is if the OS defined border on the window should be used
win := ui.NewWindow(n.GetProgName(), 640, 480, menubar)
win.SetBorderless(canvas)
win.SetMargined(margin)
// bool == false is if the OS defined border on the window should be used
win := ui.NewWindow(n.GetProgName(), 40, 40, n.State.Borderless)
win.SetBorderless(n.State.Borderless)
win.SetMargined(n.State.Pad)
win.OnClosing(func(*ui.Window) bool {
// show(n, false)
me.myTree.DoWindowCloseEvent(n)
newt.uiWindow = nil // delete the local reference to the window
me.myTree.SendWindowCloseEvent(n)
// n.DeleteNode()
return true
})
newt.uiWindow = win
newt.uiControl = win
n.TK = newt
if p.WidgetType == widget.Window {
log.Log(WARN, "newWindow() TODO: make this window a tab")
} else {
place(p, n)
}
win.Show()
return
}
func (n *node) SetWindowTitle(title string) {
log.Log(CHANGE, "toolkit NewWindow", widget.GetString(n.value), "title", title)
win := n.tk.uiWindow
if win == nil {
log.Log(ERROR, "Error: no window", n.WidgetId)
} else {
win.SetTitle(title)
log.Log(CHANGE, "Setting the window title", title)
}
}