196 lines
5.7 KiB
Go
196 lines
5.7 KiB
Go
package gui
|
|
|
|
/*
|
|
This is where the communication to the toolkit plugin happens.
|
|
|
|
We copy the current values from the widget node of the binary tree
|
|
and send an "action" to the toolkit over a channel.
|
|
|
|
TODO: use protobuf
|
|
*/
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"go.wit.com/log"
|
|
"go.wit.com/widget"
|
|
)
|
|
|
|
func (n *Node) SetVisable(b bool) {
|
|
n.visable = b
|
|
}
|
|
|
|
// returns true if the window is not visable to the user
|
|
// in which case events are not sent to the toolkit
|
|
// TODO: fix this so ParentVisable() works
|
|
func (n *Node) WindowVisable() bool {
|
|
if n == nil {
|
|
return false
|
|
}
|
|
if n.WidgetType == widget.Window {
|
|
return n.visable
|
|
}
|
|
if n.parent == nil {
|
|
return false
|
|
}
|
|
return n.parent.WindowVisable()
|
|
}
|
|
|
|
// returns true if the parent is not visable to the user
|
|
// in which case events are not sent to the toolkit
|
|
func (n *Node) ParentVisable() bool {
|
|
if n == nil {
|
|
return false
|
|
}
|
|
if n.parent == nil {
|
|
return false
|
|
}
|
|
return n.parent.visable
|
|
}
|
|
|
|
// copies the state of the Node into the action
|
|
// TODO: switch to protobuf here
|
|
func getNewAction(n *Node, atype widget.ActionType) *widget.Action {
|
|
var a widget.Action
|
|
a.ActionType = atype
|
|
|
|
// These should be "stable" at this point (2024/01/13)
|
|
a.WidgetId = n.id
|
|
|
|
// set state
|
|
a.State.ProgName = n.progname
|
|
a.State.Label = n.label
|
|
// a.State.Value = n.value
|
|
a.State.DefaultS = n.defaultS
|
|
a.State.CurrentS = n.currentS
|
|
a.State.NewString = n.newString
|
|
|
|
a.State.Checked = n.checked
|
|
a.State.Visable = n.visable
|
|
a.State.Hidden = n.hidden
|
|
// TODO: if visable == false here, return
|
|
a.State.Enable = n.enabled
|
|
a.State.Pad = n.pad
|
|
a.State.Expand = n.expand
|
|
a.State.Borderless = n.borderless
|
|
a.State.Direction = n.direction
|
|
|
|
for s, _ := range n.strings {
|
|
a.State.Strings = append(a.State.Strings, s)
|
|
}
|
|
a.State.Range.Low = n.X
|
|
a.State.Range.High = n.Y
|
|
|
|
a.ProgName = n.progname
|
|
// a.Value = n.value
|
|
a.Direction = n.direction
|
|
|
|
// These should be improved/deprecated based on the gui/widget docs
|
|
a.X = n.X
|
|
a.Y = n.Y
|
|
|
|
a.State.GridOffset.X = n.AtW
|
|
a.State.GridOffset.Y = n.AtH
|
|
|
|
a.State.AtW = n.AtW
|
|
a.State.AtH = n.AtH
|
|
|
|
if n.parent != nil {
|
|
a.ParentId = n.parent.id
|
|
}
|
|
a.WidgetType = n.WidgetType
|
|
|
|
return &a
|
|
}
|
|
|
|
// 2025/02/09 this will continue to suck until I switch it to protocol buffers
|
|
// 2024/01/11 finally moving to type any. simplify to just 'value'
|
|
// 2023/05/09 pretty clean
|
|
// 2023/04/06 Queue() is also being used and channels are being used.
|
|
func sendAction(n *Node, atype widget.ActionType) {
|
|
if n == nil {
|
|
log.Error(errors.New("Sending Action on n = nil"))
|
|
return
|
|
}
|
|
if atype == widget.Disable {
|
|
// log.Log(WARN, "START got DISABLE action ", n.id, n.WidgetType, n.GetProgName())
|
|
}
|
|
n.mu.Lock()
|
|
defer n.mu.Unlock()
|
|
// log.Log(PLUG, "SENDING ACTION STRINGS n.Strings", n.strings, n.id, n.WidgetType, n.GetProgName())
|
|
|
|
if n.changed {
|
|
n.changed = false
|
|
} else {
|
|
// probably shouldn't even send this to the toolkits
|
|
// TODO: can't implement this yet
|
|
}
|
|
|
|
// this checks to see if the window is show in the toolkit. If it is not,
|
|
// then don't send any events. Unless it is a window widget, then send events
|
|
if n.WidgetType != widget.Window {
|
|
if n.WindowVisable() {
|
|
// lots of output. make this verbose?
|
|
log.Log(INFO, "Sending action to widget. Window is visable", n.id, n.WidgetType, n.GetProgName())
|
|
} else {
|
|
// lots of output. make this verbose?
|
|
log.Log(INFO, "Not sending action to widget. Window is not visable", n.id, n.WidgetType, n.GetProgName())
|
|
return
|
|
}
|
|
// set if the widget is visable based on the parent
|
|
// this has nothing to do with show() and hide()
|
|
if n.ParentVisable() {
|
|
log.Log(INFO, "Parent is visable n =", n.id, n.WidgetType, n.GetProgName())
|
|
if n.visable != true {
|
|
log.Log(INFO, "switching visable=true", n.id, n.WidgetType, n.GetProgName())
|
|
}
|
|
n.visable = true
|
|
} else {
|
|
log.Log(INFO, "Parent is not visable n =", n.id, n.WidgetType, n.GetProgName())
|
|
log.Log(INFO, "not sending action to toolkits")
|
|
if n.visable != false {
|
|
log.Log(INFO, "switching visable=false", n.id, n.WidgetType, n.GetProgName())
|
|
}
|
|
n.visable = false
|
|
return
|
|
}
|
|
}
|
|
if atype == widget.Disable {
|
|
// log.Log(WARN, "END got DISABLE action ", n.id, n.WidgetType, n.GetProgName())
|
|
}
|
|
|
|
// make a new action and populate the current node state
|
|
a := getNewAction(n, atype)
|
|
sendActionToPlugin(a)
|
|
}
|
|
|
|
// sends the action/event to each toolkit via a golang plugin channel
|
|
func sendActionToPlugin(a *widget.Action) {
|
|
for _, aplug := range allPlugins {
|
|
log.Log(CHANGE, "send to toolkit =", aplug.name, "Action type=", a.ActionType, a.WidgetId)
|
|
if aplug.dead {
|
|
// log.Log(WARN, "skiping dead toolkit =", aplug.name, "Action type=", a.ActionType, a.WidgetId)
|
|
return
|
|
}
|
|
if aplug.pluginChan == nil {
|
|
log.Log(PLUG, "Action() retrieving the aplug.PluginChannel()", aplug.name)
|
|
aplug.pluginChan = aplug.PluginChannel()
|
|
log.Log(PLUG, "Action() retrieved", aplug.pluginChan)
|
|
}
|
|
log.Log(INFO, "Action() SEND to pluginChan", aplug.name, a.ActionType, a.WidgetType, a.WidgetId, a.ProgName)
|
|
aplug.pluginChan <- *a
|
|
// added during debugging. might be a good idea in general for a tactile experience
|
|
// start playing with this
|
|
if a.ActionType == widget.Hide {
|
|
// log.Sleep(.001) // this delay makes it so SetText() works on initial widget creation
|
|
} else {
|
|
// 2024/12/16 still leaving this as I'm not sure binary tree access is actually
|
|
// safe (thread safe, correct locking, etc). I think it is. Things seem stable
|
|
// sync.Mutex() locks don't appear to work somehow in a way I don't understand
|
|
// it's probably due to []string use. use map[] instead
|
|
log.Sleep(.000001) // this delay makes it so SetText() works on initial widget creation
|
|
// log.Sleep(.002) // this delay makes it so SetText() works on initial widget creation
|
|
}
|
|
}
|
|
}
|