gocui/eventBindings.go

259 lines
7.4 KiB
Go

// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
package main
import (
"fmt"
"strings"
"syscall"
"github.com/awesome-gocui/gocui"
"go.wit.com/log"
)
// register how the 'gocui' will work as a GO toolkit plugin
// all applications will use these keys. they are universal.
// tells 'gocui' where to send events
func registerHandlers(g *gocui.Gui) {
// mouse handlers
g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown) // normal left mouse down
g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown) // mouse with the ctrl key held down
g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp) // mouse button release
g.SetKeybinding("", gocui.MouseWheelUp, gocui.ModNone, wheelsUp) // mouse button release
g.SetKeybinding("", gocui.MouseWheelDown, gocui.ModNone, wheelsDown) // mouse button release
// Ctrl key handlers
g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, doExit) // CTRL-C : exits the application
g.SetKeybinding("", gocui.KeyCtrlV, gocui.ModNone, doPanic) // CTRL-V : force a panic()
g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone, openDebuggger) // CTRL-D : open the (D)ebugger
keyForced, modForced := gocui.MustParse("ctrl+z") // setup ctrl+z
g.SetKeybinding("", keyForced, modForced, handle_ctrl_z) // CTRL-Z :cleverly let's you background gocui (breaks cursor mouse on return)
// regular keys
g.SetKeybinding("", 'H', gocui.ModNone, theHelp) // '?' toggles on and off the help menu
g.SetKeybinding("", 'O', gocui.ModNone, theStdout) // 'o' toggle the STDOUT window
g.SetKeybinding("", 'q', gocui.ModNone, doExit) // 'q' exit
g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, tabCycleWindows) // '2' use this to test new ideas
g.SetKeybinding("", gocui.KeyPgup, gocui.ModNone, stdoutPgup) // Pgup scroll up the Stdout buffer
g.SetKeybinding("", gocui.KeyPgdn, gocui.ModNone, stdoutPgdn) // Pgdn scroll down the Stdout buffer
// debugging
g.SetKeybinding("", '2', gocui.ModNone, theNotsure) // '2' use this to test new ideas
g.SetKeybinding("", 'S', gocui.ModNone, theSuperMouse) // 'S' Super Mouse mode!
g.SetKeybinding("", 'M', gocui.ModNone, printWidgetPlacements) // 'M' list all widgets with positions
g.SetKeybinding("", 'L', gocui.ModNone, printWidgetTree) // 'L' list all widgets in tree view
g.SetKeybinding("", 'f', gocui.ModNone, theFind) // 'f' shows what is under your mouse
g.SetKeybinding("", 'd', gocui.ModNone, theLetterD) // 'd' toggles on and off debugging buttons
g.SetKeybinding("", 'q', gocui.ModNone, quit) // 'q' only exits gocui. plugin stays alive (?)
}
// flips on 'super mouse' mode // this was awesome for debugging gocui. never remove this code.
// while this is turned on, it will print out every widget found under the mouse
func theSuperMouse(g *gocui.Gui, v *gocui.View) error {
if me.supermouse {
log.Log(GOCUI, "supermouse off")
me.supermouse = false
} else {
me.supermouse = true
log.Log(GOCUI, "supermouse on")
}
return nil
}
func (tk *guiWidget) makeTK(ddItems []string) {
items := strings.Join(ddItems, "\n")
var err error
tk.labelN = items
tk.SetText(items)
tk.gocuiSize.w0 = 100
tk.gocuiSize.w1 = 120
tk.gocuiSize.h0 = 15
tk.gocuiSize.h1 = 18
tk.v, err = me.baseGui.SetView(tk.cuiName,
tk.gocuiSize.w0,
tk.gocuiSize.h0,
tk.gocuiSize.w1,
tk.gocuiSize.h1, 0)
if err != nil {
log.Info("makeTK() err", err)
return
}
if tk.v == nil {
return
}
tk.v.Wrap = true
tk.v.Frame = true
tk.v.Clear()
fmt.Fprint(tk.v, items)
tk.Show()
}
/*
func addDropdown() *tree.Node {
return addDropdownNew(-222)
}
*/
// use this to test code ideas // put whatever you want here and hit '2' to activate it
func theNotsure(g *gocui.Gui, v *gocui.View) error {
if me.dark {
me.dark = false
} else {
me.dark = true
}
log.Info("got keypress 2. now what? dark =", me.dark)
return nil
}
func stdoutPgup(g *gocui.Gui, v *gocui.View) error {
me.stdout.pager -= 40
if me.stdout.pager < 0 {
me.stdout.pager = 0
}
tk := me.stdout.tk
tk.refreshStdout()
return nil
}
func stdoutPgdn(g *gocui.Gui, v *gocui.View) error {
me.stdout.pager += 10
tk := me.stdout.tk
tk.refreshStdout()
return nil
}
func wheelsUp(g *gocui.Gui, v *gocui.View) error {
log.Info("private wheels up")
return nil
}
func wheelsDown(g *gocui.Gui, v *gocui.View) error {
log.Info("you've landed")
return nil
}
func tabCycleWindows(g *gocui.Gui, v *gocui.View) error {
// log.Info("try to switch windows here")
if len(me.allwin) != len(findWindows()) {
me.allwin = findWindows()
}
tk := findNextWindow()
if tk == nil {
log.Info("findNextWindow() err. returned nil")
return nil
}
tk.makeWindowActive()
// w, h := g.MousePosition()
// me.downW = tk.gocuiSize.w0
// me.downH = tk.gocuiSize.h0
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
return nil
}
func theStdout(g *gocui.Gui, v *gocui.View) error {
me.stdout.pager = 0
if me.stdout.outputOnTop {
if me.stdout.outputOffscreen {
me.stdout.outputOffscreen = false
log.Info(fmt.Sprintf("set stdout off screen pager=%d len(%d)", me.stdout.pager, len(me.stdout.outputS)))
relocateStdoutOffscreen()
return nil
} else {
me.stdout.outputOffscreen = true
log.Info("set stdout on screen here")
}
// move the stdout window back onscreen
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
me.stdout.outputOnTop = false
setThingsOnTop()
// me.baseGui.SetViewOnBottom("msg")
// setBottomBG()
} else {
me.stdout.outputOnTop = true
setThingsOnTop()
// me.baseGui.SetViewOnTop("msg")
}
return nil
}
func theShow(g *gocui.Gui, v *gocui.View) error {
var w *guiWidget
w = me.treeRoot.TK.(*guiWidget)
w.showWidgets()
return nil
}
func doExit(g *gocui.Gui, v *gocui.View) error {
standardExit()
return nil
}
func doPanic(g *gocui.Gui, v *gocui.View) error {
log.Log(GOCUI, "do panic() here")
standardClose()
panic("forced panic in gocui")
}
func openDebuggger(g *gocui.Gui, v *gocui.View) error {
me.myTree.SendEnableDebugger()
return nil
}
func theFind(g *gocui.Gui, v *gocui.View) error {
w, h := g.MousePosition()
for _, tk := range findByXY(w, h) {
// tk.v.BgColor = gocui.ColorGreen
tk.dumpWidget("theFind()")
// tk.verifyRect()
}
return nil
}
// is run whenever anyone hits 'd' (in an open space)
func theLetterD(g *gocui.Gui, v *gocui.View) error {
// widgets that don't have physical existance in
// a display toolkit are hidden. In the case
// of gocui, they are set as not 'visible' and put offscreen
// or have the size set to zero
// (hopefully anyway) lots of things with the toolkit
// still don't work
fakeStartWidth = me.FakeW
fakeStartHeight = me.TabH + me.FramePadH
if me.showDebug {
showFake()
me.showDebug = false
} else {
hideFake()
me.showDebug = true
}
return nil
}
func theHelp(g *gocui.Gui, v *gocui.View) error {
if me.showHelp {
log.Info("Show the help!")
showHelp()
} else {
log.Info("Hide the help!")
hideHelp()
}
return nil
}
// todo: find and give credit to the person that I found this patch in their forked repo
// handle ctrl+z
func handle_ctrl_z(g *gocui.Gui, v *gocui.View) error {
gocui.Suspend()
log.Info("got ctrl+z")
syscall.Kill(syscall.Getpid(), syscall.SIGSTOP)
log.Info("got ctrl+z syscall() done")
gocui.Resume()
return nil
}