180 lines · 3.1 KB · Go
RawDownload
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}