github.com/Seikaijyu/gio@v0.0.1/app/os.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package app
     4  
     5  import (
     6  	"errors"
     7  	"image"
     8  	"image/color"
     9  
    10  	"github.com/Seikaijyu/gio/io/key"
    11  
    12  	"github.com/Seikaijyu/gio/gpu"
    13  	"github.com/Seikaijyu/gio/io/pointer"
    14  	"github.com/Seikaijyu/gio/io/system"
    15  	"github.com/Seikaijyu/gio/unit"
    16  )
    17  
    18  // errOutOfDate is reported when the GPU surface dimensions or properties no
    19  // longer match the window.
    20  var errOutOfDate = errors.New("app: GPU surface out of date")
    21  
    22  // Config describes a Window configuration.
    23  type Config struct {
    24  	// Size is the window dimensions (Width, Height).
    25  	Size image.Point
    26  	// MaxSize is the window maximum allowed dimensions.
    27  	MaxSize image.Point
    28  	// MinSize is the window minimum allowed dimensions.
    29  	MinSize image.Point
    30  	// Title is the window title displayed in its decoration bar.
    31  	Title string
    32  	// WindowMode is the window mode.
    33  	Mode WindowMode
    34  	// StatusColor is the color of the Android status bar.
    35  	StatusColor color.NRGBA
    36  	// NavigationColor is the color of the navigation bar
    37  	// on Android, or the address bar in browsers.
    38  	NavigationColor color.NRGBA
    39  	// Orientation is the current window orientation.
    40  	Orientation Orientation
    41  	// CustomRenderer is true when the window content is rendered by the
    42  	// client.
    43  	CustomRenderer bool
    44  	// Decorated reports whether window decorations are provided automatically.
    45  	Decorated bool
    46  	// decoHeight is the height of the fallback decoration for platforms such
    47  	// as Wayland that may need fallback client-side decorations.
    48  	decoHeight unit.Dp
    49  }
    50  
    51  // ConfigEvent is sent whenever the configuration of a Window changes.
    52  type ConfigEvent struct {
    53  	Config Config
    54  }
    55  
    56  func (c *Config) apply(m unit.Metric, options []Option) {
    57  	for _, o := range options {
    58  		o(m, c)
    59  	}
    60  }
    61  
    62  type wakeupEvent struct{}
    63  
    64  // WindowMode is the window mode (WindowMode.Option sets it).
    65  // Note that mode can be changed programatically as well as by the user
    66  // clicking on the minimize/maximize buttons on the window's title bar.
    67  type WindowMode uint8
    68  
    69  const (
    70  	// Windowed is the normal window mode with OS specific window decorations.
    71  	Windowed WindowMode = iota
    72  	// Fullscreen is the full screen window mode.
    73  	Fullscreen
    74  	// Minimized is for systems where the window can be minimized to an icon.
    75  	Minimized
    76  	// Maximized is for systems where the window can be made to fill the available monitor area.
    77  	Maximized
    78  )
    79  
    80  // Option changes the mode of a Window.
    81  func (m WindowMode) Option() Option {
    82  	return func(_ unit.Metric, cnf *Config) {
    83  		cnf.Mode = m
    84  	}
    85  }
    86  
    87  // String returns the mode name.
    88  func (m WindowMode) String() string {
    89  	switch m {
    90  	case Windowed:
    91  		return "windowed"
    92  	case Fullscreen:
    93  		return "fullscreen"
    94  	case Minimized:
    95  		return "minimized"
    96  	case Maximized:
    97  		return "maximized"
    98  	}
    99  	return ""
   100  }
   101  
   102  // Orientation is the orientation of the app (Orientation.Option sets it).
   103  //
   104  // Supported platforms are Android and JS.
   105  type Orientation uint8
   106  
   107  const (
   108  	// AnyOrientation allows the window to be freely orientated.
   109  	AnyOrientation Orientation = iota
   110  	// LandscapeOrientation constrains the window to landscape orientations.
   111  	LandscapeOrientation
   112  	// PortraitOrientation constrains the window to portrait orientations.
   113  	PortraitOrientation
   114  )
   115  
   116  func (o Orientation) Option() Option {
   117  	return func(_ unit.Metric, cnf *Config) {
   118  		cnf.Orientation = o
   119  	}
   120  }
   121  
   122  func (o Orientation) String() string {
   123  	switch o {
   124  	case AnyOrientation:
   125  		return "any"
   126  	case LandscapeOrientation:
   127  		return "landscape"
   128  	case PortraitOrientation:
   129  		return "portrait"
   130  	}
   131  	return ""
   132  }
   133  
   134  type frameEvent struct {
   135  	system.FrameEvent
   136  
   137  	Sync bool
   138  }
   139  
   140  type context interface {
   141  	API() gpu.API
   142  	RenderTarget() (gpu.RenderTarget, error)
   143  	Present() error
   144  	Refresh() error
   145  	Release()
   146  	Lock() error
   147  	Unlock()
   148  }
   149  
   150  // Driver is the interface for the platform implementation
   151  // of a window.
   152  type driver interface {
   153  	// SetAnimating sets the animation flag. When the window is animating,
   154  	// FrameEvents are delivered as fast as the display can handle them.
   155  	SetAnimating(anim bool)
   156  	// ShowTextInput updates the virtual keyboard state.
   157  	ShowTextInput(show bool)
   158  	SetInputHint(mode key.InputHint)
   159  	NewContext() (context, error)
   160  	// ReadClipboard requests the clipboard content.
   161  	ReadClipboard()
   162  	// WriteClipboard requests a clipboard write.
   163  	WriteClipboard(s string)
   164  	// Configure the window.
   165  	Configure([]Option)
   166  	// SetCursor updates the current cursor to name.
   167  	SetCursor(cursor pointer.Cursor)
   168  	// Wakeup wakes up the event loop and sends a WakeupEvent.
   169  	Wakeup()
   170  	// Perform actions on the window.
   171  	Perform(system.Action)
   172  	// EditorStateChanged notifies the driver that the editor state changed.
   173  	EditorStateChanged(old, new editorState)
   174  }
   175  
   176  type windowRendezvous struct {
   177  	in   chan windowAndConfig
   178  	out  chan windowAndConfig
   179  	errs chan error
   180  }
   181  
   182  type windowAndConfig struct {
   183  	window  *callbacks
   184  	options []Option
   185  }
   186  
   187  func newWindowRendezvous() *windowRendezvous {
   188  	wr := &windowRendezvous{
   189  		in:   make(chan windowAndConfig),
   190  		out:  make(chan windowAndConfig),
   191  		errs: make(chan error),
   192  	}
   193  	go func() {
   194  		var main windowAndConfig
   195  		var out chan windowAndConfig
   196  		for {
   197  			select {
   198  			case w := <-wr.in:
   199  				var err error
   200  				if main.window != nil {
   201  					err = errors.New("multiple windows are not supported")
   202  				}
   203  				wr.errs <- err
   204  				main = w
   205  				out = wr.out
   206  			case out <- main:
   207  			}
   208  		}
   209  	}()
   210  	return wr
   211  }
   212  
   213  func (wakeupEvent) ImplementsEvent() {}
   214  func (ConfigEvent) ImplementsEvent() {}
   215  
   216  func walkActions(actions system.Action, do func(system.Action)) {
   217  	for a := system.Action(1); actions != 0; a <<= 1 {
   218  		if actions&a != 0 {
   219  			actions &^= a
   220  			do(a)
   221  		}
   222  	}
   223  }