// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 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) "github.com/awesome-gocui/gocui" "go.wit.com/log" "go.wit.com/toolkits/tree" "go.wit.com/widget" ) func newAdd(n *tree.Node) { if n == nil { log.Warn("Tree Error: Add() sent n == nil") return } if n.TK != nil { log.Warn("Tree Add() sent a widget we aleady seem to have") // this is done to protect the plugin being 'refreshed' with the // widget binary tree. TODO: find a way to keep them in sync return } n.TK = initWidget(n) if n.WidgetType == widget.Root { me.treeRoot = n } addWidget(n) /* TODO: removed while refactoring tree if w.enable { // don't change the color } else { w = n.TK.(*guiWidget) } */ w := n.TK.(*guiWidget) w.Show() } // for gocui as a GUI plugin, SetTitle & SetLabel are identical to SetText func newSetTitle(n *tree.Node, s string) { newSetText(n, s) } func newSetLabel(n *tree.Node, s string) { newSetText(n, s) } // newSetText() and newAddText() are simple. They take the event sent // to the GO plugin from the application and lookup the plugin structure // then pass that event to gocui. This is the transfer point func newSetText(n *tree.Node, s string) { if n == nil { log.Warn("Tree Error: Add() sent n == nil") return } if n.TK == nil { log.Warn("Tree sent an action on a widget we didn't seem to have.") return } w := n.TK.(*guiWidget) w.SetText(s) } func newAddText(n *tree.Node, s string) { if n == nil { log.Warn("Tree Error: Add() sent n == nil") return } if n.TK == nil { log.Warn("Tree sent an action on a widget we didn't seem to have.") return } w := n.TK.(*guiWidget) w.AddText(s) } func newaction(n *tree.Node, atype widget.ActionType) { log.Log(INFO, "newaction() START", atype) if !me.ok { log.Log(INFO, "newaction() START NOT OKAY", atype) log.Log(INFO, "newaction() START NOT OKAY", atype) log.Log(INFO, "newaction() START NOT OKAY", atype) waitOK() } if n == nil { log.Warn("Tree Error: Add() sent n == nil") return } if n.TK == nil { log.Warn("Tree sent an action on a widget we didn't seem to have.") // do this init here again? Probably something // went wrong and we should reset the our while gocui.View tree n.TK = initWidget(n) } w := n.TK.(*guiWidget) switch atype { case widget.Show: if me.debug { w.dumpWidget("Show()") } w.node.State.Hidden = false w.Show() case widget.Hide: if me.debug { w.dumpWidget("Hide()") } if n.Hidden() { // already hidden } else { // log.Log(NOW, "attempt to hide() =", atype, n.WidgetId, n.WidgetType, n.ProgName()) w.node.State.Hidden = true w.Hide() } case widget.Move: log.Log(NOW, "attempt to move() =", atype, n.WidgetType, n.ProgName()) case widget.ToolkitClose: log.Log(NOW, "attempting to close the plugin and release stdout and stderr") standardClose() case widget.Enable: w.Enable() case widget.Disable: w.Disable() case widget.Delete: if w == nil { return } else { w.hideWidgets() w.deleteNode() } n.DeleteNode() default: log.Log(ERROR, "newaction() UNHANDLED Action Type =", atype, "WidgetType =", n.WidgetType, "Name =", n.ProgName()) } log.Log(INFO, "newaction() END", atype, n.String()) } func (w *guiWidget) deleteGocuiViews() { if w.v == nil { // no gocui view to delete for this widget } else { me.baseGui.DeleteView(w.cuiName) w.v = nil } for _, child := range w.children { child.deleteGocuiViews() } } func (w *guiWidget) deleteNode() { p := w.parent for i, child := range p.children { log.Log(NOW, "parent has child:", i, child.cuiName, child.String()) if w == child { log.Log(NOW, "Found child ==", i, child.cuiName, child.String()) log.Log(NOW, "Found n ==", i, w.cuiName, w.String()) p.children = append(p.children[:i], p.children[i+1:]...) } } for i, child := range p.children { log.Log(NOW, "parent now has child:", i, child.cuiName, child.String()) } w.deleteGocuiViews() } func (w *guiWidget) AddText(text string) { if w == nil { log.Log(NOW, "widget is nil") return } w.vals = append(w.vals, text) for i, s := range w.vals { log.Log(NOW, "AddText()", w.String(), i, s) } w.SetText(text) } func (tk *guiWidget) SetText(text string) { var changed bool = false if tk == nil { log.Log(NOW, "widget is nil") return } if tk.labelN != text { tk.labelN = text changed = true } tk.node.State.Label = text if !changed { return } if tk.Visible() { tk.textResize() tk.Hide() tk.Show() } } func (tk *guiWidget) GetText() string { if tk == nil { log.Log(NOW, "widget is nil") return "" } // deprecate this if tk.labelN != "" { return tk.labelN } if tk.node == nil { // return gocui.view name? return tk.cuiName } if tk.node.State.Label != "" { return tk.node.State.Label } return "" } func (tk *guiWidget) Disable() { if tk == nil { log.Log(NOW, "widget is nil") return } initTextbox() tk.prepTextbox() r := new(rectType) r.w0 = 2 r.h0 = 1 r.w1 = r.w0 + 24 r.h1 = r.h0 + 2 me.textbox.tk.forceSizes(r) me.textbox.tk.Show() // actually makes the gocui view. TODO: redo this log.Info("textbox should be shown") // showTextbox("Running...") me.textbox.tk.dumpWidget("shown?") me.textbox.tk.setColorModal() me.textbox.tk.v.Clear() me.textbox.tk.v.WriteString("Running...") me.textbox.tk.v.Editable = true me.textbox.tk.v.Wrap = true me.baseGui.SetView(me.textbox.tk.cuiName, r.w0, r.h0, r.w1, r.h1, 0) me.baseGui.SetCurrentView(me.textbox.tk.v.Name()) // bind the enter key to a function so we can close the textbox me.baseGui.SetKeybinding(me.textbox.tk.v.Name(), gocui.KeyEnter, gocui.ModNone, theCloseTheTextbox) me.textbox.active = true /* tk.enable = false tk.node.State.Enable = false // log.Info("disable widget in gocui", tk.node.WidgetType, tk.node.ProgName()) switch tk.node.WidgetType { case widget.Box: // log.Info("todo: blank out the window here", tk.String()) r := new(rectType) // startW, startH := tk.Position() r.w0 = 0 r.h0 = 0 r.w1 = r.w0 + 24 r.h1 = r.h0 + 2 me.textbox.tk.forceSizes(r) showTextbox("Running...") return case widget.Button: tk.setColorDisable() return default: tk.dumpWidget("fixme: disable") } */ } func (tk *guiWidget) Enable() { if tk == nil { log.Log(NOW, "widget is nil") return } initTextbox() tk.prepTextbox() me.textbox.tk.Hide() /* initTextbox() tk.enable = true tk.node.State.Enable = true // log.Info("enable widget in gocui", tk.node.WidgetType, tk.node.ProgName()) switch tk.node.WidgetType { case widget.Box: // log.Info("todo: un blank the window here") me.textbox.tk.Hide() me.textbox.active = false // log.Info("escaped from textbox") return case widget.Button: tk.restoreEnableColor() return default: tk.dumpWidget("fixme: enable") } */ }