gocui/eventMouseMove.go

153 lines
4.1 KiB
Go

// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
// 2025 note by jcarr:
// this is one of the coolest things ever worked with.
// Personally, I've been working on making a gocui GO plugin
// so I can use it as a generalized console GUI toolkit.
//
// Well done everyone that has contributed to this gocui project !!!
// I am in your debt. Happy hacking & peace.
package main
import (
"fmt"
"github.com/awesome-gocui/gocui"
log "go.wit.com/log"
"go.wit.com/widget"
)
// this function uses the mouse position to highlight & unhighlight things
// this is run every time the user moves the mouse over the terminal window
func mouseMove(g *gocui.Gui) {
w, h := g.MousePosition()
if me.supermouse {
for _, tk := range findByXY(w, h) {
s := fmt.Sprintf("SM (%3d,%3d)", w, h)
tk.dumpWidget(s)
}
}
// toggle off all highlight vies except for whatever is under the mouse
for _, view := range g.Views() {
view.Highlight = false
}
if v, err := g.ViewByPosition(w, h); err == nil {
v.Highlight = true
}
// create the 'msg' view if it does not yet exist // TODO: put this somewhere more correct
if widgetView, _ := g.View("msg"); widgetView == nil {
if createStdout(g) {
return
}
return
}
if me.globalMouseDown && (me.dropdown.active || me.textbox.active) {
log.Info("can't drag while dropdown or textbox are active", w, h)
return
}
if me.globalMouseDown {
// log.Info("msgMouseDown == true")
// plugin will segfault if you don't keep this inside a check for msgMouseDown
// don't move this code out of here
var found bool = false
if me.currentDrag != nil {
// me.currentDrag.dumpWidget(fmt.Sprintf("MM (%3d,%3d)", w, h))
me.currentDrag.moveNew()
return
}
// new function that is smarter
if tk := findWindowUnderMouse(); tk != nil {
me.currentDrag = tk
return
}
// first look for windows
for _, tk := range findByXY(w, h) {
if tk.node.WidgetType == widget.Window {
me.currentDrag = tk
return
}
}
// now look for the STDOUT window
for _, tk := range findByXY(w, h) {
if tk.node.WidgetType == widget.Flag {
me.currentDrag = tk
// tk.moveNew()
return
}
}
for _, tk := range findByXY(w, h) {
if tk.node.WidgetType == widget.Stdout {
me.currentDrag = tk
// tk.moveNew()
return
}
/*
if tk.node.WidgetType == widget.Label {
me.currentDrag = tk
// tk.moveNew()
return
}
*/
found = true
}
if !found {
log.Info(fmt.Sprintf("findByXY() empty. nothing to move at (%d,%d)", w, h))
}
}
}
// this is how the window gets dragged around
func (tk *guiWidget) moveNew() {
w, h := me.baseGui.MousePosition()
if tk.node.WidgetType == widget.Window {
tk.window.wasDragged = true
tk.redrawWindow(w-tk.dragW, h-tk.dragH) // TODO: fix these hard coded things with offsets
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
return
}
if tk.node.WidgetType == widget.Flag {
me.baseGui.SetView(tk.cuiName, w-3, h-3, w+20, h+20, 0)
// tk.verifyRect()
s := fmt.Sprintf("move(%dx%d) %s ###", w, h, tk.cuiName)
tk.dumpWidget(s)
return
} else {
if me.stdout.resize {
newW := w - me.stdout.lastW
newH := h - me.stdout.lastH
me.stdout.w = newW
me.stdout.h = newH
log.Info("Resize true", w, h, newW, newH)
// me.stdout.lastW = w - me.stdout.mouseOffsetW
// me.stdout.lastH = h - me.stdout.mouseOffsetH
tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
} else {
// log.Info("Resize false", w, h)
me.stdout.lastW = w - me.stdout.mouseOffsetW
me.stdout.lastH = h - me.stdout.mouseOffsetH
tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
}
}
// always place the help menu on top
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
}
func createStdout(g *gocui.Gui) bool {
makeOutputWidget(g, "this is a create before a mouse click")
if me.stdout.tk != nil {
msg := fmt.Sprintf("test out gocuiEvent() %d\n", me.ecount)
// me.logStdout.v.Write([]byte(msg))
me.stdout.tk.Write([]byte(msg))
log.Log(NOW, "logStdout test out")
}
return true
}