diff options
| author | faiface <faiface@ksp.sk> | 2017-08-29 00:35:28 +0200 |
|---|---|---|
| committer | faiface <faiface@ksp.sk> | 2017-08-29 00:35:28 +0200 |
| commit | 09db3d0b721685fda1cee71833ec4dd0fe1b4c9a (patch) | |
| tree | 7473dfeb9d1b4664c25be1e7cc939a804855c650 /layout | |
| parent | 0c433c89a218c428cbc6dc093d4b4d6dd8174114 (diff) | |
| download | gui-09db3d0b721685fda1cee71833ec4dd0fe1b4c9a.zip | |
start over, concurrency full on
Diffstat (limited to 'layout')
| -rw-r--r-- | layout/interface.go | 40 | ||||
| -rw-r--r-- | layout/layer.go | 118 | ||||
| -rw-r--r-- | layout/split.go | 163 |
3 files changed, 40 insertions, 281 deletions
diff --git a/layout/interface.go b/layout/interface.go new file mode 100644 index 0000000..1dcf34a --- /dev/null +++ b/layout/interface.go @@ -0,0 +1,40 @@ +package layout + +import ( + "fmt" + "image" + "image/draw" +) + +type EventDrawer interface { + Event() <-chan EventConsume + Draw() chan<- ImageFlush +} + +type EventConsume struct { + Event string + Consume chan<- bool +} + +func SendEvent(ch chan<- EventConsume, format string, a ...interface{}) (consume <-chan bool) { + cons := make(chan bool) + ch <- EventConsume{fmt.Sprintf(format, a...), cons} + return cons +} + +func (ec EventConsume) Matches(format string, a ...interface{}) bool { + _, err := fmt.Sscanf(ec.Event, format, a...) + return err == nil +} + +type ImageFlush struct { + Image chan<- draw.Image + Flush <-chan image.Rectangle +} + +func SendDraw(ch chan<- ImageFlush) (img <-chan draw.Image, flush chan<- image.Rectangle) { + imgC := make(chan draw.Image) + flushC := make(chan image.Rectangle) + ch <- ImageFlush{imgC, flushC} + return imgC, flushC +} diff --git a/layout/layer.go b/layout/layer.go deleted file mode 100644 index 42000a5..0000000 --- a/layout/layer.go +++ /dev/null @@ -1,118 +0,0 @@ -package layout - -import ( - "container/list" - "errors" - "image" - "image/draw" - - "github.com/faiface/gui/event" -) - -type EventImageFlusher interface { - Event(pattern string, handler func(event string) bool) - Image() *image.RGBA - Flush(r image.Rectangle) -} - -type LayerList struct { - event.Dispatch - dst EventImageFlusher - layers list.List -} - -func NewLayerList(dst EventImageFlusher) *LayerList { - l := &LayerList{dst: dst} - - dst.Event("", l.Happen) - - l.Event("resize", func(evt string) bool { - var x1, y1, x2, y2 int - event.Sscan(evt, &x1, &y1, &x2, &y2) - - for e := l.layers.Back(); e != nil; e = e.Prev() { - layer := e.Value.(*Layer) - rgba := image.NewRGBA(dst.Image().Bounds()) - draw.Draw(rgba, layer.rgba.Bounds(), layer.rgba, layer.rgba.Bounds().Min, draw.Src) - layer.rgba = rgba - } - - return false - }) - - r := dst.Image().Bounds() - l.Happen(event.Sprint("resize", r.Min.X, r.Min.Y, r.Max.X, r.Max.Y)) - - return l -} - -func (l *LayerList) Add() *Layer { - layer := &Layer{ - lst: l, - rgba: image.NewRGBA(l.dst.Image().Bounds()), - } - layer.elm = l.layers.PushFront(layer) - return layer -} - -func (l *LayerList) Remove(layer *Layer) { - if layer.lst == nil { - panic(errors.New("layer: Remove: layer already removed")) - } - l.layers.Remove(layer.elm) - layer.lst = nil -} - -func (l *LayerList) Front(layer *Layer) { - if layer.lst == nil { - panic(errors.New("layer: Front: layer removed")) - } - l.layers.MoveToFront(layer.elm) -} - -func (l *LayerList) Happen(event string) bool { - if l.Dispatch.Happen(event) { - return true - } - for e := l.layers.Front(); e != nil; e = e.Next() { - layer := e.Value.(*Layer) - if layer.Happen(event) { - return true - } - } - return false -} - -func (l *LayerList) Flush(r image.Rectangle) { - if l.dst == nil { - panic(errors.New("layer: Flush: no destination")) - } - draw.Draw(l.dst.Image(), r, image.Transparent, r.Min, draw.Src) - for e := l.layers.Back(); e != nil; e = e.Prev() { - layer := e.Value.(*Layer) - draw.Draw(l.dst.Image(), r, layer.rgba, r.Min, draw.Over) - } - l.dst.Flush(r) -} - -type Layer struct { - event.Dispatch - lst *LayerList - elm *list.Element - rgba *image.RGBA -} - -func (l *Layer) List() *LayerList { - return l.lst -} - -func (l *Layer) Image() *image.RGBA { - return l.rgba -} - -func (l *Layer) Flush(r image.Rectangle) { - if l.lst == nil { - panic(errors.New("layer: Flush: layer removed")) - } - l.lst.Flush(r) -} diff --git a/layout/split.go b/layout/split.go deleted file mode 100644 index 90c4a0a..0000000 --- a/layout/split.go +++ /dev/null @@ -1,163 +0,0 @@ -package layout - -import ( - "image" - - "github.com/faiface/gui/event" -) - -type Box struct { - event.Dispatch - dst EventImageFlusher - sub *image.RGBA -} - -func (b *Box) Image() *image.RGBA { - return b.sub -} - -func (b *Box) Flush(r image.Rectangle) { - r = r.Intersect(b.sub.Bounds()) - b.dst.Flush(r) -} - -type Splitter func(r image.Rectangle, i, n int) image.Rectangle - -func Vertical() Splitter { - return func(r image.Rectangle, i, n int) image.Rectangle { - width := r.Dx() - return image.Rect( - r.Min.X+width*i/n, - r.Min.Y, - r.Min.X+width*(i+1)/n, - r.Max.Y, - ) - } -} - -func Horizontal() Splitter { - return func(r image.Rectangle, i, n int) image.Rectangle { - height := r.Dy() - return image.Rect( - r.Min.X, - r.Min.Y+height*i/n, - r.Max.X, - r.Min.Y+height*(i+1)/n, - ) - } -} - -func FixedTop(thickness int, rest Splitter) Splitter { - return VariableTop(&thickness, rest) -} - -func FixedBottom(thickness int, rest Splitter) Splitter { - return VariableBottom(&thickness, rest) -} - -func FixedLeft(thickness int, rest Splitter) Splitter { - return VariableLeft(&thickness, rest) -} - -func FixedRight(thickness int, rest Splitter) Splitter { - return VariableRight(&thickness, rest) -} - -func VariableTop(thickness *int, rest Splitter) Splitter { - return func(r image.Rectangle, i, n int) image.Rectangle { - if i == 0 { - r.Max.Y = r.Min.Y + *thickness - return r - } - r.Min.Y += *thickness - return rest(r, i-1, n-1) - } -} - -func VariableBottom(thickness *int, rest Splitter) Splitter { - return func(r image.Rectangle, i, n int) image.Rectangle { - if i == 0 { - r.Min.Y = r.Max.Y - *thickness - return r - } - r.Max.Y -= *thickness - return rest(r, i-1, n-1) - } -} - -func VariableLeft(thickness *int, rest Splitter) Splitter { - return func(r image.Rectangle, i, n int) image.Rectangle { - if i == 0 { - r.Max.X = r.Min.X + *thickness - return r - } - r.Min.X += *thickness - return rest(r, i-1, n-1) - } -} - -func VariableRight(thickness *int, rest Splitter) Splitter { - return func(r image.Rectangle, i, n int) image.Rectangle { - if i == 0 { - r.Min.X = r.Max.X - *thickness - return r - } - r.Max.X -= *thickness - return rest(r, i-1, n-1) - } -} - -type Split struct { - event.Dispatch - dst EventImageFlusher - splitter Splitter - boxes []*Box -} - -func NewSplit(dst EventImageFlusher, splitter Splitter) *Split { - s := &Split{ - dst: dst, - splitter: splitter, - } - s.Event("resize", func(string) bool { - s.Split() - s.dst.Flush(s.dst.Image().Bounds()) - return true - }) - dst.Event("", s.Happen) - return s -} - -func (s *Split) Happen(evt string) bool { - if s.Dispatch.Happen(evt) { - return true - } - for _, box := range s.boxes { - if box.Happen(evt) { - return true - } - } - return false -} - -func (s *Split) Add() *Box { - box := &Box{ - dst: s.dst, - } - s.boxes = append(s.boxes, box) - s.Split() - return box -} - -func (s *Split) Split() { - r := s.dst.Image().Bounds() - n := len(s.boxes) - for i := range s.boxes { - subR := s.splitter(r, i, n) - s.boxes[i].sub = s.dst.Image().SubImage(subR).(*image.RGBA) - } - for _, box := range s.boxes { - subR := box.sub.Bounds() - box.Happen(event.Sprint("resize", subR.Min.X, subR.Min.Y, subR.Max.X, subR.Max.Y)) - } -} |