2025-02-01 11:42:31 -06:00
|
|
|
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
|
|
|
// Use of this source code is governed by the GPL 3.0
|
|
|
|
|
2024-01-18 00:08:37 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2025-02-06 16:19:36 -06:00
|
|
|
"slices"
|
|
|
|
"strings"
|
2024-01-18 00:08:37 -06:00
|
|
|
|
|
|
|
"github.com/awesome-gocui/gocui"
|
|
|
|
|
|
|
|
"go.wit.com/log"
|
2024-01-18 04:10:08 -06:00
|
|
|
"go.wit.com/widget"
|
2024-01-18 00:08:37 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
func showMsg(g *gocui.Gui, v *gocui.View) error {
|
|
|
|
var l string
|
|
|
|
var err error
|
|
|
|
|
|
|
|
log.Log(NOW, "showMsg() v.name =", v.Name())
|
|
|
|
if _, err := g.SetCurrentView(v.Name()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, cy := v.Cursor()
|
|
|
|
if l, err = v.Line(cy); err != nil {
|
|
|
|
l = ""
|
|
|
|
}
|
|
|
|
|
2024-11-13 21:03:50 -06:00
|
|
|
outv := makeOutputWidget(g, l)
|
|
|
|
outv.Write([]byte("test out2"))
|
|
|
|
log.Info("test out2")
|
2024-01-18 00:08:37 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
2024-01-28 02:20:31 -06:00
|
|
|
if me.treeRoot == nil {
|
2024-01-18 00:08:37 -06:00
|
|
|
// keep skipping this until the binary tree is initialized
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2025-02-06 02:49:21 -06:00
|
|
|
if me.stdout.tk == nil {
|
2024-01-18 00:08:37 -06:00
|
|
|
a := new(widget.Action)
|
2025-02-06 04:47:50 -06:00
|
|
|
a.ProgName = "2stdout2"
|
2024-01-18 00:08:37 -06:00
|
|
|
a.WidgetType = widget.Stdout
|
|
|
|
a.WidgetId = -3
|
|
|
|
a.ParentId = 0
|
2024-01-28 02:20:31 -06:00
|
|
|
// n := addNode(a)
|
|
|
|
n := me.myTree.AddNode(a)
|
2025-02-06 02:49:21 -06:00
|
|
|
me.stdout.tk = initWidget(n)
|
2024-01-28 02:20:31 -06:00
|
|
|
|
2025-02-06 02:49:21 -06:00
|
|
|
tk := me.stdout.tk
|
2025-02-06 03:09:13 -06:00
|
|
|
tk.gocuiSize.w0 = me.stdout.lastW
|
|
|
|
tk.gocuiSize.h0 = me.stdout.lastH
|
2025-02-06 02:40:44 -06:00
|
|
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + me.stdout.w
|
|
|
|
tk.gocuiSize.h1 = tk.gocuiSize.h0 + me.stdout.h
|
|
|
|
|
2024-01-18 00:08:37 -06:00
|
|
|
}
|
2025-02-06 02:40:44 -06:00
|
|
|
|
2024-01-18 00:08:37 -06:00
|
|
|
v, err := g.View("msg")
|
|
|
|
if v == nil {
|
|
|
|
log.Log(NOW, "makeoutputwindow() this is supposed to happen. v == nil", err)
|
|
|
|
} else {
|
|
|
|
log.Log(NOW, "makeoutputwindow() msg != nil. WTF now? err =", err)
|
|
|
|
}
|
|
|
|
|
2025-02-06 02:49:21 -06:00
|
|
|
rect := me.stdout.tk.gocuiSize
|
|
|
|
v, err = g.SetView("msg", rect.w0, rect.h0, rect.w1, rect.h1, 0)
|
|
|
|
|
2024-01-18 00:08:37 -06:00
|
|
|
if errors.Is(err, gocui.ErrUnknownView) {
|
|
|
|
log.Log(NOW, "makeoutputwindow() this is supposed to happen?", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Log(NOW, "makeoutputwindow() create output window failed", err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if v == nil {
|
|
|
|
log.Log(NOW, "makeoutputwindow() msg == nil. WTF now? err =", err)
|
|
|
|
return nil
|
|
|
|
} else {
|
2025-02-06 02:49:21 -06:00
|
|
|
me.stdout.tk.v = v
|
2024-01-18 00:08:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
v.Clear()
|
|
|
|
v.SelBgColor = gocui.ColorCyan
|
|
|
|
v.SelFgColor = gocui.ColorBlack
|
|
|
|
fmt.Fprintln(v, "figure out how to capture STDOUT to here\n"+stringFromMouseClick)
|
2025-02-06 04:47:50 -06:00
|
|
|
// g.SetViewOnBottom("msg")
|
|
|
|
// setBottomBG()
|
2025-02-01 19:42:04 -06:00
|
|
|
|
2025-02-06 02:49:21 -06:00
|
|
|
me.stdout.tk.v = v
|
2025-02-06 03:09:13 -06:00
|
|
|
me.stdout.tk.DrawAt(me.stdout.lastW, me.stdout.lastH)
|
2025-02-06 03:28:05 -06:00
|
|
|
relocateStdoutOffscreen()
|
2024-01-18 00:08:37 -06:00
|
|
|
return v
|
|
|
|
}
|
2025-02-06 03:28:05 -06:00
|
|
|
|
|
|
|
func relocateStdoutOffscreen() {
|
2025-02-06 03:33:27 -06:00
|
|
|
if me.stdout.tk == nil {
|
|
|
|
return
|
|
|
|
}
|
2025-02-06 04:15:36 -06:00
|
|
|
log.CaptureMode(me.stdout.tk)
|
|
|
|
log.Log(ERROR, "setting log.CaptureMode(tk.v) in relocateStdoutOffscreen()")
|
2025-02-06 03:28:05 -06:00
|
|
|
newW := 10
|
|
|
|
newH := 0 - me.stdout.h - 4
|
|
|
|
me.stdout.tk.relocateStdout(newW, newH)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tk *guiWidget) relocateStdout(w int, h int) {
|
|
|
|
w0 := w
|
|
|
|
h0 := h
|
|
|
|
w1 := w + me.stdout.w
|
|
|
|
h1 := h + me.stdout.h
|
|
|
|
|
|
|
|
tk.gocuiSize.w0 = w0
|
|
|
|
tk.gocuiSize.w1 = w1
|
|
|
|
tk.gocuiSize.h0 = h0
|
|
|
|
tk.gocuiSize.h1 = h1
|
|
|
|
|
|
|
|
tk.full.w0 = w0
|
|
|
|
tk.full.w1 = w1
|
|
|
|
tk.full.h0 = h0
|
|
|
|
tk.full.h1 = h1
|
|
|
|
|
|
|
|
me.baseGui.SetView("msg", w0, h0, w1, h1, 0)
|
|
|
|
// me.baseGui.SetViewOnBottom("msg")
|
|
|
|
}
|
2025-02-06 16:19:36 -06:00
|
|
|
|
|
|
|
// from the gocui devs:
|
|
|
|
// Write appends a byte slice into the view's internal buffer. Because
|
|
|
|
// View implements the io.Writer interface, it can be passed as parameter
|
|
|
|
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
|
|
|
|
// be called to clear the view's buffer.
|
|
|
|
|
|
|
|
func (w *guiWidget) Write(p []byte) (n int, err error) {
|
|
|
|
w.tainted = true
|
|
|
|
me.writeMutex.Lock()
|
|
|
|
defer me.writeMutex.Unlock()
|
|
|
|
|
|
|
|
tk := me.stdout.tk
|
|
|
|
|
|
|
|
if tk.v == nil {
|
|
|
|
// optionally write the output to /tmp
|
|
|
|
s := fmt.Sprint(string(p))
|
|
|
|
s = strings.TrimSuffix(s, "\n")
|
|
|
|
fmt.Fprintln(outf, s)
|
|
|
|
v, _ := me.baseGui.View("msg")
|
|
|
|
if v != nil {
|
|
|
|
// fmt.Fprintln(outf, "found msg")
|
|
|
|
tk.v = v
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// display the output in the gocui window
|
|
|
|
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
|
|
|
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
|
|
|
|
|
|
|
var cur []string
|
|
|
|
// chop off the last lines in the buffer
|
|
|
|
chop := len(me.stdout.outputS) - (me.stdout.h - 1)
|
|
|
|
if chop < 0 {
|
|
|
|
chop = 0
|
|
|
|
}
|
|
|
|
if len(me.stdout.outputS) > chop {
|
|
|
|
cur = append(cur, me.stdout.outputS[chop:]...)
|
|
|
|
} else {
|
|
|
|
cur = append(cur, me.stdout.outputS...)
|
|
|
|
}
|
|
|
|
slices.Reverse(cur)
|
|
|
|
tk.v.Clear()
|
|
|
|
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
|
|
|
}
|
|
|
|
|
|
|
|
return len(p), nil
|
|
|
|
}
|
2025-02-06 20:59:15 -06:00
|
|
|
|
|
|
|
// lets the user page up and down through the stdout buffer
|
|
|
|
func (tk *guiWidget) refreshStdout() {
|
|
|
|
if len(me.stdout.outputS) < me.stdout.h+me.stdout.pager {
|
|
|
|
log.Info(fmt.Sprintf("buffer too small=%d len(%d)", me.stdout.pager, len(me.stdout.outputS)))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var cur []string
|
|
|
|
// chop off the last lines in the buffer
|
|
|
|
chop := len(me.stdout.outputS) - (me.stdout.pager + me.stdout.h)
|
|
|
|
cur = append(cur, me.stdout.outputS[chop:chop+me.stdout.h]...)
|
|
|
|
slices.Reverse(cur)
|
|
|
|
tk.v.Clear()
|
|
|
|
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
|
|
|
}
|