-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathwindow.go
99 lines (82 loc) · 2.58 KB
/
window.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"image"
"image/draw"
"sync"
"github.com/driusan/de/demodel"
"github.com/driusan/de/kbmap"
"github.com/driusan/de/renderer"
"github.com/driusan/de/viewer"
"golang.org/x/exp/shiny/screen"
"golang.org/x/mobile/event/size"
)
// dewindow encapsulates the shiny window of de.
type dewindow struct {
sync.Mutex
screen.Window
painting bool
buffer screen.Buffer
sz size.Event
}
func (w *dewindow) paint(buf *demodel.CharBuffer, viewport *viewer.Viewport) {
if w.painting {
return
}
w.realpaint(buf, viewport)
}
// paints buf into the viewport attached to this window
func (w *dewindow) realpaint(buf *demodel.CharBuffer, viewport *viewer.Viewport) {
w.Lock()
defer w.Unlock()
defer func() {
w.painting = false
}()
w.painting = true
if w.buffer == nil {
return
}
dst := w.buffer.RGBA()
// Fill the buffer with the window background colour before
// drawing the web page on top of it.
// This should logically be in the viewport code itself, but importing
// kbmap to switch on the mode sentinals would result in a cyclical
// import.
if viewport.BackgroundMode != viewer.StableBackground {
switch viewport.GetKeyboardMode() {
case kbmap.InsertMode:
draw.Draw(dst, dst.Bounds(), &image.Uniform{renderer.InsertBackground}, image.ZP, draw.Src)
case kbmap.DeleteMode:
draw.Draw(dst, dst.Bounds(), &image.Uniform{renderer.DeleteBackground}, image.ZP, draw.Src)
default:
draw.Draw(dst, dst.Bounds(), &image.Uniform{renderer.NormalBackground}, image.ZP, draw.Src)
}
} else {
draw.Draw(dst, dst.Bounds(), &image.Uniform{renderer.NormalBackground}, image.ZP, draw.Src)
}
s := w.sz.Size()
contentBounds := dst.Bounds()
tagBounds := tagSize
// ensure that the tag takes no more than half the window, so that the content doesn't get
// drowned out by commands that output more to stderr than they should.
if wHeight := s.Y; tagBounds.Max.Y > wHeight/2 {
tagBounds.Max.Y = wHeight / 2
}
contentBounds.Min.Y = tagBounds.Max.Y
tagline.RenderInto(dst.SubImage(image.Rectangle{image.ZP, image.Point{s.X, tagBounds.Max.Y}}).(*image.RGBA), buf.Tagline, clipRectangle(w.sz, viewport))
viewport.RenderInto(dst.SubImage(image.Rectangle{image.Point{0, tagBounds.Max.Y}, s}).(*image.RGBA), buf, clipRectangle(w.sz, viewport))
w.Upload(image.Point{0, 0}, w.buffer, dst.Bounds())
w.Publish()
return
}
func (w *dewindow) setSize(s size.Event, sc screen.Screen) error {
w.Lock()
defer w.Unlock()
w.sz = s
if w.buffer != nil {
// Release the old buffer.
w.buffer.Release()
}
sbuffer, err := sc.NewBuffer(s.Size())
w.buffer = sbuffer
return err
}