Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
|
cc75f34f6f | |
|
f65d80862e | |
|
dcd32c255c | |
|
f223a21545 | |
|
05567cb88c | |
|
a605119c2c | |
|
0d60e6bdcb | |
|
52bae09613 | |
|
789f5c109f | |
|
b19c7de609 | |
|
b8e3b43114 | |
|
ac4541b31f | |
|
491f80c961 | |
|
43b2217717 |
|
@ -2,4 +2,5 @@
|
|||
go.mod
|
||||
go.sum
|
||||
fyne
|
||||
*.so
|
||||
nocui
|
||||
|
|
33
Makefile
33
Makefile
|
@ -1,13 +1,35 @@
|
|||
all: plugin
|
||||
ldd ../fyne.so
|
||||
VERSION = $(shell git describe --tags)
|
||||
BUILDTIME = $(shell date +%Y.%m.%d)
|
||||
|
||||
all: clean goimports plugin
|
||||
#ldd fyne.so
|
||||
|
||||
deps:
|
||||
sudo apt install libxxf86vm-dev libxxf86vm1
|
||||
|
||||
plugin:
|
||||
go build -v -x -buildmode=plugin -o ../fyne.so
|
||||
# LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/ GO111MODULE=off go build -v -x -buildmode=plugin -o fyne.so
|
||||
GO111MODULE=off go build -v -x -buildmode=plugin -o fyne.so
|
||||
|
||||
install: clean
|
||||
go build -v -buildmode=plugin -o ~/go/lib/fyne-${VERSION}.so \
|
||||
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
||||
cd ~/go/lib && ln -f -s fyne-${VERSION}.so fyne.so
|
||||
|
||||
clean:
|
||||
rm -f fyne fyne.so
|
||||
|
||||
binary:
|
||||
go build -v -x
|
||||
|
||||
non-plugin:
|
||||
go build -v -x
|
||||
./fyne
|
||||
|
||||
GO111-non-plugin:
|
||||
GO111MODULE=off go build -v -x
|
||||
./fyne
|
||||
|
||||
check-git-clean:
|
||||
@git diff-index --quiet HEAD -- || (echo "Git repository is dirty, please commit your changes first"; exit 1)
|
||||
|
||||
|
@ -19,8 +41,3 @@ pkgsite:
|
|||
|
||||
goimports:
|
||||
goimports -w *.go
|
||||
|
||||
redomod:
|
||||
rm -f go.*
|
||||
GO111MODULE= go mod init
|
||||
GO111MODULE= go mod tidy
|
||||
|
|
15
README.md
15
README.md
|
@ -1,5 +1,18 @@
|
|||
# nogui
|
||||
# fyne
|
||||
|
||||
Package gui implements a abstraction layer for Go visual elements.
|
||||
|
||||
This is a sample plugin. It's a skeleton intended to be used when making a new toolkit plugin.
|
||||
|
||||
fyne appears to require:
|
||||
runtime.LockOSThread() // Ensure main stays on one OS thread
|
||||
a := app.New()
|
||||
w := a.NewWindow("Fyne Plugin Fix")
|
||||
w.ShowAndRun()
|
||||
|
||||
error:
|
||||
gui doing TestDraw() Forge: (this kinda works sometimes)
|
||||
panic: Run() or ShowAndRun() must be called from main goroutine
|
||||
|
||||
so for fyne to work, there must be a protocol buffer GO GUI plugin first that
|
||||
can spawn and talk to fyne
|
||||
|
|
71
action.go
71
action.go
|
@ -7,12 +7,15 @@ package main
|
|||
*/
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"go.wit.com/lib/protobuf/guipb"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func Add(n *tree.Node) {
|
||||
func newAdd(n *tree.Node) {
|
||||
log.Log(INFO, "Add() END =", n.WidgetType, n.String())
|
||||
if n == nil {
|
||||
log.Warn("Tree Error: Add() sent n == nil")
|
||||
|
@ -58,7 +61,7 @@ func newaction(n *tree.Node, atype widget.ActionType) {
|
|||
// w.disableColor()
|
||||
case widget.Delete:
|
||||
log.Info("newaction() DeleteNode()")
|
||||
n.DeleteNode()
|
||||
// n.DeleteNode()
|
||||
case widget.ToolkitClose:
|
||||
log.Info("newaction() toolkit closed. are the channels cleand up?")
|
||||
return
|
||||
|
@ -68,15 +71,15 @@ func newaction(n *tree.Node, atype widget.ActionType) {
|
|||
log.Log(INFO, "newaction() END", atype, n.String())
|
||||
}
|
||||
|
||||
func SetTitle(n *tree.Node, s string) {
|
||||
SetText(n, s)
|
||||
func setTitle(n *tree.Node, s string) {
|
||||
setText(n, s)
|
||||
}
|
||||
|
||||
func SetLabel(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) {
|
||||
func setText(n *tree.Node, s string) {
|
||||
if n == nil {
|
||||
log.Warn("Tree Error: Add() sent n == nil")
|
||||
return
|
||||
|
@ -90,7 +93,7 @@ func SetText(n *tree.Node, s string) {
|
|||
log.Info("SetText()", n.WidgetType, n.String())
|
||||
}
|
||||
|
||||
func AddText(n *tree.Node, s string) {
|
||||
func addText(n *tree.Node, s string) {
|
||||
if n == nil {
|
||||
log.Warn("Tree Error: Add() sent n == nil")
|
||||
return
|
||||
|
@ -103,3 +106,55 @@ func AddText(n *tree.Node, s string) {
|
|||
// w := n.TK.(*guiWidget)
|
||||
// w.AddText(s)
|
||||
}
|
||||
|
||||
func setChecked(n *tree.Node, b bool) {
|
||||
log.Info("do enable() here")
|
||||
}
|
||||
|
||||
func toolkitClose() {
|
||||
log.Info("do enable() here")
|
||||
}
|
||||
|
||||
func showTable(t *guipb.Table) {
|
||||
log.Info("gocui: should show table here")
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
log.Info("gocui: table.Title", t.Title)
|
||||
}
|
||||
|
||||
func enableWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
tk.Enable()
|
||||
}
|
||||
|
||||
func disableWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
tk.Disable()
|
||||
}
|
||||
|
||||
func showWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
tk.Show()
|
||||
}
|
||||
|
||||
func hideWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
if n.WidgetType == widget.Window {
|
||||
// tk.windowFrame.Hide()
|
||||
// tk.hideWidgets()
|
||||
}
|
||||
tk.Hide()
|
||||
tk.deleteWidget()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) deleteWidget() {
|
||||
log.Info("gocui deleteWidget() looking for child to delete:", tk.cuiName)
|
||||
p := tk.parent
|
||||
for i, child := range p.children {
|
||||
if tk == child {
|
||||
log.Info("deleteWidget() found parent with child to delete:", i, child.cuiName)
|
||||
p.children = slices.Delete(p.children, i, i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
args.go
4
args.go
|
@ -17,8 +17,8 @@ var WARN *log.LogFlag
|
|||
var ERROR *log.LogFlag
|
||||
|
||||
func init() {
|
||||
full := "toolkit/nocui"
|
||||
short := "nocui"
|
||||
full := "toolkit/fyne"
|
||||
short := "fyne"
|
||||
|
||||
NOW = log.NewFlag("NOW", true, full, short, "temp debugging stuff")
|
||||
INFO = log.NewFlag("INFO", true, full, short, "normal debugging stuff")
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
package main // import "go.wit.com/toolkits/fyne"
|
||||
// the above line overrides the default 'go mod init' to use whatever is here
|
||||
// `go-clean `go-get github.com/go-gl/glfw`
|
|
@ -9,6 +9,7 @@ import (
|
|||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
var a fyne.App
|
||||
|
@ -16,6 +17,7 @@ var w fyne.Window
|
|||
var w2 fyne.Window
|
||||
|
||||
func fynetest() {
|
||||
log.Info("FYNE TEST START")
|
||||
a = app.New()
|
||||
w = a.NewWindow("Hello")
|
||||
|
||||
|
@ -28,6 +30,7 @@ func fynetest() {
|
|||
}),
|
||||
))
|
||||
|
||||
log.Info("FYNE TEST SHOW")
|
||||
w.Show()
|
||||
|
||||
// bobWindow()
|
||||
|
|
59
main.go
59
main.go
|
@ -8,31 +8,36 @@ package main
|
|||
*/
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"fyne.io/fyne/v2/app"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var PLUGIN string = "fyne"
|
||||
|
||||
func blah() {
|
||||
fynetest()
|
||||
a.Run()
|
||||
}
|
||||
|
||||
func initPlugin() {
|
||||
log.Log(INFO, "Init()")
|
||||
|
||||
me.myTree = tree.New()
|
||||
me.myTree.PluginName = "nocui"
|
||||
// me.myTree.ActionFromChannel = doAction
|
||||
|
||||
me.myTree.NodeAction = newaction
|
||||
me.myTree.Add = Add
|
||||
me.myTree.SetTitle = SetTitle
|
||||
me.myTree.SetLabel = SetLabel
|
||||
me.myTree.SetText = SetText
|
||||
me.myTree.AddText = AddText
|
||||
me.myTree = initTree()
|
||||
|
||||
me.exit = false
|
||||
|
||||
log.Log(INFO, "Init() END")
|
||||
|
||||
showOptions()
|
||||
|
||||
go simpleStdin()
|
||||
log.Log(INFO, "Init() FYNE END")
|
||||
// blah()
|
||||
|
||||
me.myTree.InitOK()
|
||||
}
|
||||
|
||||
func init() {
|
||||
// fynetest()
|
||||
// a.Run()
|
||||
}
|
||||
|
||||
// this must be defined for plugin's, but is never run
|
||||
|
@ -41,3 +46,25 @@ func main() {
|
|||
fynetest()
|
||||
a.Run()
|
||||
}
|
||||
|
||||
// this is called at the very initial connection
|
||||
// between the app and this gocui plugin
|
||||
// this is a good place to initialize gocui's default behavior
|
||||
func toolkitInit() {
|
||||
log.Log(INFO, "TOOLKIT Init()")
|
||||
|
||||
me.exit = false
|
||||
showOptions()
|
||||
log.Log(INFO, "TOOLKIT Init() END")
|
||||
|
||||
fynetest()
|
||||
go a.Run()
|
||||
}
|
||||
|
||||
func testmain() {
|
||||
runtime.LockOSThread() // Ensure main stays on one OS thread
|
||||
a := app.New()
|
||||
w := a.NewWindow("Fyne Plugin Fix")
|
||||
w.ShowAndRun()
|
||||
// use w.QueueUpdate() to talk to fyne (?)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
// 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/widget"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) WidgetType() widget.WidgetType {
|
||||
if tk.node == nil {
|
||||
return widget.Label
|
||||
}
|
||||
return tk.node.WidgetType
|
||||
}
|
||||
|
||||
func (tk *guiWidget) WidgetId() int {
|
||||
return tk.node.WidgetId
|
||||
}
|
||||
|
||||
func (tk *guiWidget) GetLabel() string {
|
||||
return tk.node.GetLabel()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) IsEnabled() bool {
|
||||
return tk.node.IsEnabled()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Checked() bool {
|
||||
return tk.node.State.Checked
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Hidden() bool {
|
||||
if tk.node == nil {
|
||||
return false
|
||||
}
|
||||
if tk.parent == nil {
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
if tk.parent.WidgetId() == 0 {
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
if tk.parent.Hidden() {
|
||||
return true
|
||||
}
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Direction() widget.Orientation {
|
||||
return tk.node.State.Direction
|
||||
}
|
||||
|
||||
func (tk *guiWidget) GridW() int {
|
||||
return tk.node.State.AtW
|
||||
}
|
||||
|
||||
func (tk *guiWidget) GridH() int {
|
||||
return tk.node.State.AtH
|
||||
}
|
||||
|
||||
func (tk *guiWidget) SetChecked(b bool) {
|
||||
tk.node.State.Checked = b
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) Show() {
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Hide() {
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Disable() {
|
||||
if tk == nil {
|
||||
log.Info("widget is nil")
|
||||
return
|
||||
}
|
||||
|
||||
switch tk.WidgetType() {
|
||||
case widget.Box:
|
||||
return
|
||||
case widget.Button:
|
||||
return
|
||||
default:
|
||||
log.Log(NOW, "fixme")
|
||||
}
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Enable() {
|
||||
if tk == nil {
|
||||
log.Info("widget is nil")
|
||||
return
|
||||
}
|
||||
|
||||
switch tk.WidgetType() {
|
||||
case widget.Box:
|
||||
// hideDisable()
|
||||
return
|
||||
case widget.Button:
|
||||
// tk.restoreEnableColor()
|
||||
return
|
||||
default:
|
||||
log.Log(NOW, "fixme")
|
||||
}
|
||||
}
|
2
stdin.go
2
stdin.go
|
@ -33,7 +33,7 @@ func showOptions() {
|
|||
func simpleStdin() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("nocui YAHOOOO Recovered in simpleStdin()", r)
|
||||
log.Warn("fyne YAHOOOO Recovered in simpleStdin()", r)
|
||||
log.Println("Recovered from panic:", r)
|
||||
log.Println("Stack trace:")
|
||||
debug.PrintStack()
|
||||
|
|
10
structs.go
10
structs.go
|
@ -1,11 +1,17 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
// stores the raw toolkit internals
|
||||
type guiWidget struct {
|
||||
parent *guiWidget
|
||||
children []*guiWidget
|
||||
node *tree.Node // the pointer back to the tree
|
||||
cuiName string
|
||||
Width int
|
||||
Height int
|
||||
|
||||
|
@ -13,8 +19,8 @@ type guiWidget struct {
|
|||
val map[string]int
|
||||
}
|
||||
|
||||
// It's probably a terrible idea to call this 'me'
|
||||
var me config
|
||||
var initOnce sync.Once // run initPlugin() only once
|
||||
var me config // It's probably a terrible idea to call this 'me'
|
||||
|
||||
type config struct {
|
||||
treeRoot *tree.Node // the base of the binary tree. it should have id == 0
|
||||
|
|
24
tree.go
24
tree.go
|
@ -1,24 +0,0 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
This is reference code for toolkit developers
|
||||
*/
|
||||
|
||||
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()
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// 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 (
|
||||
"time"
|
||||
|
||||
log "go.wit.com/log"
|
||||
"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)
|
||||
for {
|
||||
if me.myTree != nil {
|
||||
break
|
||||
}
|
||||
log.Info("me.myTree == nil")
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
}
|
||||
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.ToolkitInit = toolkitInit
|
||||
t.ToolkitClose = toolkitClose
|
||||
t.ShowTable = showTable
|
||||
|
||||
return t
|
||||
}
|
Loading…
Reference in New Issue