summaryrefslogtreecommitdiff
path: root/eventMouseDrag.go
diff options
context:
space:
mode:
Diffstat (limited to 'eventMouseDrag.go')
-rw-r--r--eventMouseDrag.go185
1 files changed, 185 insertions, 0 deletions
diff --git a/eventMouseDrag.go b/eventMouseDrag.go
new file mode 100644
index 0000000..e976d22
--- /dev/null
+++ b/eventMouseDrag.go
@@ -0,0 +1,185 @@
+// 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
+}
+
+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
+}