summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--gui.go286
-rw-r--r--table.go116
-rw-r--r--tableCallbacks.go41
4 files changed, 454 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..60cc8de
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+# simple sortcut to push all git changes
+push:
+ git pull
+ git add --all
+ -git commit -a -s
+ git push
+
+# should update every go dependancy (?)
+update:
+ git pull
+ go get -v -t -u ./...
diff --git a/gui.go b/gui.go
new file mode 100644
index 0000000..71ef399
--- /dev/null
+++ b/gui.go
@@ -0,0 +1,286 @@
+package main
+
+import "log"
+// import "fmt"
+
+import "github.com/gookit/config"
+import "github.com/andlabs/ui"
+import _ "github.com/andlabs/ui/winmanifest"
+
+import "github.com/davecgh/go-spew/spew"
+
+var mainwin *ui.Window
+var maintab *ui.Tab
+var tabcount int
+
+var jcarrButton *ui.Button
+var jcarrEntry *ui.MultilineEntry
+
+func buttonClick(button *ui.Button) {
+ log.Println("hostname =", config.String("hostname"), button)
+ spew.Dump(button)
+ if (jcarrButton == button) {
+ log.Println("This is the jcarrButton")
+ cur := jcarrEntry.Text()
+ jcarrEntry.SetText(cur + "THIS IS A GREAT IDEA\n")
+ } else {
+ log.Println("This is NOT the jcarrButton")
+ }
+}
+
+func hostnameButton(hostname string) ui.Control {
+ tmpbox := ui.NewHorizontalBox()
+ tmpbox.SetPadded(true)
+
+ tmpButton := ui.NewButton(hostname)
+ tmpbox.Append(tmpButton, false)
+ tmpButton.OnClicked(buttonClick)
+
+ jcarrButton = tmpButton
+
+ return tmpbox
+}
+
+func makeGroupEntries() ui.Control {
+ group := ui.NewGroup("Entries")
+ group.SetMargined(true)
+
+ group.SetChild(ui.NewNonWrappingMultilineEntry())
+
+ entryForm := ui.NewForm()
+ entryForm.SetPadded(true)
+ group.SetChild(entryForm)
+
+ jcarrEntry = ui.NewMultilineEntry()
+ entryForm.Append("Entry", ui.NewEntry(), false)
+ entryForm.Append("Password Entry", ui.NewPasswordEntry(), false)
+ entryForm.Append("Search Entry", ui.NewSearchEntry(), false)
+ entryForm.Append("Multiline Entry", jcarrEntry, true)
+ entryForm.Append("Multiline Entry No Wrap", ui.NewNonWrappingMultilineEntry(), true)
+
+ return group
+}
+
+func makeNumbersPage() ui.Control {
+ hbox := ui.NewHorizontalBox()
+ hbox.SetPadded(true)
+
+ group := ui.NewGroup("Numbers")
+ group.SetMargined(true)
+ hbox.Append(group, true)
+
+ vbox := ui.NewVerticalBox()
+ vbox.SetPadded(true)
+ group.SetChild(vbox)
+
+ spinbox := ui.NewSpinbox(47, 100)
+ slider := ui.NewSlider(21, 100)
+ pbar := ui.NewProgressBar()
+
+ spinbox.OnChanged(func(*ui.Spinbox) {
+ slider.SetValue(spinbox.Value())
+ pbar.SetValue(spinbox.Value())
+ })
+ slider.OnChanged(func(*ui.Slider) {
+ spinbox.SetValue(slider.Value())
+ pbar.SetValue(slider.Value())
+ })
+ vbox.Append(spinbox, false)
+ vbox.Append(slider, false)
+ vbox.Append(pbar, false)
+ vbox.Append(hostnameButton("jcarrtest"), false)
+
+ ip := ui.NewProgressBar()
+ ip.SetValue(-1)
+ vbox.Append(ip, false)
+
+ group = ui.NewGroup("Lists")
+ group.SetMargined(true)
+ hbox.Append(group, true)
+
+ vbox = ui.NewVerticalBox()
+ vbox.SetPadded(true)
+ group.SetChild(vbox)
+
+ cbox := ui.NewCombobox()
+ cbox.Append("Combobox Item 1")
+ cbox.Append("Combobox Item 2")
+ cbox.Append("Combobox Item 3")
+ vbox.Append(cbox, false)
+
+ ecbox := ui.NewEditableCombobox()
+ ecbox.Append("Editable Item 1")
+ ecbox.Append("Editable Item 2")
+ ecbox.Append("Editable Item 3")
+ vbox.Append(ecbox, false)
+
+ rb := ui.NewRadioButtons()
+ rb.Append("Radio Button 1")
+ rb.Append("Radio Button 2")
+ rb.Append("Radio Button 3")
+ vbox.Append(rb, false)
+
+ return hbox
+}
+
+func makeDataChoosersPage() ui.Control {
+ hbox := ui.NewHorizontalBox()
+ hbox.SetPadded(true)
+
+ vbox := ui.NewVerticalBox()
+ vbox.SetPadded(true)
+ hbox.Append(vbox, false)
+
+ vbox.Append(ui.NewDatePicker(), false)
+ vbox.Append(ui.NewTimePicker(), false)
+ vbox.Append(ui.NewDateTimePicker(), false)
+ vbox.Append(ui.NewFontButton(), false)
+ vbox.Append(ui.NewColorButton(), false)
+
+ hbox.Append(ui.NewVerticalSeparator(), false)
+
+ vbox = ui.NewVerticalBox()
+ vbox.SetPadded(true)
+ hbox.Append(vbox, true)
+
+ grid := ui.NewGrid()
+ grid.SetPadded(true)
+ vbox.Append(grid, false)
+
+ button := ui.NewButton("Open File")
+ entry := ui.NewEntry()
+ entry.SetReadOnly(true)
+ button.OnClicked(func(*ui.Button) {
+ filename := ui.OpenFile(mainwin)
+ if filename == "" {
+ filename = "(cancelled)"
+ }
+ entry.SetText(filename)
+ })
+ grid.Append(button,
+ 0, 0, 1, 1,
+ false, ui.AlignFill, false, ui.AlignFill)
+ grid.Append(entry,
+ 1, 0, 1, 1,
+ true, ui.AlignFill, false, ui.AlignFill)
+
+ button = ui.NewButton("Save File")
+ entry2 := ui.NewEntry()
+ entry2.SetReadOnly(true)
+ button.OnClicked(func(*ui.Button) {
+ filename := ui.SaveFile(mainwin)
+ if filename == "" {
+ filename = "(cancelled)"
+ }
+ entry2.SetText(filename)
+ })
+ grid.Append(button,
+ 0, 1, 1, 1,
+ false, ui.AlignFill, false, ui.AlignFill)
+ grid.Append(entry2,
+ 1, 1, 1, 1,
+ true, ui.AlignFill, false, ui.AlignFill)
+
+ msggrid := ui.NewGrid()
+ msggrid.SetPadded(true)
+ grid.Append(msggrid,
+ 0, 2, 2, 1,
+ false, ui.AlignCenter, false, ui.AlignStart)
+
+ button = ui.NewButton("Message Box")
+ button.OnClicked(func(*ui.Button) {
+ ui.MsgBox(mainwin,
+ "This is a normal message box.",
+ "More detailed information can be shown here.")
+ })
+ msggrid.Append(button,
+ 0, 0, 1, 1,
+ false, ui.AlignFill, false, ui.AlignFill)
+ button = ui.NewButton("Error Box")
+ button.OnClicked(func(*ui.Button) {
+ ui.MsgBoxError(mainwin,
+ "This message box describes an error.",
+ "More detailed information can be shown here.")
+ })
+ msggrid.Append(button,
+ 1, 0, 1, 1,
+ false, ui.AlignFill, false, ui.AlignFill)
+
+ return hbox
+}
+
+func setupUI() {
+ mainwin = ui.NewWindow("Cloud Control Panel", config.Int("width"), config.Int("height"), false)
+ mainwin.OnClosing(func(*ui.Window) bool {
+ ui.Quit()
+ return true
+ })
+ ui.OnShouldQuit(func() bool {
+ mainwin.Destroy()
+ return true
+ })
+
+ maintab = ui.NewTab()
+ mainwin.SetChild(maintab)
+ mainwin.SetMargined(true)
+
+ maintab.Append("List examples", makeNumbersPage())
+ tabcount = 0
+ maintab.SetMargined(tabcount, true)
+
+ maintab.Append("Choosers examples", makeDataChoosersPage())
+ tabcount += 1
+ maintab.SetMargined(tabcount, true)
+
+ maintab.Append("Group examples", makeGroupEntries())
+ tabcount += 1
+ maintab.SetMargined(tabcount, true)
+
+ mainwin.Show()
+}
+
+func addTableTab(name string, rowcount int, row1name string) {
+ mh := new(tableData)
+
+ mh.rowcount = rowcount
+ mh.rows = make([]rowData, mh.rowcount)
+
+ // This is the standard callback function from libUI when the user does something
+ mh.libUIevent = defaultSetCellValue
+
+ tmpBTindex := 0
+ initBTcolor (mh, 0)
+ initTextColorColumn(mh, 1, 2, "really fun", ui.TableColor{0.9, 0, 0, 1})
+ initButtonColumn (mh, 3, "but3ton")
+ initTextColorColumn(mh, 4, 5, "jwc45blah", ui.TableColor{0.0, 0.9, 0.4, 1})
+ initTextColorColumn(mh, 6, 7, "jwc67blah", ui.TableColor{0.3, 0.1, 0.9, 1})
+ initTextColumn (mh, 8, "jwc8blah")
+ initButtonColumn (mh, 9, "but9ton")
+
+ model := ui.NewTableModel(mh)
+
+ table := ui.NewTable(
+ &ui.TableParams{
+ Model: model,
+ RowBackgroundColorModelColumn: tmpBTindex,
+ })
+
+ appendTextColumn (mh, table, 1, "jwc1col")
+ table.AppendButtonColumn("button3", 3, ui.TableModelColumnAlwaysEditable)
+ appendTextColorColumn (mh, table, 4, 5, "testcolor")
+ appendTextColorColumn (mh, table, 6, 7, "appendTest")
+ appendTextColumn (mh, table, 8, "jwc8col")
+ table.AppendButtonColumn("button9", 9, ui.TableModelColumnAlwaysEditable)
+
+ tabcount += 1
+ maintab.Append(name, table)
+ maintab.SetMargined(tabcount, true)
+}
+
+func doGUI() {
+ ui.Main(setupUI)
+
+ log.Println("GUI exited. Not sure what to do here. os.Exit() ?")
+
+ onExit()
+}
diff --git a/table.go b/table.go
new file mode 100644
index 0000000..6e23e25
--- /dev/null
+++ b/table.go
@@ -0,0 +1,116 @@
+// based off andlabs/ui/examples/table.go
+
+package main
+
+import "fmt"
+import "log"
+import "github.com/andlabs/ui"
+import _ "github.com/andlabs/ui/winmanifest"
+
+var img [2]*ui.Image
+
+type cellData struct {
+ index int
+ value ui.TableValue
+ name string // what type of cell is this?
+ event func() // what function to call if there is an event on this
+}
+
+// hmm. will this stand the test of time?
+type rowData struct {
+ name string // what kind of row is this?
+ status string // status of the row?
+/*
+ // These may or may not be implementable
+ click func() // what function to call if the user clicks on it
+ doubleclick func() // what function to call if the user double clicks on it
+*/
+ cells [20]cellData
+}
+
+type tableData struct {
+ rowcount int // This is the number of 'rows' which really means data elements not what the human sees
+ rows []rowData // This is all the table data by row
+ generatedColumnTypes []ui.TableValue // generate this dynamically
+ libUIevent func(*tableData, *ui.TableModel, int, int, ui.TableValue)
+}
+
+func initBTcolor(mh *tableData, intBG int) {
+ img[0] = ui.NewImage(16, 16)
+ img[1] = ui.NewImage(16, 16)
+
+ mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableColor{})
+
+ for i := 0; i < mh.rowcount; i++ {
+ log.Println("i=",i)
+
+ // alternate background of each row light and dark
+ if (i % 2) == 1 {
+ mh.rows[i].cells[intBG].value = ui.TableColor{0.5, 0.5, 0.5, .7}
+ mh.rows[i].cells[intBG].name = "BG"
+ } else {
+ mh.rows[i].cells[intBG].value = ui.TableColor{0.1, 0.1, 0.1, .1}
+ mh.rows[i].cells[intBG].name = "BG"
+ }
+ }
+}
+
+func initButtonColumn(mh *tableData, buttonID int, junk string) {
+ mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString(""))
+
+ for i := 0; i < mh.rowcount; i++ {
+ // set the button text for Column ?
+ mh.rows[i].cells[buttonID].value = ui.TableString(fmt.Sprintf("%s %d", junk, i))
+ mh.rows[i].cells[buttonID].name = "BUTTON"
+ }
+}
+
+func initTextColorColumn(mh *tableData, stringID int, colorID int, junk string, color ui.TableColor) {
+ mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString(""))
+ mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableColor{})
+
+ for i := 0; i < mh.rowcount; i++ {
+ log.Println("i=",i)
+
+ // text for Column ?
+ mh.rows[i].cells[stringID].value = ui.TableString(fmt.Sprintf("%s %d", junk, i))
+ mh.rows[i].cells[stringID].name = "EDIT"
+
+ // text color for Column ?
+ mh.rows[i].cells[colorID].value = color
+ mh.rows[i].cells[colorID].name = "COLOR"
+ }
+}
+
+func initTextColumn(mh *tableData, stringID int, junk string) {
+ mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString(""))
+
+ for i := 0; i < mh.rowcount; i++ {
+ log.Println("i=",i)
+
+ // text for Column ?
+ mh.rows[i].cells[stringID].value = ui.TableString(fmt.Sprintf("%s %d", junk, i))
+ mh.rows[i].cells[stringID].name = "EDIT"
+ }
+}
+
+func appendTextColorColumn(mh *tableData, table *ui.Table, stringID int, colorID int, columnName string) {
+ table.AppendTextColumn(columnName, stringID, ui.TableModelColumnAlwaysEditable,
+ &ui.TableTextColumnOptionalParams{
+ ColorModelColumn: colorID,
+ });
+}
+
+func appendTextColumn(mh *tableData, table *ui.Table, stringID int, columnName string) {
+ table.AppendTextColumn(columnName, stringID, ui.TableModelColumnAlwaysEditable, nil)
+}
+
+func defaultSetCellValue(mh *tableData, m *ui.TableModel, row, column int, value ui.TableValue) {
+ if (mh.rows[row].cells[column].name == "EDIT") {
+ mh.rows[row].cells[column].value = value
+ }
+ if (mh.rows[row].cells[column].name == "BUTTON") {
+ log.Println("FOUND THE BUTTON!!!!!!! Button was pressed START", row, column)
+ }
+ return
+}
diff --git a/tableCallbacks.go b/tableCallbacks.go
new file mode 100644
index 0000000..42f91ef
--- /dev/null
+++ b/tableCallbacks.go
@@ -0,0 +1,41 @@
+package main
+
+//
+// These functions are the hooks to the andlabs libui
+// They eventually feed information to the OS native GUI toolkits
+// and feed back user interaction with the GUI
+//
+
+import "os"
+import "log"
+
+import "github.com/andlabs/ui"
+import _ "github.com/andlabs/ui/winmanifest"
+
+func (mh *tableData) NumRows(m *ui.TableModel) int {
+ return mh.rowcount
+}
+
+// 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 {
+ return mh.generatedColumnTypes
+}
+
+// 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
+func (mh *tableData) CellValue(m *ui.TableModel, row, column int) ui.TableValue {
+ return mh.rows[row].cells[column].value
+}
+
+func (mh *tableData) SetCellValue(m *ui.TableModel, row, column int, value ui.TableValue) {
+ log.Println("SetCallValue() START row=", row, "column=", column, "value=", value)
+ // spew.Dump(m)
+ // spew.Dump(mh)
+ if (mh.libUIevent == nil) {
+ log.Println("CellValue NOT DEFINED. This table wasn't setup correctly! mh.scanCellValue == nil")
+ os.Exit(-1)
+ }
+ // spew.Dump(m)
+ mh.libUIevent(mh, m, row, column, value)
+ log.Println("SetCallValue() END")
+}