From 2a5734892a85804b6c44a0cd8dd22d20fed21d96 Mon Sep 17 00:00:00 2001
From: Jeff Carr <jcarr@wit.com>
Date: Thu, 6 Feb 2025 19:00:00 -0600
Subject: [PATCH] trying to fix Hidden() to use the parent

---
 checkbox.go        | 44 ++++++++++++--------------------------------
 debug.go           |  6 +++++-
 dropdown.go        | 29 -----------------------------
 eventBindings.go   | 21 +++++++++++++++++++--
 eventMouseClick.go | 23 -----------------------
 plugin.go          |  8 +++++++-
 size.go            | 31 +++++++++++++++++++++++--------
 structs.go         |  2 +-
 treeDraw.go        | 10 ++++++++--
 9 files changed, 75 insertions(+), 99 deletions(-)

diff --git a/checkbox.go b/checkbox.go
index 4b5f4f2..8e949b2 100644
--- a/checkbox.go
+++ b/checkbox.go
@@ -9,17 +9,24 @@ import (
 	"go.wit.com/widget"
 )
 
+// this comes from the application
 func setChecked(n *tree.Node, b bool) {
 	if n.WidgetType != widget.Checkbox {
 	}
+
+	n.State.Checked = b
 	var tk *guiWidget
 	tk = n.TK.(*guiWidget)
 
-	/*
-		if tk.node.State.Label == "" {
-			tk.node.State.Label = "BLANK"
-		}
-	*/
+	tk.setCheckbox()
+}
+
+// redraw the checkbox
+func (tk *guiWidget) setCheckbox() {
+	if tk.node.WidgetType != widget.Checkbox {
+		log.Log(WARN, "setCheckbox() being run on widget:", tk.node.WidgetType)
+		return
+	}
 	if tk.node.State.Checked {
 		log.Log(WARN, "setCheckbox() got true", tk.node.State.Checked)
 		tk.labelN = "X " + tk.node.State.Label
@@ -31,30 +38,3 @@ func setChecked(n *tree.Node, b bool) {
 	tk.Hide()
 	tk.Show()
 }
-
-// redraw the checkbox
-func (w *guiWidget) setCheckbox() {
-	if w.node.WidgetType != widget.Checkbox {
-		log.Log(WARN, "setCheckbox() being run on widget:", w.node.WidgetType)
-		return
-	}
-	/*
-		if w.node.State.Label == "" {
-			w.node.State.Label = "BLANK"
-		}
-	*/
-	if w.node.State.Checked {
-		log.Log(WARN, "setCheckbox() got true", w.node.State.Checked)
-		w.labelN = "X " + w.node.State.Label
-		// w.changed = true
-	} else {
-		log.Log(WARN, "setCheckbox() got false", w.node.State.Checked)
-		w.labelN = "_ " + w.node.State.Label
-		// w.changed = true
-	}
-	// t := len(w.labelN) + 3
-	// w.gocuiSize.w1 = w.gocuiSize.w0 + t
-
-	w.Hide()
-	w.Show()
-}
diff --git a/debug.go b/debug.go
index f2b2f81..3c83280 100644
--- a/debug.go
+++ b/debug.go
@@ -57,7 +57,11 @@ func (tk *guiWidget) dumpWidget(s string) {
 	}
 	s1 = fmt.Sprintf("(wId,pId)=(%4d,%4d) ", tk.node.WidgetId, pId)
 	sizeW, sizeH := tk.Size()
-	s1 += fmt.Sprintf("size=(%3d,%3d)", sizeW, sizeH)
+	hide := "S"
+	if tk.Hidden() {
+		hide = "H"
+	}
+	s1 += fmt.Sprintf("size=(%3d,%3d)%s)", sizeW, sizeH, hide)
 	if tk.Visible() {
 		s1 += fmt.Sprintf("gocui=(%3d,%3d,%3d,%3d)",
 			tk.gocuiSize.w0, tk.gocuiSize.h0, tk.gocuiSize.w1, tk.gocuiSize.h1)
diff --git a/dropdown.go b/dropdown.go
index 328f7ff..f426fc0 100644
--- a/dropdown.go
+++ b/dropdown.go
@@ -120,9 +120,6 @@ func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string {
 
 	// only need height to figure out what line in the dropdown menu the user clicked
 	_, startH := w.Position()
-	// startW, startH := w.Position()
-	// log.Log(GOCUI, "dropdownClicked() start (w,h) =", startW, startH)
-	// log.Log(GOCUI, "dropdownClicked() at    (w,h) =", mouseW, mouseH)
 
 	itemNumber := mouseH - startH
 	items := me.dropdown.items
@@ -146,19 +143,9 @@ func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string {
 	return ""
 }
 
-var dtoggle bool = false // temporarily tracking show & hide
-var doffset int = 5      // how many spaces over the dropdown menu should be from the mouse
-
 func dropdownUnclicked(w, h int) {
 	var d *guiWidget
 
-	/*
-		if me.dropdownV == nil {
-			log.Log(GOCUI, "mouseUp() dropdownV = nil")
-			return
-		}
-	*/
-
 	// examine everything under X & Y on the screen)
 	for _, tk := range findByXY(w, h) {
 		// tk.dumpWidget("dropdownUnclicked()")
@@ -171,20 +158,4 @@ func dropdownUnclicked(w, h int) {
 		return
 	}
 	// log.Log(GOCUI, "dropdownUnclicked()", d.node.Strings(), "end. now try to enable me.dropdownV")
-	/*
-		dtext := strings.Join(d.node.Strings(), "\n")
-		tk := me.dropdownV
-		if dtoggle {
-			// log.Log(GOCUI, "dropdownUnclicked() set visible=false")
-			tk.Hide()
-			dtoggle = false
-			tk.SetText("goodbye")
-		} else {
-			// log.Log(GOCUI, "dropdownUnclicked() set visible=true")
-			tk.MoveToOffset(w+doffset, h)
-			tk.SetText(dtext)
-			tk.Show()
-			dtoggle = true
-		}
-	*/
 }
diff --git a/eventBindings.go b/eventBindings.go
index e3f1994..eaf8d92 100644
--- a/eventBindings.go
+++ b/eventBindings.go
@@ -5,6 +5,7 @@ package main
 
 import (
 	"fmt"
+	"slices"
 	"strings"
 	"syscall"
 
@@ -103,12 +104,28 @@ func theNotsure(g *gocui.Gui, v *gocui.View) error {
 }
 
 func stdoutPgup(g *gocui.Gui, v *gocui.View) error {
-	log.Info("try to page up in the stdout buffer here")
+	me.stdout.pager = 0
+	log.Info(fmt.Sprintf("try to page up in the stdout buffer here pager=%d len(%d)", me.stdout.pager, len(me.stdout.outputS)))
 	return nil
 }
 
 func stdoutPgdn(g *gocui.Gui, v *gocui.View) error {
-	log.Info("try to page down in the stdout buffer here")
+	me.stdout.pager += 10
+	log.Info(fmt.Sprintf("try to page down in the stdout buffer here pager=%d len(%d)", me.stdout.pager, len(me.stdout.outputS)))
+	tk := me.stdout.tk
+
+	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 nil
+	}
+
+	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"))
 	return nil
 }
 
diff --git a/eventMouseClick.go b/eventMouseClick.go
index 0d09007..5e21d02 100644
--- a/eventMouseClick.go
+++ b/eventMouseClick.go
@@ -76,10 +76,8 @@ func (tk *guiWidget) doWindowClick() {
 func (tk *guiWidget) doWidgetClick(w int, h int) {
 	switch tk.node.WidgetType {
 	case widget.Window:
-		// tk.dumpWidget("doWidgetClick()")
 		tk.doWindowClick()
 		return
-	case widget.Group:
 	case widget.Checkbox:
 		if tk.node.State.Checked {
 			log.Log(WARN, "checkbox is being set to false")
@@ -91,33 +89,12 @@ func (tk *guiWidget) doWidgetClick(w int, h int) {
 			tk.setCheckbox()
 		}
 		me.myTree.SendUserEvent(tk.node)
-	case widget.Grid:
-		/*
-			newR := tk.realGocuiSize()
-			tk.placeGrid(newR.w0, newR.h0)
-			tk.showWidgets()
-		*/
-	case widget.Box:
-		/*
-			if tk.node.State.Direction == widget.Horizontal {
-				log.Log(GOCUI, "BOX IS HORIZONTAL", tk.String())
-			} else {
-				log.Log(GOCUI, "BOX IS VERTICAL", tk.String())
-			}
-			tk.placeWidgets(tk.startW, tk.startH)
-			tk.toggleTree()
-		*/
 	case widget.Button:
 		me.myTree.SendFromUser(tk.node)
 	case widget.Combobox:
 		tk.showDropdown()
 	case widget.Dropdown:
 		tk.showDropdown()
-	case widget.Stdout:
-		/*
-			log.Log(GOCUI, "stdout widget found!")
-			tk.dumpWidget("stdout click")
-		*/
 	case widget.Flag:
 		tk.dropdownClicked(w, h)
 	default:
diff --git a/plugin.go b/plugin.go
index 8509bba..90c84fe 100644
--- a/plugin.go
+++ b/plugin.go
@@ -95,7 +95,13 @@ func newaction(n *tree.Node, atype widget.ActionType) {
 	case widget.Show:
 		w.Show()
 	case widget.Hide:
-		w.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:
diff --git a/size.go b/size.go
index 5b9ff1f..4439298 100644
--- a/size.go
+++ b/size.go
@@ -9,6 +9,19 @@ import (
 	"go.wit.com/widget"
 )
 
+func (tk *guiWidget) Hidden() bool {
+	if tk.parent == nil {
+		return tk.node.Hidden()
+	}
+	if tk.parent.node.WidgetId == 0 {
+		return tk.node.Hidden()
+	}
+	if tk.parent.Hidden() {
+		return true
+	}
+	return tk.node.Hidden()
+}
+
 func (tk *guiWidget) Size() (int, int) {
 	if tk == nil {
 		return 0, 0
@@ -18,7 +31,7 @@ func (tk *guiWidget) Size() (int, int) {
 	}
 
 	// don't count hidden widgets in size calculations
-	if tk.node.Hidden() {
+	if tk.Hidden() {
 		return 0, 0
 	}
 
@@ -27,7 +40,7 @@ func (tk *guiWidget) Size() (int, int) {
 		var maxH int = 0
 		var maxW int = 0
 		for _, child := range tk.children {
-			if tk.node.Hidden() {
+			if tk.Hidden() {
 				continue
 			}
 			sizeW, sizeH := child.Size()
@@ -48,7 +61,7 @@ func (tk *guiWidget) Size() (int, int) {
 		maxH := tk.gocuiSize.Height()
 
 		for _, child := range tk.children {
-			if tk.node.Hidden() {
+			if tk.Hidden() {
 				continue
 			}
 			sizeW, sizeH := child.Size()
@@ -62,8 +75,10 @@ func (tk *guiWidget) Size() (int, int) {
 		return maxW + me.GroupPadW + 3, maxH
 	case widget.Label:
 		return len(tk.String()) + 2, 1
+	case widget.Textbox:
+		return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
 	case widget.Checkbox:
-		return len(tk.String()) + 2, 3
+		return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
 	}
 	if tk.isFake {
 		return 0, 0
@@ -72,13 +87,13 @@ func (tk *guiWidget) Size() (int, int) {
 }
 
 func (w *guiWidget) sizeGrid() (int, int) {
-	if w.node.Hidden() {
+	if w.Hidden() {
 		return 0, 0
 	}
 
 	// first compute the max sizes of the rows and columns
 	for _, child := range w.children {
-		if w.node.Hidden() {
+		if w.Hidden() {
 			continue
 		}
 		sizeW, sizeH := child.Size()
@@ -110,14 +125,14 @@ func (w *guiWidget) sizeBox() (int, int) {
 	if w.node.WidgetType != widget.Box {
 		return 0, 0
 	}
-	if w.node.Hidden() {
+	if w.Hidden() {
 		return 0, 0
 	}
 	var maxW int = 0
 	var maxH int = 0
 
 	for _, child := range w.children {
-		if w.node.Hidden() {
+		if w.Hidden() {
 			continue
 		}
 		sizeW, sizeH := child.Size()
diff --git a/structs.go b/structs.go
index 01a7f49..310f4cf 100644
--- a/structs.go
+++ b/structs.go
@@ -88,7 +88,7 @@ type stdout struct {
 	init            bool       // moves the window offscreen on startup
 	resize          bool       // user is resizing the window
 	outputS         []string   // the buffer of all the output
-
+	pager           int        // allows the user to page through the buffer
 }
 
 // settings for the dropdown window
diff --git a/treeDraw.go b/treeDraw.go
index 86eb673..39c8edc 100644
--- a/treeDraw.go
+++ b/treeDraw.go
@@ -141,8 +141,14 @@ func (w *guiWidget) Show() {
 	// deprecate this
 	// if this isn't in the binary tree
 	// it's some internal widget so always display those
-	if w.node == nil {
-		w.drawView()
+	/*
+		if w.node == nil {
+			w.drawView()
+			return
+		}
+	*/
+
+	if w.node.Hidden() {
 		return
 	}