summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-07-28 17:59:50 -0400
committerPietro Gagliardi <[email protected]>2014-07-28 17:59:50 -0400
commit0b82f37bcbf9c53392f8aa7309cf6a2c5b3e5375 (patch)
tree750b92e3ee67dc0acab91e121926befbc9d247b0
parent286704beddf7a4b3bf5bcdfa7a7ea4e32110d7d3 (diff)
Added the basic Table interface. Now to implement it...
-rw-r--r--redo/table.go66
-rw-r--r--redo/zz_test.go18
2 files changed, 84 insertions, 0 deletions
diff --git a/redo/table.go b/redo/table.go
new file mode 100644
index 0000000..f6f78d5
--- /dev/null
+++ b/redo/table.go
@@ -0,0 +1,66 @@
+// 28 july 2014
+
+package ui
+
+import (
+ "fmt"
+ "reflect"
+ "sync"
+)
+
+// Table is a Control that displays a list of like-structured data in a grid where each row represents an item and each column represents a bit of data.
+// As such, a Table renders a []struct{...} where each field of the struct can be a string, a number, [TODO an image, or a checkbox].
+// Tables maintain their own storage behind a sync.RWMutex-compatible sync.Locker; use Table.Lock()/Table.Unlock() to make changes and Table.RLock()/Table.RUnlock() to merely read values.
+// TODO headers
+type Table interface {
+ // Lock and Unlock lock and unlock Data for reading or writing.
+ // RLock and RUnlock lock and unlock Data for reading only.
+ // These methods have identical semantics to the analogous methods of sync.RWMutex.
+ Lock()
+ Unlock()
+ RLock()
+ RUnlock()
+
+ // Data returns the internal data.
+ // The returned value will contain an object of type pointer to slice of some structure; use a type assertion to get the properly typed object out.
+ // Do not call this outside a Lock()..Unlock() or RLock()..RUnlock() pair.
+ Data() interface{}
+}
+
+type tablebase struct {
+ lock sync.RWMutex
+ data interface{}
+}
+
+// NewTable creates a new Table.
+// Currently, the argument must be a reflect.Type representing the structure that each item in the Table will hold, and the Table will be initially empty.
+// This will change in the future.
+func NewTable(ty reflect.Type) Table {
+ if ty.Kind() != reflect.Struct {
+ panic(fmt.Errorf("unknown or unsupported type %v given to NewTable()", ty))
+ }
+ b := new(tablebase)
+ // arbitrary starting capacity
+ b.data = reflect.NewSlice(ty, 0, 512).Addr().Interface()
+ return finishNewTable(b)
+}
+
+func (b *tablebase) Lock() {
+ b.lock.Lock()
+}
+
+func (b *tablebase) Unlock() {
+ b.lock.Unlock()
+}
+
+func (b *tablebase) RLock() {
+ b.lock.RLock()
+}
+
+func (b *tablebase) RUnlock() {
+ b.lock.RUnlock()
+}
+
+func (b *tablebase) Data() {
+ return b.data
+}
diff --git a/redo/zz_test.go b/redo/zz_test.go
index 5fc821e..327aec2 100644
--- a/redo/zz_test.go
+++ b/redo/zz_test.go
@@ -12,6 +12,18 @@ import (
var closeOnClick = flag.Bool("close", false, "close on click")
+type dtype struct {
+ Name string
+ Address string
+}
+var ddata = []dtype{
+ { "alpha", "beta" },
+ { "gamma", "delta" },
+ { "epsilon", "zeta" },
+ { "eta", "theta" },
+ { "iota", "kappa" },
+}
+
// because Cocoa hates being run off the main thread, even if it's run exclusively off the main thread
func init() {
flag.BoolVar(&spaced, "spaced", false, "enable spacing")
@@ -30,6 +42,12 @@ func init() {
done <- struct{}{}
return true
})
+ table := NewTable(reflect.TypeOf(ddata[0]))
+ table.Lock()
+ dq := table.Data().(*[]dtype)
+ *dq = ddata
+ table.Unlock()
+ t.Append("Table", table)
b := NewButton("There")
if *closeOnClick {
b.SetText("Click to Close")