175 lines
4.6 KiB
Go
175 lines
4.6 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"
|
||
|
"time"
|
||
|
|
||
|
"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) {
|
||
|
me.ok = true // this tells init() it's okay to work with gocui
|
||
|
// very useful for debugging in the past. also, just fun
|
||
|
if me.supermouse {
|
||
|
w, h := g.MousePosition()
|
||
|
for _, tk := range findByXY(w, h) {
|
||
|
s := fmt.Sprintf("SM (%3d,%3d)", w, h)
|
||
|
tk.dumpWidget(s)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if time.Since(me.mouse.down) < me.mouse.clicktime {
|
||
|
// log.Info("not yet")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if me.dropdown.active || me.textbox.active {
|
||
|
// can't drag or do anything when dropdown or textbox are visible
|
||
|
return
|
||
|
}
|
||
|
// okay, the mouse is down and it has been long enough
|
||
|
// the user is trying to drag something. let's figure out what
|
||
|
|
||
|
w, h := g.MousePosition()
|
||
|
// 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.mouse.globalMouseDown && (me.dropdown.active || me.textbox.active) {
|
||
|
log.Info("can't drag while dropdown or textbox are active", w, h)
|
||
|
return
|
||
|
}
|
||
|
*/
|
||
|
if me.mouse.mouseUp {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// if me.mouse.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.mouse.currentDrag != nil {
|
||
|
// me.mouse.currentDrag.dumpWidget(fmt.Sprintf("MM (%3d,%3d)", w, h))
|
||
|
me.mouse.currentDrag.moveNew()
|
||
|
return
|
||
|
}
|
||
|
// new function that is smarter
|
||
|
if tk := findWindowUnderMouse(); tk != nil {
|
||
|
tk.setAsDragging()
|
||
|
return
|
||
|
}
|
||
|
// first look for windows
|
||
|
for _, tk := range findByXY(w, h) {
|
||
|
if tk.node.WidgetType == widget.Window {
|
||
|
tk.setAsDragging()
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// now look for the STDOUT window
|
||
|
for _, tk := range findByXY(w, h) {
|
||
|
if tk.node.WidgetType == widget.Flag {
|
||
|
tk.setAsDragging()
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
for _, tk := range findByXY(w, h) {
|
||
|
if tk.node.WidgetType == widget.Stdout {
|
||
|
tk.setAsDragging()
|
||
|
// tk.moveNew()
|
||
|
return
|
||
|
}
|
||
|
/*
|
||
|
if tk.node.WidgetType == widget.Label {
|
||
|
me.mouse.currentDrag = tk
|
||
|
// tk.moveNew()
|
||
|
return
|
||
|
}
|
||
|
*/
|
||
|
found = true
|
||
|
}
|
||
|
if !found {
|
||
|
log.Info(fmt.Sprintf("findByXY() empty. nothing to move at (%d,%d)", w, h))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (tk *guiWidget) setAsDragging() {
|
||
|
me.mouse.currentDrag = tk
|
||
|
tk.lastW = tk.gocuiSize.w0
|
||
|
tk.lastH = tk.gocuiSize.h0
|
||
|
}
|
||
|
|
||
|
// 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
|
||
|
|
||
|
// compute the new location based off how far the mouse has moved
|
||
|
// since the mouse button was pressed down
|
||
|
newW := tk.lastW + w - me.mouse.downW
|
||
|
newH := tk.lastH + h - me.mouse.downH
|
||
|
tk.redrawWindow(newW, newH)
|
||
|
|
||
|
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
|
||
|
}
|
||
|
if tk.node.WidgetType == widget.Stdout {
|
||
|
if me.mouse.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 {
|
||
|
// compute the new location based off how far the mouse has moved
|
||
|
// since the mouse button was pressed down
|
||
|
newW := tk.lastW + w - me.mouse.downW
|
||
|
newH := tk.lastH + h - me.mouse.downH
|
||
|
tk.relocateStdout(newW, newH)
|
||
|
}
|
||
|
}
|
||
|
// always place the help menu on top
|
||
|
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||
|
}
|