2014-07-08 09:00:16 -05:00
|
|
|
// 8 july 2014
|
|
|
|
|
|
|
|
package ui
|
|
|
|
|
|
|
|
// This file is called zz_test.go to keep it separate from the other files in this package (and because go test won't accept just test.go)
|
|
|
|
|
|
|
|
import (
|
2014-07-18 21:30:07 -05:00
|
|
|
"flag"
|
2014-10-02 09:05:53 -05:00
|
|
|
"fmt"
|
2014-08-04 22:31:11 -05:00
|
|
|
"image"
|
2014-08-04 22:48:04 -05:00
|
|
|
"image/color"
|
|
|
|
"image/draw"
|
2014-10-02 09:05:53 -05:00
|
|
|
"reflect"
|
2014-08-20 00:35:05 -05:00
|
|
|
"strings"
|
2014-10-02 09:05:53 -05:00
|
|
|
"testing"
|
|
|
|
"time"
|
2014-07-08 09:00:16 -05:00
|
|
|
)
|
|
|
|
|
2014-07-18 21:30:07 -05:00
|
|
|
var closeOnClick = flag.Bool("close", false, "close on click")
|
2014-08-11 11:21:19 -05:00
|
|
|
var smallWindow = flag.Bool("small", false, "open a small window (test Mac OS X initial control sizing)")
|
2014-10-11 19:16:38 -05:00
|
|
|
var spaced = flag.Bool("spaced", false, "enable spacing")
|
2014-07-18 21:30:07 -05:00
|
|
|
|
2014-07-28 16:59:50 -05:00
|
|
|
type dtype struct {
|
2014-10-02 09:05:53 -05:00
|
|
|
Name string
|
|
|
|
Address string
|
2014-07-28 16:59:50 -05:00
|
|
|
}
|
2014-10-02 09:05:53 -05:00
|
|
|
|
2014-07-28 16:59:50 -05:00
|
|
|
var ddata = []dtype{
|
2014-10-02 09:05:53 -05:00
|
|
|
{"alpha", "beta"},
|
|
|
|
{"gamma", "delta"},
|
|
|
|
{"epsilon", "zeta"},
|
|
|
|
{"eta", "theta"},
|
|
|
|
{"iota", "kappa"},
|
2014-07-28 16:59:50 -05:00
|
|
|
}
|
|
|
|
|
2014-07-28 22:55:52 -05:00
|
|
|
type testwin struct {
|
2014-10-02 09:05:53 -05:00
|
|
|
t Tab
|
|
|
|
w Window
|
|
|
|
repainter *repainter
|
|
|
|
fe *ForeignEvent
|
|
|
|
festack Stack
|
|
|
|
festart Button
|
|
|
|
felabel Label
|
|
|
|
festop Button
|
|
|
|
vedit TextField
|
|
|
|
openbtn Button
|
|
|
|
fnlabel Label
|
|
|
|
icons []icon
|
|
|
|
il ImageList
|
|
|
|
icontbl Table
|
|
|
|
group2 Group
|
|
|
|
group Group
|
|
|
|
simpleGrid SimpleGrid
|
|
|
|
nt Tab
|
|
|
|
a Area
|
|
|
|
spw Stack
|
|
|
|
sph Stack
|
|
|
|
s Stack
|
|
|
|
l Label
|
|
|
|
table Table
|
|
|
|
b Button
|
|
|
|
c Checkbox
|
|
|
|
e TextField
|
|
|
|
e2 TextField
|
2014-08-11 11:21:19 -05:00
|
|
|
|
2014-10-02 09:05:53 -05:00
|
|
|
wsmall Window
|
2014-07-28 22:55:52 -05:00
|
|
|
}
|
|
|
|
|
2014-08-21 04:37:24 -05:00
|
|
|
type areaHandler struct {
|
2014-10-02 09:05:53 -05:00
|
|
|
handled bool
|
2014-08-21 04:37:24 -05:00
|
|
|
}
|
2014-10-02 09:05:53 -05:00
|
|
|
|
2014-08-04 22:31:11 -05:00
|
|
|
func (a *areaHandler) Paint(r image.Rectangle) *image.RGBA {
|
2014-08-04 22:48:04 -05:00
|
|
|
i := image.NewRGBA(r)
|
2014-10-02 09:05:53 -05:00
|
|
|
draw.Draw(i, r, &image.Uniform{color.RGBA{128, 0, 128, 255}}, image.ZP, draw.Src)
|
2014-08-04 22:48:04 -05:00
|
|
|
return i
|
2014-08-04 22:31:11 -05:00
|
|
|
}
|
2014-10-02 09:05:53 -05:00
|
|
|
func (a *areaHandler) Mouse(me MouseEvent) { fmt.Printf("%#v\n", me) }
|
2014-08-21 04:37:24 -05:00
|
|
|
func (a *areaHandler) Key(ke KeyEvent) bool { fmt.Printf("%#v %q\n", ke, ke.Key); return a.handled }
|
2014-08-04 22:31:11 -05:00
|
|
|
|
2014-08-26 11:52:32 -05:00
|
|
|
func (tw *testwin) openFile(fn string) {
|
|
|
|
if fn == "" {
|
|
|
|
fn = "<no file selected>"
|
|
|
|
}
|
|
|
|
tw.fnlabel.SetText(fn)
|
|
|
|
}
|
|
|
|
|
2014-08-18 16:12:45 -05:00
|
|
|
func (tw *testwin) addfe() {
|
|
|
|
tw.festart = NewButton("Start")
|
|
|
|
tw.festart.OnClicked(func() {
|
|
|
|
if tw.fe != nil {
|
|
|
|
tw.fe.Stop()
|
|
|
|
}
|
|
|
|
ticker := time.NewTicker(1 * time.Second)
|
|
|
|
tw.fe = NewForeignEvent(ticker.C, func(d interface{}) {
|
|
|
|
t := d.(time.Time)
|
|
|
|
tw.felabel.SetText(t.String())
|
|
|
|
})
|
|
|
|
})
|
|
|
|
tw.felabel = NewStandaloneLabel("<stopped>")
|
|
|
|
tw.festop = NewButton("Stop")
|
|
|
|
tw.festop.OnClicked(func() {
|
|
|
|
if tw.fe != nil {
|
|
|
|
tw.fe.Stop()
|
|
|
|
tw.felabel.SetText("<stopped>")
|
|
|
|
tw.fe = nil
|
|
|
|
}
|
|
|
|
})
|
2014-08-20 00:35:05 -05:00
|
|
|
tw.vedit = NewTextField()
|
|
|
|
tw.vedit.OnChanged(func() {
|
|
|
|
if strings.Contains(tw.vedit.Text(), "bad") {
|
|
|
|
tw.vedit.Invalid("bad entered")
|
|
|
|
} else {
|
|
|
|
tw.vedit.Invalid("")
|
|
|
|
}
|
|
|
|
})
|
2014-08-18 18:01:56 -05:00
|
|
|
tw.openbtn = NewButton("Open")
|
|
|
|
tw.openbtn.OnClicked(func() {
|
2014-08-26 11:52:32 -05:00
|
|
|
OpenFile(tw.w, tw.openFile)
|
2014-08-18 18:01:56 -05:00
|
|
|
})
|
|
|
|
tw.fnlabel = NewStandaloneLabel("<no file selected>")
|
2014-08-28 09:30:53 -05:00
|
|
|
tw.festack = NewVerticalStack(tw.festart,
|
|
|
|
tw.felabel,
|
|
|
|
tw.festop,
|
|
|
|
NewCheckbox("This is a checkbox test"),
|
2014-08-20 00:35:05 -05:00
|
|
|
Space(),
|
|
|
|
tw.vedit,
|
2014-08-18 18:01:56 -05:00
|
|
|
Space(),
|
2014-08-28 09:30:53 -05:00
|
|
|
NewCheckbox("This is a checkbox test"),
|
2014-08-18 18:01:56 -05:00
|
|
|
tw.openbtn, tw.fnlabel)
|
2014-08-28 09:30:53 -05:00
|
|
|
tw.festack.SetStretchy(4)
|
|
|
|
tw.festack.SetStretchy(6)
|
|
|
|
tw.festack = NewHorizontalStack(tw.festack, Space())
|
|
|
|
tw.festack.SetStretchy(0)
|
|
|
|
tw.festack.SetStretchy(1)
|
2014-08-18 16:12:45 -05:00
|
|
|
tw.t.Append("Foreign Events", tw.festack)
|
|
|
|
}
|
|
|
|
|
2014-07-28 22:55:52 -05:00
|
|
|
func (tw *testwin) make(done chan struct{}) {
|
|
|
|
tw.t = NewTab()
|
|
|
|
tw.w = NewWindow("Hello", 320, 240, tw.t)
|
|
|
|
tw.w.OnClosing(func() bool {
|
|
|
|
if *closeOnClick {
|
|
|
|
panic("window closed normally in close on click mode (should not happen)")
|
|
|
|
}
|
|
|
|
println("window close event received")
|
|
|
|
Stop()
|
|
|
|
done <- struct{}{}
|
|
|
|
return true
|
|
|
|
})
|
2014-10-02 09:05:53 -05:00
|
|
|
tw.icons, tw.il = readIcons() // repainter uses these
|
2014-08-21 14:32:36 -05:00
|
|
|
tw.repainter = newRepainter(15)
|
2014-09-03 17:36:33 -05:00
|
|
|
tw.t.Append("Repaint", tw.repainter.grid)
|
2014-08-18 16:12:45 -05:00
|
|
|
tw.addfe()
|
2014-08-16 16:37:21 -05:00
|
|
|
tw.icontbl = NewTable(reflect.TypeOf(icon{}))
|
|
|
|
tw.icontbl.Lock()
|
|
|
|
idq := tw.icontbl.Data().(*[]icon)
|
|
|
|
*idq = tw.icons
|
|
|
|
tw.icontbl.Unlock()
|
|
|
|
tw.icontbl.LoadImageList(tw.il)
|
2014-08-20 20:21:45 -05:00
|
|
|
tw.icontbl.OnSelected(func() {
|
|
|
|
s := fmt.Sprintf("%d ", tw.icontbl.Selected())
|
|
|
|
tw.icontbl.RLock()
|
|
|
|
defer tw.icontbl.RUnlock()
|
|
|
|
idq := tw.icontbl.Data().(*[]icon)
|
|
|
|
for _, v := range *idq {
|
|
|
|
s += strings.ToUpper(fmt.Sprintf("%v", v.Bool)[0:1]) + " "
|
|
|
|
}
|
|
|
|
tw.w.SetTitle(s)
|
|
|
|
})
|
2014-08-16 16:37:21 -05:00
|
|
|
tw.t.Append("Image List Table", tw.icontbl)
|
2014-08-15 21:59:45 -05:00
|
|
|
tw.group2 = NewGroup("Group", NewButton("Button in Group"))
|
2014-08-28 10:18:49 -05:00
|
|
|
tw.t.Append("Empty Group", NewGroup("Group", Space()))
|
2014-08-15 21:59:45 -05:00
|
|
|
tw.t.Append("Filled Group", tw.group2)
|
2014-08-15 20:43:24 -05:00
|
|
|
tw.group = NewGroup("Group", NewVerticalStack(NewCheckbox("Checkbox in Group")))
|
|
|
|
tw.t.Append("Group", tw.group)
|
2014-08-31 12:02:47 -05:00
|
|
|
tw.simpleGrid = NewSimpleGrid(3,
|
2014-08-15 18:50:00 -05:00
|
|
|
NewLabel("0,0"), NewTextField(), NewLabel("0,2"),
|
|
|
|
NewButton("1,0"), NewButton("1,1"), NewButton("1,2"),
|
|
|
|
NewLabel("2,0"), NewTextField(), NewStandaloneLabel("2,2"))
|
2014-08-31 12:02:47 -05:00
|
|
|
tw.simpleGrid.SetFilling(2, 1)
|
|
|
|
tw.simpleGrid.SetFilling(1, 2)
|
|
|
|
tw.simpleGrid.SetStretchy(1, 1)
|
|
|
|
tw.t.Append("Simple Grid", tw.simpleGrid)
|
2014-08-08 21:28:58 -05:00
|
|
|
tw.t.Append("Blank Tab", NewTab())
|
|
|
|
tw.nt = NewTab()
|
|
|
|
tw.nt.Append("Tab 1", Space())
|
|
|
|
tw.nt.Append("Tab 2", Space())
|
|
|
|
tw.t.Append("Tab", tw.nt)
|
2014-08-06 20:34:31 -05:00
|
|
|
tw.t.Append("Space", Space())
|
2014-08-21 04:37:24 -05:00
|
|
|
tw.a = NewArea(200, 200, &areaHandler{false})
|
2014-08-04 22:31:11 -05:00
|
|
|
tw.t.Append("Area", tw.a)
|
2014-07-30 21:42:32 -05:00
|
|
|
tw.spw = NewHorizontalStack(
|
|
|
|
NewButton("hello"),
|
|
|
|
NewCheckbox("hello"),
|
|
|
|
NewTextField(),
|
|
|
|
NewPasswordField(),
|
2014-10-02 09:05:53 -05:00
|
|
|
NewTable(reflect.TypeOf(struct{ A, B, C int }{})),
|
2014-07-30 21:42:32 -05:00
|
|
|
NewStandaloneLabel("hello"))
|
|
|
|
tw.t.Append("Pref Width", tw.spw)
|
|
|
|
tw.sph = NewVerticalStack(
|
|
|
|
NewButton("hello"),
|
|
|
|
NewCheckbox("hello"),
|
|
|
|
NewTextField(),
|
|
|
|
NewPasswordField(),
|
2014-10-02 09:05:53 -05:00
|
|
|
NewTable(reflect.TypeOf(struct{ A, B, C int }{})),
|
2014-08-08 22:47:06 -05:00
|
|
|
NewStandaloneLabel("hello ÉÀÔ"))
|
2014-07-30 21:42:32 -05:00
|
|
|
tw.t.Append("Pref Height", tw.sph)
|
2014-07-29 22:23:45 -05:00
|
|
|
stack1 := NewHorizontalStack(NewLabel("Test"), NewTextField())
|
|
|
|
stack1.SetStretchy(1)
|
2014-08-08 22:47:06 -05:00
|
|
|
stack2 := NewHorizontalStack(NewLabel("ÉÀÔ"), NewTextField())
|
2014-07-29 22:23:45 -05:00
|
|
|
stack2.SetStretchy(1)
|
2014-08-08 22:47:06 -05:00
|
|
|
stack3 := NewHorizontalStack(NewLabel("Test 2"),
|
2014-10-02 09:05:53 -05:00
|
|
|
NewTable(reflect.TypeOf(struct{ A, B, C int }{})))
|
2014-08-08 22:47:06 -05:00
|
|
|
stack3.SetStretchy(1)
|
|
|
|
tw.s = NewVerticalStack(stack1, stack2, stack3)
|
|
|
|
tw.s.SetStretchy(2)
|
2014-07-29 22:23:45 -05:00
|
|
|
tw.t.Append("Stack", tw.s)
|
2014-07-29 12:48:31 -05:00
|
|
|
tw.l = NewStandaloneLabel("hello")
|
|
|
|
tw.t.Append("Label", tw.l)
|
2014-07-28 22:55:52 -05:00
|
|
|
tw.table = NewTable(reflect.TypeOf(ddata[0]))
|
|
|
|
tw.table.Lock()
|
|
|
|
dq := tw.table.Data().(*[]dtype)
|
|
|
|
*dq = ddata
|
|
|
|
tw.table.Unlock()
|
|
|
|
tw.t.Append("Table", tw.table)
|
|
|
|
tw.b = NewButton("There")
|
|
|
|
if *closeOnClick {
|
|
|
|
tw.b.SetText("Click to Close")
|
|
|
|
}
|
|
|
|
tw.b.OnClicked(func() {
|
|
|
|
println("in OnClicked()")
|
|
|
|
if *closeOnClick {
|
|
|
|
tw.w.Close()
|
|
|
|
Stop()
|
|
|
|
done <- struct{}{}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
tw.t.Append("Button", tw.b)
|
|
|
|
tw.c = NewCheckbox("You Should Now See Me Instead")
|
2014-08-03 08:13:25 -05:00
|
|
|
tw.c.OnToggled(func() {
|
2014-07-28 22:55:52 -05:00
|
|
|
tw.w.SetTitle(fmt.Sprint(tw.c.Checked()))
|
|
|
|
})
|
|
|
|
tw.t.Append("Checkbox", tw.c)
|
|
|
|
tw.e = NewTextField()
|
|
|
|
tw.t.Append("Text Field", tw.e)
|
|
|
|
tw.e2 = NewPasswordField()
|
2014-07-29 00:40:17 -05:00
|
|
|
tw.t.Append("Password Field", tw.e2)
|
2014-07-28 22:55:52 -05:00
|
|
|
tw.w.Show()
|
2014-08-11 11:21:19 -05:00
|
|
|
if *smallWindow {
|
|
|
|
tw.wsmall = NewWindow("Small", 80, 80,
|
|
|
|
NewVerticalStack(
|
|
|
|
NewButton("Small"),
|
2014-08-14 22:43:43 -05:00
|
|
|
NewButton("Small 2"),
|
2014-08-21 04:37:24 -05:00
|
|
|
NewArea(200, 200, &areaHandler{true})))
|
2014-08-11 11:21:19 -05:00
|
|
|
tw.wsmall.Show()
|
|
|
|
}
|
2014-07-28 22:55:52 -05:00
|
|
|
}
|
|
|
|
|
2014-08-13 08:57:22 -05:00
|
|
|
// this must be on the heap thanks to moving stacks
|
|
|
|
// soon even this won't be enough...
|
|
|
|
var tw *testwin
|
|
|
|
|
2014-07-08 15:47:28 -05:00
|
|
|
// because Cocoa hates being run off the main thread, even if it's run exclusively off the main thread
|
|
|
|
func init() {
|
2014-07-18 21:30:07 -05:00
|
|
|
flag.Parse()
|
2014-07-19 09:16:00 -05:00
|
|
|
go func() {
|
2014-08-13 08:57:22 -05:00
|
|
|
tw = new(testwin)
|
2014-07-08 09:00:16 -05:00
|
|
|
done := make(chan struct{})
|
2014-07-28 22:55:52 -05:00
|
|
|
Do(func() { tw.make(done) })
|
2014-07-08 09:00:16 -05:00
|
|
|
<-done
|
2014-07-19 09:16:00 -05:00
|
|
|
}()
|
2014-07-08 09:00:16 -05:00
|
|
|
err := Go()
|
|
|
|
if err != nil {
|
2014-07-08 15:47:28 -05:00
|
|
|
panic(err)
|
2014-07-08 09:00:16 -05:00
|
|
|
}
|
|
|
|
}
|
2014-07-08 15:47:28 -05:00
|
|
|
|
|
|
|
func TestDummy(t *testing.T) {
|
|
|
|
// do nothing
|
|
|
|
}
|