package control9 import ( "bitbucket.org/mischief/draw9" "bufio" "fmt" "image" "strings") type Controlset struct { controls []Control screen *draw9.Image active []Control focus Control ctl chan string data chan string kbdc chan rune mousec chan draw9.Mouse resizec chan int resizeexitc chan int OnResize func(cs *Controlset) csexitc chan int kbd *draw9.Consctl ms *draw9.Mousectl clicktotype bool} func NewControlset(screen *draw9.Image, kbd *draw9.Consctl, ms *draw9.Mousectl) (*Controlset, error) { if screen == nil { return nil, fmt.Errorf("nil screen") } if kbd == nil { } if ms == nil { } cs := &Controlset{ screen: screen, ctl: make(chan string, 64), data: make(chan string, 64), kbdc: kbd.C, mousec: ms.C, resizec: ms.Resize, resizeexitc: make(chan int), csexitc: make(chan int), kbd: kbd, ms: ms, } go cs.resize() go cs.cs() return cs, nil} // Called looks up a child control by name.func (cs *Controlset) Called(name string) Control { for _, c := range cs.controls { if c.Name() == name { return c } } return nil} func (cs *Controlset) newctl(name string, typ ControlType) *BaseControl { bc := &BaseControl{ name: name, size: image.Rect(1, 1, 10000, 10000), //rect: image.Rect(1, 1, 100, 100), // event: make(chan string, 64), data: make(chan string, 0), typ: typ, hidden: false, set: cs, screen: cs.screen, } return bc} func (cs *Controlset) addctl(c Control) { cs.controls = append(cs.controls, c) cs.active = append(cs.active, c)} func (cs *Controlset) Ctl(s string) { cs.ctl <- s} func (cs *Controlset) cmd(s string) { f := strings.Fields(s) for _, c := range cs.controls { if c.Name() == f[0] { c.Ctl(strings.Join(f[1:], " ")) } }} func (cs *Controlset) onctl(s string) { sc := bufio.NewScanner(strings.NewReader(s)) for sc.Scan() { cs.cmd(sc.Text()) }} func (cs *Controlset) Resize() { if cs.OnResize != nil { cs.OnResize(cs) }} func (cs *Controlset) resize() { for { select { case <-cs.resizec: cs.Resize() case <-cs.resizeexitc: return } }} func (cs *Controlset) cs() { prevbut := 0 for { select { case r := <-cs.kbdc: if cs.focus != nil { cs.focus.Key(r) } case ms := <-cs.mousec: if prevbut > 0 { goto Send } if cs.focus != nil && cs.focus.Hidden() == false && ms.Pt().In(cs.focus.Rect()) == true { goto Send } if cs.clicktotype { goto Change } if !ms.Any() { goto Send } Change: /* change focus */ if cs.focus != nil { cs.focus.Ctl("focus 0") } cs.focus = nil for _, c := range cs.active { if c.Hidden() == false && ms.Pt().In(c.Rect()) == true { cs.focus = c c.Ctl("focus 1") c.Mouse(ms) break } } Send: /* send mouse */ if cs.focus != nil { cs.focus.Mouse(ms) } prevbut = ms.Buttons() case s := <-cs.ctl: cs.onctl(s) case <-cs.csexitc: /* fixme */ return } }} func (cs *Controlset) Screen(sc *draw9.Image){ *cs.screen = *sc}
package control9
import (
"bitbucket.org/mischief/draw9"
"bufio"
"fmt"
"image"
"strings"
)
type Controlset struct {
controls []Control
screen *draw9.Image
active []Control
focus Control
ctl chan string
data chan string
kbdc chan rune
mousec chan draw9.Mouse
resizec chan int
resizeexitc chan int
OnResize func(cs *Controlset)
csexitc chan int
kbd *draw9.Consctl
ms *draw9.Mousectl
clicktotype bool
}
func NewControlset(screen *draw9.Image, kbd *draw9.Consctl, ms *draw9.Mousectl) (*Controlset, error) {
if screen == nil {
return nil, fmt.Errorf("nil screen")
}
if kbd == nil {
}
if ms == nil {
}
cs := &Controlset{
screen: screen,
ctl: make(chan string, 64),
data: make(chan string, 64),
kbdc: kbd.C,
mousec: ms.C,
resizec: ms.Resize,
resizeexitc: make(chan int),
csexitc: make(chan int),
kbd: kbd,
ms: ms,
}
go cs.resize()
go cs.cs()
return cs, nil
}
// Called looks up a child control by name.
func (cs *Controlset) Called(name string) Control {
for _, c := range cs.controls {
if c.Name() == name {
return c
}
}
return nil
}
func (cs *Controlset) newctl(name string, typ ControlType) *BaseControl {
bc := &BaseControl{
name: name,
size: image.Rect(1, 1, 10000, 10000),
//rect: image.Rect(1, 1, 100, 100),
// event: make(chan string, 64),
data: make(chan string, 0),
typ: typ,
hidden: false,
set: cs,
screen: cs.screen,
}
return bc
}
func (cs *Controlset) addctl(c Control) {
cs.controls = append(cs.controls, c)
cs.active = append(cs.active, c)
}
func (cs *Controlset) Ctl(s string) {
cs.ctl <- s
}
func (cs *Controlset) cmd(s string) {
f := strings.Fields(s)
for _, c := range cs.controls {
if c.Name() == f[0] {
c.Ctl(strings.Join(f[1:], " "))
}
}
}
func (cs *Controlset) onctl(s string) {
sc := bufio.NewScanner(strings.NewReader(s))
for sc.Scan() {
cs.cmd(sc.Text())
}
}
func (cs *Controlset) Resize() {
if cs.OnResize != nil {
cs.OnResize(cs)
}
}
func (cs *Controlset) resize() {
for {
select {
case <-cs.resizec:
cs.Resize()
case <-cs.resizeexitc:
return
}
}
}
func (cs *Controlset) cs() {
prevbut := 0
for {
select {
case r := <-cs.kbdc:
if cs.focus != nil {
cs.focus.Key(r)
}
case ms := <-cs.mousec:
if prevbut > 0 {
goto Send
}
if cs.focus != nil && cs.focus.Hidden() == false && ms.Pt().In(cs.focus.Rect()) == true {
goto Send
}
if cs.clicktotype {
goto Change
}
if !ms.Any() {
goto Send
}
Change:
/* change focus */
if cs.focus != nil {
cs.focus.Ctl("focus 0")
}
cs.focus = nil
for _, c := range cs.active {
if c.Hidden() == false && ms.Pt().In(c.Rect()) == true {
cs.focus = c
c.Ctl("focus 1")
c.Mouse(ms)
break
}
}
Send:
/* send mouse */
if cs.focus != nil {
cs.focus.Mouse(ms)
}
prevbut = ms.Buttons()
case s := <-cs.ctl:
cs.onctl(s)
case <-cs.csexitc:
/* fixme */
return
}
}
}
func (cs *Controlset) Screen(sc *draw9.Image){
*cs.screen = *sc
}