bff8b64e5aeb45d7d1218197f09ff17764a49768 — Elias Naur 28 days ago e140f2a
ui/app: replace WindowOptions with WindowOption

Thanks to Larry Clapp for noticing the opportunity for improvement.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
M ui/app/app.go => ui/app/app.go +1 -1
@@ 69,7 69,7 @@   type windowAndOptions struct {
  	window *Window
- 	opts   *WindowOptions
+ 	opts   *windowOptions
  }
  
  const (

M ui/app/os_android.go => ui/app/os_android.go +1 -1
@@ 422,7 422,7 @@ func main() {
  }
  
- func createWindow(window *Window, opts *WindowOptions) error {
+ func createWindow(window *Window, opts *windowOptions) error {
  	mainWindow.in <- windowAndOptions{window, opts}
  	return <-mainWindow.errs
  }

M ui/app/os_ios.go => ui/app/os_ios.go +1 -1
@@ 246,7 246,7 @@ }
  }
  
- func createWindow(win *Window, opts *WindowOptions) error {
+ func createWindow(win *Window, opts *windowOptions) error {
  	mainWindow.in <- windowAndOptions{win, opts}
  	return <-mainWindow.errs
  }

M ui/app/os_js.go => ui/app/os_js.go +1 -1
@@ 31,7 31,7 @@   var mainDone = make(chan struct{})
  
- func createWindow(win *Window, opts *WindowOptions) error {
+ func createWindow(win *Window, opts *windowOptions) error {
  	doc := js.Global().Get("document")
  	cont := getContainer(doc)
  	cnv := createCanvas(doc)

M ui/app/os_macos.go => ui/app/os_macos.go +1 -1
@@ 266,7 266,7 @@ })
  }
  
- func createWindow(win *Window, opts *WindowOptions) error {
+ func createWindow(win *Window, opts *windowOptions) error {
  	mainWindow.in <- windowAndOptions{win, opts}
  	return <-mainWindow.errs
  }

M ui/app/os_wayland.go => ui/app/os_wayland.go +2 -2
@@ 156,7 156,7 @@ <-mainDone
  }
  
- func createWindow(window *Window, opts *WindowOptions) error {
+ func createWindow(window *Window, opts *windowOptions) error {
  	connMu.Lock()
  	defer connMu.Unlock()
  	if len(winMap) > 0 {


@@ 182,7 182,7 @@ return nil
  }
  
- func createNativeWindow(opts *WindowOptions) (*window, error) {
+ func createNativeWindow(opts *windowOptions) (*window, error) {
  	pipe := make([]int, 2)
  	if err := syscall.Pipe2(pipe, syscall.O_NONBLOCK|syscall.O_CLOEXEC); err != nil {
  		return nil, fmt.Errorf("createNativeWindow: failed to create pipe: %v", err)

M ui/app/os_windows.go => ui/app/os_windows.go +2 -2
@@ 161,7 161,7 @@ <-mainDone
  }
  
- func createWindow(window *Window, opts *WindowOptions) error {
+ func createWindow(window *Window, opts *windowOptions) error {
  	onceMu.Lock()
  	defer onceMu.Unlock()
  	if len(winMap) > 0 {


@@ 191,7 191,7 @@ return <-cerr
  }
  
- func createNativeWindow(opts *WindowOptions) (*window, error) {
+ func createNativeWindow(opts *windowOptions) (*window, error) {
  	setProcessDPIAware()
  	screenDC, err := getDC(0)
  	if err != nil {

M ui/app/window.go => ui/app/window.go +49 -19
@@ 15,11 15,12 @@ "gioui.org/ui/system"
  )
  
- // WindowOptions specifies a set of window properties
- // for creating new Windows.
- type WindowOptions struct {
- 	// Width and Height of the Window. Use the zero value
- 	// to choose a default size.
+ // WindowOption configures a Window.
+ type WindowOption struct{
+ 	apply func(opts *windowOptions)
+ }
+ 
+ type windowOptions struct {
  	Width, Height ui.Value
  	Title         string
  }


@@ 83,20 84,15 @@ // platform.
  //
  // BUG: Calling NewWindow more than once is not yet supported.
- func NewWindow(opts *WindowOptions) *Window {
- 	if opts == nil {
- 		opts = &WindowOptions{
- 			Title: "Gio",
- 		}
- 	}
- 	if opts.Width.V < 0 || opts.Height.V < 0 {
- 		panic("window width and height must be larger than or equal to 0")
- 	}
- 	if opts.Width.V == 0 {
- 		opts.Width = ui.Dp(800)
+ func NewWindow(options ...WindowOption) *Window {
+ 	opts := &windowOptions{
+ 		Width: ui.Dp(800),
+ 		Height: ui.Dp(600),
+ 		Title: "Gio",
  	}
- 	if opts.Height.V == 0 {
- 		opts.Height = ui.Dp(600)
+ 
+ 	for _, o := range options {
+ 		o.apply(opts)
  	}
  
  	w := &Window{


@@ 224,7 220,7 @@ }
  }
  
- func (w *Window) run(opts *WindowOptions) {
+ func (w *Window) run(opts *windowOptions) {
  	defer close(w.in)
  	defer close(w.out)
  	if err := createWindow(w, opts); err != nil {


@@ 332,4 328,38 @@ return q.q.Next(k)
  }
  
+ 
+ // WithTitle returns an option that sets the window title.
+ func WithTitle(t string) WindowOption {
+ 	return WindowOption{
+ 		apply: func(opts *windowOptions) {
+ 			opts.Title = t
+ 		},
+ 	}
+ }
+ 
+ // WithWidth returns an option that sets the window width.
+ func WithWidth(w ui.Value) WindowOption {
+ 	if w.V<= 0 {
+ 		panic("width must be larger than or equal to 0")
+ 	}
+ 	return WindowOption{
+ 		apply: func(opts *windowOptions) {
+ 			opts.Width= w
+ 		},
+ 	}
+ }
+ 
+ // WithHeight returns an option that sets the window height.
+ func WithHeight(h ui.Value) WindowOption {
+ 	if h.V<= 0 {
+ 		panic("height must be larger than or equal to 0")
+ 	}
+ 	return WindowOption{
+ 		apply: func(opts *windowOptions) {
+ 			opts.Height = h
+ 		},
+ 	}
+ }
+ 
  func (_ driverEvent) ImplementsEvent() {}