Documentation

Overview

    Package screen provides interfaces for portable two-dimensional graphics and input events.

    Screens are not created directly. Instead, driver packages provide access to the screen through a Main function that is designed to be called by the program's main function. The golang.org/x/exp/shiny/driver package provides the default driver for the system, such as the X11 driver for desktop Linux, but other drivers, such as the OpenGL driver, can be explicitly invoked by calling that driver's Main function. To use the default driver:

    package main
    
    import (
    	"github.com/oakmound/shiny/driver"
    	"github.com/oakmound/shiny/screen"
    	"golang.org/x/mobile/event/lifecycle"
    )
    
    func main() {
    	driver.Main(func(s screen.Screen) {
    		w, err := s.NewWindow(nil)
    		if err != nil {
    			handleError(err)
    			return
    		}
    		defer w.Release()
    
    		for {
    			switch e := w.NextEvent().(type) {
    			case lifecycle.Event:
    				if e.To == lifecycle.StageDead {
    					return
    				}
    				etc
    			case etc:
    				etc
    			}
    		}
    	})
    }
    

    Complete examples can be found in the shiny/example directory.

    Each driver package provides Screen, Image, Texture and Window implementations that work together. Such types are interface types because this package is driver-independent, but those interfaces aren't expected to be implemented outside of drivers. For example, a driver's Window implementation will generally work only with that driver's Image implementation, and will not work with an arbitrary type that happens to implement the Image methods.

    Index

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    This section is empty.

    Types

    type Drawer

    type Drawer interface {
    	// Draw draws the sub-Texture defined by src and sr to the destination (the
    	// method receiver). src2dst defines how to transform src coordinates to
    	// dst coordinates. For example, if src2dst is the matrix
    	//
    	// m00 m01 m02
    	// m10 m11 m12
    	//
    	// then the src-space point (sx, sy) maps to the dst-space point
    	// (m00*sx + m01*sy + m02, m10*sx + m11*sy + m12).
    	Draw(src2dst f64.Aff3, src Texture, sr image.Rectangle, op draw.Op)
    
    	// DrawUniform is like Draw except that the src is a uniform color instead
    	// of a Texture.
    	DrawUniform(src2dst f64.Aff3, src color.Color, sr image.Rectangle, op draw.Op)
    
    	// Copy copies the sub-Texture defined by src and sr to the destination
    	// (the method receiver), such that sr.Min in src-space aligns with dp in
    	// dst-space.
    	Copy(dp image.Point, src Texture, sr image.Rectangle, op draw.Op)
    
    	// Scale scales the sub-Texture defined by src and sr to the destination
    	// (the method receiver), such that sr in src-space is mapped to dr in
    	// dst-space.
    	Scale(dr image.Rectangle, src Texture, sr image.Rectangle, op draw.Op)
    
    	// Upload uploads the sub-Buffer defined by src and sr to the destination
    	// (the method receiver), such that sr.Min in src-space aligns with dp in
    	// dst-space. The destination's contents are overwritten; the draw operator
    	// is implicitly draw.Src.
    	//
    	// It is valid to upload a Buffer while another upload of the same Buffer
    	// is in progress, but a Buffer's image.RGBA pixel contents should not be
    	// accessed while it is uploading. A Buffer is re-usable, in that its pixel
    	// contents can be further modified, once all outstanding calls to Upload
    	// have returned.
    	//
    	// TODO: make it optional that a Buffer's contents is preserved after
    	// Upload? Undoing a swizzle is a non-trivial amount of work, and can be
    	// redundant if the next paint cycle starts by clearing the buffer.
    	//
    	// When uploading to a Window, there will not be any visible effect until
    	// Publish is called.
    	Upload(dp image.Point, src Image, sr image.Rectangle)
    
    	// Fill fills that part of the destination (the method receiver) defined by
    	// dr with the given color.
    	//
    	// When filling a Window, there will not be any visible effect until
    	// Publish is called.
    	Fill(dr image.Rectangle, src color.Color, op draw.Op)
    }

      Drawer is something you can draw Textures on.

      Draw is the most general purpose of this interface's methods. It supports arbitrary affine transformations, such as translations, scales and rotations.

      Copy and Scale are more specific versions of Draw. The affected dst pixels are an axis-aligned rectangle, quantized to the pixel grid. Copy copies pixels in a 1:1 manner, Scale is more general. They have simpler parameters than Draw, using ints instead of float64s.

      When drawing on a Window, there will not be any visible effect until Publish is called.

      type EventDeque

      type EventDeque interface {
      	// Send adds an event to the end of the deque. They are returned by
      	// NextEvent in FIFO order.
      	Send(event interface{})
      
      	// SendFirst adds an event to the start of the deque. They are returned by
      	// NextEvent in LIFO order, and have priority over events sent via Send.
      	SendFirst(event interface{})
      
      	// NextEvent returns the next event in the deque. It blocks until such an
      	// event has been sent.
      	//
      	// Typical event types include:
      	//	- lifecycle.Event
      	//	- size.Event
      	//	- paint.Event
      	//	- key.Event
      	//	- mouse.Event
      	//	- touch.Event
      	// from the golang.org/x/mobile/event/... packages. Other packages may send
      	// events, of those types above or of other types, via Send or SendFirst.
      	NextEvent() interface{}
      }

        EventDeque is an infinitely buffered double-ended queue of events.

        type Image

        type Image interface {
        	Spanner
        
        	// Release releases the Image's resources, after all pending uploads and
        	// draws resolve.
        	//
        	// The behavior of the Image after Release, whether calling its methods or
        	// passing it as an argument, is undefined.
        	Release()
        
        	// RGBA returns the pixel buffer as an *image.RGBA.
        	//
        	// Its contents should not be accessed while the Image is uploading.
        	//
        	// The contents of the returned *image.RGBA's Pix field (of type []byte)
        	// can be modified at other times, but that Pix slice itself (i.e. its
        	// underlying pointer, length and capacity) should not be modified at any
        	// time.
        	//
        	// The following is valid:
        	//	m := buffer.RGBA()
        	//	if len(m.Pix) >= 4 {
        	//		m.Pix[0] = 0xff
        	//		m.Pix[1] = 0x00
        	//		m.Pix[2] = 0x00
        	//		m.Pix[3] = 0xff
        	//	}
        	// or, equivalently:
        	//	m := buffer.RGBA()
        	//	m.SetRGBA(m.Rect.Min.X, m.Rect.Min.Y, color.RGBA{0xff, 0x00, 0x00, 0xff})
        	// and using the standard library's image/draw package is also valid:
        	//	dst := buffer.RGBA()
        	//	draw.Draw(dst, dst.Bounds(), etc)
        	// but the following is invalid:
        	//	m := buffer.RGBA()
        	//	m.Pix = anotherByteSlice
        	// and so is this:
        	//	*buffer.RGBA() = anotherImageRGBA
        	RGBA() *image.RGBA
        }

          Image is an in-memory pixel buffer. Its pixels can be modified by any Go code that takes an *image.RGBA, such as the standard library's image/draw package. A Image is essentially an *image.RGBA, but not all *image.RGBA values (including those returned by image.NewRGBA) are valid Images, as a driver may assume that the memory backing a Image's pixels are specially allocated.

          To see a Image's contents on a screen, upload it to a Texture (and then draw the Texture on a Window) or upload it directly to a Window.

          When specifying a sub-Image via Upload, a Image's top-left pixel is always (0, 0) in its own coordinate space.

          type PublishResult

          type PublishResult struct {
          	// BackBufferPreserved is whether the contents of the back buffer was
          	// preserved. If false, the contents are undefined.
          	BackBufferPreserved bool
          }

            PublishResult is the result of an Window.Publish call.

            type Screen

            type Screen interface {
            	// NewImage returns a new Image for this screen.
            	NewImage(size image.Point) (Image, error)
            
            	// NewTexture returns a new Texture for this screen.
            	NewTexture(size image.Point) (Texture, error)
            
            	// NewWindow returns a new Window for this screen.
            	//
            	// A nil opts is valid and means to use the default option values.
            	NewWindow(opts WindowGenerator) (Window, error)
            }

              Screen creates Images, Textures and Windows.

              type Spanner

              type Spanner interface {
              	// Size returns the size of this Spanner.
              	Size() image.Point
              
              	// Bounds returns the bounds of this Spanner's span.
              	Bounds() image.Rectangle
              }

                Spanner types span some distance. This distance can either be returned as a rectangle from 0,0 or as a size point.

                type Texture

                type Texture interface {
                	Spanner
                
                	// Upload uploads the sub-Buffer defined by src and sr to the destination
                	// (the method receiver), such that sr.Min in src-space aligns with dp in
                	// dst-space. The destination's contents are overwritten; the draw operator
                	// is implicitly draw.Src.
                	//
                	// It is valid to upload a Buffer while another upload of the same Buffer
                	// is in progress, but a Buffer's image.RGBA pixel contents should not be
                	// accessed while it is uploading. A Buffer is re-usable, in that its pixel
                	// contents can be further modified, once all outstanding calls to Upload
                	// have returned.
                	//
                	// TODO: make it optional that a Buffer's contents is preserved after
                	// Upload? Undoing a swizzle is a non-trivial amount of work, and can be
                	// redundant if the next paint cycle starts by clearing the buffer.
                	//
                	// When uploading to a Window, there will not be any visible effect until
                	// Publish is called.
                	Upload(dp image.Point, src Image, sr image.Rectangle)
                
                	// Fill fills that part of the destination (the method receiver) defined by
                	// dr with the given color.
                	//
                	// When filling a Window, there will not be any visible effect until
                	// Publish is called.
                	Fill(dr image.Rectangle, src color.Color, op draw.Op)
                
                	// Release releases the Texture's resources, after all pending uploads and
                	// draws resolve.
                	//
                	// The behavior of the Texture after Release, whether calling its methods
                	// or passing it as an argument, is undefined.
                	Release()
                }

                  Texture is a pixel buffer, but not one that is directly accessible as a []byte. Conceptually, it could live on a GPU, in another process or even be across a network, instead of on a CPU in this process.

                  Images can be uploaded to Textures, and Textures can be drawn on Windows.

                  When specifying a sub-Texture via Draw, a Texture's top-left pixel is always (0, 0) in its own coordinate space.

                  type Window

                  type Window interface {
                  	// Release closes the window.
                  	//
                  	// The behavior of the Window after Release, whether calling its methods or
                  	// passing it as an argument, is undefined.
                  	Release()
                  
                  	EventDeque
                  
                  	Drawer
                  
                  	// Publish flushes any pending Upload and Draw calls to the window, and
                  	// swaps the back buffer to the front.
                  	Publish() PublishResult
                  }

                    Window is a top-level, double-buffered GUI window.

                    type WindowGenerator

                    type WindowGenerator struct {
                    	// Width and Height specify the dimensions of the new window. If Width
                    	// or Height are zero, a driver-dependent default will be used for each
                    	// zero value dimension.
                    	Width, Height int
                    
                    	// Title specifies the window title.
                    	Title string
                    
                    	// Fullscreen determines whether the new window will be fullscreen or not.
                    	Fullscreen bool
                    
                    	// Borderless determines whether the new window will have borders or not
                    	Borderless bool
                    
                    	// TopMost determines whether the new window will stay on top of other windows
                    	// even when out of focus.
                    	TopMost bool
                    
                    	// NoScaling determines whether the new window will have scaling allowed.
                    	// With a zero value of false, scaling is allowed.
                    	NoScaling bool
                    
                    	// X and Y determine the location the new window should be created at. If
                    	// either are zero, a driver-dependant default will be used for each zero
                    	// value. If Fullscreen is true, these values will be ignored.
                    	X, Y int32
                    }

                      A WindowGenerator can generate windows based on various new window settings.

                      func NewWindowGenerator

                      func NewWindowGenerator(opts ...WindowOption) WindowGenerator

                        NewWindowGenerator creates a window generator with zero values, then calls all options passed in on it.

                        type WindowOption

                        type WindowOption func(*WindowGenerator)

                          A WindowOption is any function that sets up a WindowGenerator.

                          func Borderless

                          func Borderless(on bool) WindowOption

                            Borderless sets the starting borderless boolean of the new window defaults to borders on.

                            func Dimensions

                            func Dimensions(w, h int) WindowOption

                              Dimensions sets the width and height of new windows

                              func Fullscreen

                              func Fullscreen(on bool) WindowOption

                                Fullscreen sets the starting fullscreen boolean of the new window

                                func Position

                                func Position(x, y int32) WindowOption

                                  Position sets the starting position of the new window

                                  func Title

                                  func Title(s string) WindowOption

                                    Title sets a sanitized form of the input string. In particular, its length will not exceed 4096, and it may be further truncated so that it is valid UTF-8 and will not contain the NUL byte.

                                    func TopMost

                                    func TopMost(on bool) WindowOption