more mouse click handling cleanups

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2019-05-24 09:02:35 -07:00
parent 9b29c265b2
commit 265a8f6813
7 changed files with 139 additions and 58 deletions

View File

@ -88,8 +88,8 @@ func (ah areaHandler) MouseEvent(a *ui.Area, me *ui.AreaMouseEvent) {
log.Println("GOT MOUSE UP") log.Println("GOT MOUSE UP")
log.Println("GOT MOUSE UP") log.Println("GOT MOUSE UP")
log.Println("GOT MOUSE UP") log.Println("GOT MOUSE UP")
if (Data.ButtonClick != nil) { if (Data.MouseClick != nil) {
Data.ButtonClick(nil) Data.MouseClick(nil)
} }
} }
} }

View File

@ -3,6 +3,8 @@ package gui
import "log" import "log"
import "time" import "time"
import "fmt" import "fmt"
import "strings"
import "os/exec"
import "github.com/gookit/config" import "github.com/gookit/config"
@ -109,4 +111,27 @@ func addDebuggingButtons(vbox *ui.Box, custom func(*ButtonMap, string)) {
vbox.Append(add5button, false) vbox.Append(add5button, false)
vbox.Append(CreateButton("DEBUG goroutines", "DEBUG", custom), false) vbox.Append(CreateButton("DEBUG goroutines", "DEBUG", custom), false)
vbox.Append(CreateButton("xterm", "XTERM", runTestExecClick), false)
}
func runTestExecClick(b *ButtonMap, msg string) {
log.Println("runTestExecClick START")
go runCommand("xterm -report-fonts")
log.Println("runTestExecClick END")
}
func runCommand(s string) {
log.Println("runXterm START")
log.Println("runXterm START")
log.Println("runXterm START")
cmd := strings.TrimSpace(s) // this is like 'chomp' in perl
cmdArgs := strings.Fields(cmd)
process := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
log.Println("runXterm process.Start()")
process.Start()
log.Println("runXterm process.Wait()")
process.Wait()
log.Println("runXterm END")
log.Println("runXterm END")
log.Println("runXterm END")
} }

94
gui.go
View File

