github.com/as/shiny@v0.8.2/screen/screen.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package screen // import "github.com/as/shiny/screen" 6 7 import ( 8 "image" 9 "image/color" 10 "image/draw" 11 "unicode/utf8" 12 13 "github.com/as/shiny/event/key" 14 "github.com/as/shiny/event/lifecycle" 15 "github.com/as/shiny/event/mouse" 16 "github.com/as/shiny/event/paint" 17 "github.com/as/shiny/event/size" 18 "github.com/as/shiny/math/f64" 19 ) 20 21 // Screen creates Buffers, Textures and Windows. 22 type Screen interface { 23 NewBuffer(size image.Point) (Buffer, error) 24 NewTexture(size image.Point) (Texture, error) 25 NewWindow(opts *NewWindowOptions) (Window, error) 26 } 27 28 type Buffer interface { 29 Release() 30 Size() image.Point 31 Bounds() image.Rectangle 32 RGBA() *image.RGBA 33 } 34 35 type Texture interface { 36 Release() 37 Size() image.Point 38 Bounds() image.Rectangle 39 Uploader 40 } 41 42 // Window is a top-level, double-buffered GUI window. 43 type Window interface { 44 Device() *Device 45 Release() 46 Uploader 47 Drawer 48 Publish() PublishResult 49 } 50 51 type ( 52 Lifecycle = lifecycle.Event 53 Scroll = mouse.Event 54 Mouse = mouse.Event 55 Key = key.Event 56 Size = size.Event 57 Paint = paint.Event 58 ) 59 60 var Dev = &Device{ 61 Scroll: make(chan Scroll, 1), 62 Mouse: make(chan Mouse, 1), 63 Key: make(chan Key, 1), 64 Size: make(chan Size, 1), 65 Paint: make(chan Paint, 1), 66 Lifecycle: make(chan Lifecycle, 1), 67 } 68 69 type Device struct { 70 Lifecycle chan Lifecycle 71 Scroll chan Scroll 72 Mouse chan Mouse 73 Key chan Key 74 Size chan Size 75 Paint chan Paint 76 } 77 78 func SendMouse(e Mouse) { 79 select { 80 case Dev.Mouse <- e: 81 default: 82 // TODO: Retry on failure, but only if it's a press or release 83 // note that this may hang the user, so a better fix should be 84 // in order 85 if e.Button != mouse.ButtonNone && e.Direction != mouse.DirNone { 86 Dev.Mouse <- e 87 } 88 } 89 } 90 91 func SendKey(e Key) { 92 select { 93 case Dev.Key <- e: 94 } 95 } 96 97 func SendSize(e Size) { 98 select { 99 case Dev.Size <- e: 100 default: 101 } 102 } 103 104 func SendPaint(e Paint) { 105 select { 106 case Dev.Paint <- e: 107 default: 108 } 109 } 110 111 func SendScroll(e Scroll) { 112 for { 113 select { 114 case Dev.Scroll <- e: 115 return 116 default: 117 select { 118 case <-Dev.Scroll: 119 default: 120 } 121 } 122 } 123 } 124 125 func SendLifecycle(e Lifecycle) { 126 select { 127 case Dev.Lifecycle <- e: 128 } 129 130 } 131 132 // PublishResult is the result of an Window.Publish call. 133 type PublishResult struct { 134 BackBufferPreserved bool 135 } 136 137 // NewWindowOptions are optional arguments to NewWindow. 138 // TODO(as): NewWindowOptions could be named better 139 type NewWindowOptions struct { 140 Width, Height int 141 Title string 142 143 // Overlay, if true, attempts to create a new window over top 144 // of the parent process's existing window (similar to running 145 // a graphical application in Plan9 over top an existing Rio 146 // window). 147 Overlay bool 148 } 149 150 func (o *NewWindowOptions) GetTitle() string { 151 if o == nil { 152 return "" 153 } 154 return sanitizeUTF8(o.Title, 4096) 155 } 156 157 func sanitizeUTF8(s string, n int) string { 158 if n < len(s) { 159 s = s[:n] 160 } 161 i := 0 162 for i < len(s) { 163 r, n := utf8.DecodeRuneInString(s[i:]) 164 if r == 0 || (r == utf8.RuneError && n == 1) { 165 break 166 } 167 i += n 168 } 169 return s[:i] 170 } 171 172 // Uploader is something you can upload a Buffer to. 173 type Uploader interface { 174 Upload(dp image.Point, src Buffer, sr image.Rectangle) 175 Fill(dr image.Rectangle, src color.Color, op draw.Op) 176 } 177 178 type Drawer interface { 179 Draw(src2dst f64.Aff3, src Texture, sr image.Rectangle, op draw.Op, opts *DrawOptions) 180 DrawUniform(src2dst f64.Aff3, src color.Color, sr image.Rectangle, op draw.Op, opts *DrawOptions) 181 Copy(dp image.Point, src Texture, sr image.Rectangle, op draw.Op, opts *DrawOptions) 182 Scale(dr image.Rectangle, src Texture, sr image.Rectangle, op draw.Op, opts *DrawOptions) 183 } 184 185 const ( 186 Over = draw.Over 187 Src = draw.Src 188 ) 189 190 type DrawOptions struct { 191 }