@ -15,14 +15,30 @@ import "github.com/davecgh/go-spew/spew"
// //
var Data GuiDataStructure var Data GuiDataStructure
type GuiTabStructure struct {
me *ui.Tab
parentWindow *ui.Window
firstBox *ui.Box
tabOffset int
// this means only one table per tab
mh *TableData
// stuff for the 'area'
// this means only one area per tab
fontButton *ui.FontButton
attrstr *ui.AttributedString
splashArea *ui.Area
}
type GuiDataStructure struct { type GuiDataStructure struct {
State string State string
MainWindow *ui.Window
Width int Width int
Height int Height int
ButtonClick func(*ButtonMap)
CurrentVM string // a fallback default function to handle mouse events
MyArea *ui.Area // if nothing else is defined to handle them
MouseClick func(*ButtonMap)
// general information // general information
Version string Version string
@ -31,6 +47,7 @@ type GuiDataStructure struct {
Buildtime string Buildtime string
HomeDir string HomeDir string
Debug bool Debug bool
DebugTable bool
// official hostname and IPv6 address for this box // official hostname and IPv6 address for this box
Hostname string Hostname string
@ -41,7 +58,21 @@ type GuiDataStructure struct {
AccUser string AccUser string
AccPass string AccPass string
// A map of all buttons everywhere on all
// windows, all tabs, across all goroutines
// This is "GLOBAL"
AllButtons []ButtonMap
// a tab (maybe the one the user is playing with?)
CurrentTab *GuiTabStructure
// a VM (maybe the one the user is playing with?)
CurrentVM string
// All the tabs
Tabs []GuiTabStructure
// stuff for the splash screen / setup tabs // stuff for the splash screen / setup tabs
// MainWindow *ui.Window
cloudWindow *ui.Window cloudWindow *ui.Window
cloudTab *ui.Tab cloudTab *ui.Tab
cloudBox *ui.Box cloudBox *ui.Box
@ -50,9 +81,9 @@ type GuiDataStructure struct {
mainwin *ui.Window mainwin *ui.Window
maintab *ui.Tab maintab *ui.Tab
tabcount int tabcount int
allButtons []ButtonMap
// stuff for the 'area' // stuff for the 'area'
MyArea *ui.Area
fontButton *ui.FontButton fontButton *ui.FontButton
attrstr *ui.AttributedString attrstr *ui.AttributedString
splashArea *ui.Area splashArea *ui.Area
@ -88,8 +119,6 @@ func InitColumns(mh *TableData, parts []TableColumnData) {
humanID := 0 humanID := 0
for key, foo := range parts { for key, foo := range parts {
log.Println("key, foo =", key, foo) log.Println("key, foo =", key, foo)
// log.Println("mh.Cells =", mh.Cells)
// log.Println("mh.Human =", mh.Human)
parts[key].Index = humanID parts[key].Index = humanID
humanID += 1 humanID += 1
@ -177,29 +206,50 @@ func AddTableTab(mytab *ui.Tab, mytabcount int, name string, rowcount int, parts
return mh return mh
} }
// This is the default mouse click handler
// Every mouse click that hasn't been assigned to
// something specific will fall into this routine
// By default, all it runs is the call back to
// the main program that is using this library
func mouseClick(b *ButtonMap, s string) {
log.Println("gui.mouseClick() START b, s =", b, s)
if (Data.MouseClick != nil) {
log.Println("\tData.MouseClick() START")
Data.MouseClick(b)
}
}
func defaultButtonClick(button *ui.Button) { func defaultButtonClick(button *ui.Button) {
log.Println("defaultButtonClick() button =", button) log.Println("defaultButtonClick() button =", button)
for key, foo := range Data.allButtons { for key, foo := range Data.AllButtons {
log.Println("Data.allButtons =", key, foo) log.Println("Data.AllButtons =", key, foo)
if Data.allButtons[key].B == button { if Data.AllButtons[key].B == button {
log.Println("\tBUTTON MATCHED") log.Println("\tBUTTON MATCHED")
log.Println("\tData.allButtons[key].Name", Data.allButtons[key].Name) log.Println("\tData.AllButtons[key].Name", Data.AllButtons[key].Name)
log.Println("\tData.allButtons[key].Note", Data.allButtons[key].Note) log.Println("\tData.AllButtons[key].Note", Data.AllButtons[key].Note)
if (Data.ButtonClick != nil) { if Data.AllButtons[key].custom != nil {
Data.ButtonClick( &Data.allButtons[key]) log.Println("\tDOING CUSTOM FUNCTION")
} else if Data.allButtons[key].custom != nil { Data.AllButtons[key].custom(&Data.AllButtons[key], "SOMETHING CUSTOM")
Data.allButtons[key].custom(nil, "BUTTON DOES NOTHING") return
}
if (Data.MouseClick != nil) {
Data.MouseClick( &Data.AllButtons[key])
} }
return return
} }
} }
log.Println("\tBUTTON NOT FOUND") log.Println("\tBUTTON NOT FOUND")
// still run the mouse click handler
if (Data.MouseClick != nil) {
Data.MouseClick(nil)
}
} }
func defaultFontButtonClick(button *ui.FontButton) { func defaultFontButtonClick(button *ui.FontButton) {
log.Println("defaultButtonClick() button =", button) log.Println("defaultButtonClick() button =", button)
for key, foo := range Data.allButtons { for key, foo := range Data.AllButtons {
log.Println("Data.allButtons =", key, foo) log.Println("Data.AllButtons =", key, foo)
} }
} }
@ -213,7 +263,7 @@ func CreateButton(name string, note string, custom func(*ButtonMap, string)) *ui
newmap.Note = note newmap.Note = note
newmap.Name = name newmap.Name = name
newmap.custom = custom newmap.custom = custom
Data.allButtons = append(Data.allButtons, newmap) Data.AllButtons = append(Data.AllButtons, newmap)
return newB return newB
} }
@ -230,7 +280,7 @@ func CreateAccountButton(account string, custom func(*ButtonMap, string)) *ui.Bu
newmap.Name = name newmap.Name = name
newmap.AccNick = account newmap.AccNick = account
newmap.custom = custom newmap.custom = custom
Data.allButtons = append(Data.allButtons, newmap) Data.AllButtons = append(Data.AllButtons, newmap)
return newB return newB
} }
@ -247,7 +297,7 @@ func CreateLoginButton(account string, custom func(*ButtonMap, string)) *ui.Butt
newmap.Name = name newmap.Name = name
newmap.AccNick = account newmap.AccNick = account
newmap.custom = custom newmap.custom = custom
Data.allButtons = append(Data.allButtons, newmap) Data.AllButtons = append(Data.AllButtons, newmap)
return newB return newB
} }
@ -261,7 +311,7 @@ func CreateFontButton(name string, note string, custom func(*ButtonMap, string))
newmap.FB = newB newmap.FB = newB
newmap.Note = note newmap.Note = note
newmap.custom = custom newmap.custom = custom
Data.allButtons = append(Data.allButtons, newmap) Data.AllButtons = append(Data.AllButtons, newmap)
return newB return newB
} }

View File

@ -8,25 +8,13 @@ import _ "github.com/andlabs/ui/winmanifest"
// import "github.com/davecgh/go-spew/spew" // import "github.com/davecgh/go-spew/spew"
func buttonClick(b *ButtonMap, s string) {
log.Println("gui.buttonClick() b, s =", b, s)
log.Println("Figure out what to do here")
log.Println("Figure out what to do here")
log.Println("Figure out what to do here")
if (Data.ButtonClick != nil) {
log.Println("Data.ButtonClick() START")
Data.ButtonClick(nil)
}
}
func ShowAccountQuestionTab() { func ShowAccountQuestionTab() {
Data.cloudTab.Delete(0) Data.cloudTab.Delete(0)
log.Println("Sleep(200)") log.Println("Sleep(200)")
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
Data.smallBox = AddAccountQuestionBox(nil, buttonClick) Data.smallBox = AddAccountQuestionBox(nil, mouseClick)
Data.cloudTab.InsertAt("New Account?", 0, Data.smallBox) Data.cloudTab.InsertAt("New Account?", 0, Data.smallBox)
Data.cloudTab.SetMargined(0, true) Data.cloudTab.SetMargined(0, true)
} }
@ -37,7 +25,7 @@ func ShowAccountTab() {
log.Println("Sleep(200)") log.Println("Sleep(200)")
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
Data.smallBox = AddAccountBox(buttonClick) Data.smallBox = AddAccountBox(mouseClick)
Data.cloudTab.InsertAt("Add Account", 0, Data.smallBox) Data.cloudTab.InsertAt("Add Account", 0, Data.smallBox)
Data.cloudTab.SetMargined(0, true) Data.cloudTab.SetMargined(0, true)
} }
@ -48,7 +36,7 @@ func ShowMainTab() {
log.Println("Sleep(200)") log.Println("Sleep(200)")
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
Data.smallBox = makeCloudInfoBox(buttonClick) Data.smallBox = makeCloudInfoBox(mouseClick)
Data.cloudTab.InsertAt("Main", 0, Data.smallBox) Data.cloudTab.InsertAt("Main", 0, Data.smallBox)
Data.cloudTab.SetMargined(0, true) Data.cloudTab.SetMargined(0, true)
} }
@ -61,21 +49,18 @@ func makeCloudWindow() {
Data.cloudWindow = ui.NewWindow("", 640, 480, true) Data.cloudWindow = ui.NewWindow("", 640, 480, true)
// cloudWindow.SetBorderless(true) // cloudWindow.SetBorderless(true)
Data.cloudWindow.OnClosing(func(*ui.Window) bool { Data.cloudWindow.OnClosing(func(*ui.Window) bool {
if (Data.ButtonClick != nil) { if (Data.MouseClick != nil) {
log.Println("Data.ButtonClick() START QUIT") log.Println("SIMULATE Data.MouseClick(QUIT)")
Data.State = "QUIT" Data.MouseClick(nil)
Data.ButtonClick(nil)
} }
// ui.Quit()
return true return true
}) })
ui.OnShouldQuit(func() bool { ui.OnShouldQuit(func() bool {
if (Data.ButtonClick != nil) { if (Data.MouseClick != nil) {
log.Println("Data.ButtonClick() START QUIT") log.Println("SIMULATE Data.MouseClick(QUIT)")
Data.State = "QUIT" Data.State = "QUIT"
Data.ButtonClick(nil) Data.MouseClick(nil)
} }
// Data.cloudWindow.Destroy()
return true return true
}) })
@ -83,7 +68,7 @@ func makeCloudWindow() {
Data.cloudWindow.SetChild(Data.cloudTab) Data.cloudWindow.SetChild(Data.cloudTab)
Data.cloudWindow.SetMargined(true) Data.cloudWindow.SetMargined(true)
Data.cloudBox = ShowSplashBox(nil, nil, buttonClick) Data.cloudBox = ShowSplashBox(nil, nil, mouseClick)
Data.cloudTab.Append("WIT Splash", Data.cloudBox) Data.cloudTab.Append("WIT Splash", Data.cloudBox)
Data.cloudTab.SetMargined(0, true) Data.cloudTab.SetMargined(0, true)

View File

@ -28,13 +28,25 @@ type RowData struct {
HumanData [20]HumanCellData HumanData [20]HumanCellData
} }
// hmm. will this stand the test of time? //
// This maps the andlabs/ui & libui components into a "human"
// readable cell reference list. The reason is that there
// are potentially 3 values for each cell. The Text, the Color
// and an image. These are not always needed so the number
// of fields varies between 1 and 3. Internally, the toolkit
// GUI abstraction needs to list all of them, but it's then
// hard to figure out which column goes with the columns that
// you see when you visually are looking at it like a spreadsheet
//
// This makes a map so that we can say "give me the value at
// row 4 and column 2" and find the fields that are needed
//
// TODO: add back image support and the progress bar
//
type HumanCellData struct { type HumanCellData struct {
Name string // what kind of row is this? Name string // what kind of row is this?
// Text ui.TableString
Text string Text string
TextID int TextID int
// Color ui.TableColor
Color color.RGBA Color color.RGBA
ColorID int ColorID int
} }
@ -45,6 +57,10 @@ type HumanMap struct {
ColorID int ColorID int
} }
//
// This is the structure that andlabs/ui uses to pass information
// to the GUI. This is the "authoritative" data.
//
type TableData struct { type TableData struct {
RowCount int // This is the number of 'rows' which really means data elements not what the human sees RowCount int // This is the number of 'rows' which really means data elements not what the human sees
RowWidth int // This is how wide each row is RowWidth int // This is how wide each row is
@ -53,6 +69,9 @@ type TableData struct {
Cells [20]CellData Cells [20]CellData
Human [20]HumanMap Human [20]HumanMap
lastRow int
lastColumn int
} }
func initRowBTcolor(mh *TableData, intBG int, cell TableColumnData) { func initRowBTcolor(mh *TableData, intBG int, cell TableColumnData) {

View File

@ -16,14 +16,14 @@ import _ "github.com/andlabs/ui/winmanifest"
func (mh *TableData) NumRows(m *ui.TableModel) int { func (mh *TableData) NumRows(m *ui.TableModel) int {
if (Data.Debug) { if (Data.Debug) {
log.Println("NumRows = mh.RowCount = ", mh.RowCount) log.Println("NumRows = mh.RowCount = ", mh.RowCount, "(last Row & Column =", mh.lastRow, mh.lastColumn, ")")
} }
return mh.RowCount return mh.RowCount
} }
// FYI: this routine seems to be called around 10 to 100 times a second for each table // FYI: this routine seems to be called around 10 to 100 times a second for each table
func (mh *TableData) ColumnTypes(m *ui.TableModel) []ui.TableValue { func (mh *TableData) ColumnTypes(m *ui.TableModel) []ui.TableValue {
if (Data.Debug) { if (Data.DebugTable) {
log.Println("ColumnTypes = ", mh.generatedColumnTypes) log.Println("ColumnTypes = ", mh.generatedColumnTypes)
} }
return mh.generatedColumnTypes return mh.generatedColumnTypes
@ -44,9 +44,11 @@ func libuiColorToGOlangColor(rgba color.RGBA) ui.TableColor {
// TODO: Figure out why this is being called 1000 times a second (10 times for each row & column) // TODO: Figure out why this is being called 1000 times a second (10 times for each row & column)
// Nevermind this TODO. Who gives a shit. This is a really smart way to treat the OS toolkits // Nevermind this TODO. Who gives a shit. This is a really smart way to treat the OS toolkits
func (mh *TableData) CellValue(m *ui.TableModel, row, column int) ui.TableValue { func (mh *TableData) CellValue(m *ui.TableModel, row, column int) ui.TableValue {
if (Data.Debug) { if (Data.DebugTable) {
log.Println("CellValue() row, column =", row, column) log.Println("CellValue() row, column =", row, column)
} }
mh.lastRow = row
mh.lastColumn = column
humanID := mh.Cells[column].HumanID humanID := mh.Cells[column].HumanID
if (column == mh.Human[humanID].TextID) { if (column == mh.Human[humanID].TextID) {
return ui.TableString(mh.Rows[row].HumanData[humanID].Text) return ui.TableString(mh.Rows[row].HumanData[humanID].Text)
@ -99,7 +101,7 @@ func defaultSetCellValue(mh *TableData, row int, column int) {
log.Println("vmname =", vmname) log.Println("vmname =", vmname)
log.Println("defaultSetCellValue() FOUND THE BUTTON!!!!!!! Button was pressed START", row, column) log.Println("defaultSetCellValue() FOUND THE BUTTON!!!!!!! Button was pressed START", row, column)
Data.CurrentVM = fmt.Sprintf("%s",vmname) Data.CurrentVM = fmt.Sprintf("%s",vmname)
log.Println("Data.CurrentVM =", Data.CurrentVM) log.Println("User last clicked on Data.CurrentVM =", Data.CurrentVM)
if (Data.Debug) { if (Data.Debug) {
go ui.Main(ShowVM) go ui.Main(ShowVM)
} else { } else {

View File

@ -152,8 +152,8 @@ func createVmBox(tab *ui.Tab, custom func(b *ButtonMap,s string)) {
func buttonVmClick(b *ButtonMap, s string) { func buttonVmClick(b *ButtonMap, s string) {
log.Println("gui.buttonVmClick() START") log.Println("gui.buttonVmClick() START")
if (Data.ButtonClick != nil) { if (Data.MouseClick != nil) {
log.Println("Data.ButtonClick() START") log.Println("Data.ButtonClick() START")
Data.ButtonClick(nil) Data.MouseClick(nil)
} }
} }