view

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2024 License: MIT, Unlicense, MIT, + 1 more Imports: 15 Imported by: 0

Documentation

Overview

Package view provides an api to build a simple graphical user interface through the GUI type, e.g.

--------------------------main.go-------------------------------
package main

import (
	"fmt"
	"os"

	"git.sr.ht/slukits/tdd-gio/view"
)

func main() {
	gui, observer := view.GUI{}, make(chan *view.Message, 10)
	go controller(&gui, observer)
	gui.Main(observer, view.Size(300, 200))
}

func controller(gui *view.GUI, observer chan *view.Message) {
	defer func() {
		if err, ok := gui.Mtx(view.MsgExit).(error); ok && err != nil {
			log.Fatal(err)
		}
		os.Exit(0)
	}()
	for {
		msg := <-observer
		switch msg {
		case view.MsgExit:
			return
		case view.MsgEventHandlingStarted:
			gui.Display(&view.Crosshair{})
		default:
			fmt.Printf("view: %s\n", msg.Txt())
		}
	}
}

----------------------------------------------------------------

While a stateless ui-library has appeal a painted ui represents state and keeping track of it has serious advantages:

  • Is the viewport size of a widget unchanged its last painting may be reused
  • It makes the ui testable: If we want to do black box testing and there is no state we can't compare state which is typically how test assertions work.
  • It allows for mouse events to be mapped to widgets.

Last but not least I think usability also counts and taking statelessness to the extreme seems to lead to unintuitive apis, e.g. it makes it quite hard to implement an MVC architecture.

Index

Constants

View Source
const (
	// SendTimeoutDflt is the default timeout a gui waits for a message
	// to be send.
	SendTimeoutDflt = time.Minute
	// SendTimeoutMsg is reported on setting the send timeout option
	SendTimeoutMsg = "send-timeout set to %v"
	// SendPnc is the panic message of a timed out message-send
	SendPnc = "sending a message timed out"
)
View Source
const CrosshairMsg = "crosshair layout x-axis: %d,%d; y-axis %d,%d"

CrosshairMsg is the format string for the text of a crosshair layout message.

View Source
const FittingMsg = "fitting '%d' lines into rectangle %v"

FittingMsg reports a Fittings instance's layout aspects iff a Fitting instance is painted with a viewport different from the last.

View Source
const PncMain = "view: gui: observer must not be zero"

PncMain is reported if a zero observer is passed into GUI.Main.

View Source
const StringMsg = "layed out string '%s' into rectangle %v"

StringMsg is reported if a Runes instance is painted with a viewport different from the last.

View Source
const WidgetMsg = "viewport(%d): %v"

WidgetMsg is the default message of an embedding widget that only wants its viewport reported on change of any of its dimensions.

View Source
const WindowSizeMsg = "window size set to %dx%d"

WindowSizeMsg is reported on setting initial window size

Variables

View Source
var (
	// MsgExit is send when a DestroyEvent (window closed) was received.
	// MsgExit context see [GUI.Mtx] provides a potentially occurred
	// system error.
	MsgExit = &Message{id: Exit, txt: "window closed"}

	// MsgPanic is reported when a panic in the event loop happened its
	// context see [GUI.Mtx] reports the panic-value.  NOTE the SendPnc
	// issued by a timed out message send is naturally not reported but
	// reissued.
	MsgPanic = &Message{txt: "event-handling panicked"}

	// MsgEventHandlingStarted is reported right before the event- and
	// display-loop is entered.
	MsgEventHandlingStarted = &Message{txt: "event-handling started"}

	// MsgResize is reported on a frame event if the window size changed
	// since the last frame event.
	MsgResize = &Message{txt: "window resized"}
)
View Source
var ErrMain = errors.New("gui: main must not be called twice")

ErrMain is reported if GUI.Main is called more often than once.

View Source
var ZeroViewportDelta image.Rectangle

ZeroViewportDelta is used by Widget.Update to express an unchanged viewport.

Functions

func SendTimeout

func SendTimeout(t time.Duration) internal.Option

SendTimeout determines how long a GUI waits on the observer channel for a message to be picked up before it panics.

func Size

func Size(width, height int) internal.Option

Size options sets the initial window size of an gui.

Types

type Blank

type Blank struct {
	Widget
}

A Blank widget embeds the internals a widget needs; its Size defaults to zero and its Paint-method is a noop. A Blank widget may be used to implement your own widget or comes in handy for testing layout aspects.

func (*Blank) Size

func (b *Blank) Size(viewport image.Rectangle) image.Point

Size of given Blank widget b defaults to zero.

type Centered

type Centered struct {
	// SizedPainter which should be layed out centered.
	Widgeter
}

Centered lays out mandatory set sized painter in the center of a provided viewport.

func (Centered) Paint

func (c Centered) Paint(viewport image.Rectangle, ops *op.Ops)

Paint set SizedPainter vertically and horizontally centered to given viewport.

func (Centered) Size

func (c Centered) Size(viewport image.Rectangle) image.Point

type Crosshair

type Crosshair struct {
	// contains filtered or unexported fields
}

Crosshair draws in its dimensions a vertically centered line over the whole height and a horizontally centered line over the whole width.

func (*Crosshair) Paint

func (c *Crosshair) Paint(viewport image.Rectangle, ops *op.Ops)

Layout draws in the Max-dimensions of given context's constraints a vertically centered line over the whole height and a horizontally centered line over the whole width. Is the layout reporter set it also reports its layout to it when ever given dimensions change.

type CrosshairLayout

type CrosshairLayout struct {
	// VAxis defines a crosshair's vertical axis
	VAxis VAxis
	// HAxis defines a crosshair's horizontal axis
	HAxis HAxis
}

CrosshairLayout describes a Crosshair widget's layout.

type Fitting added in v0.3.2

type Fitting struct {

	// Sequence to layout and paint given lines.
	giorune.Sequence

	// Lines which should be fitted into a provided viewport.
	Lines []string

	// Options for painting set lines like fb/bg-colors.
	Options []giorune.Option
	// contains filtered or unexported fields
}

Fitting interprets a set sequence of strings as lines and fits them into the provided viewport when painting.

func (*Fitting) Paint added in v0.3.2

func (f *Fitting) Paint(viewport image.Rectangle, ops *op.Ops)

Paint implements Widget.Paint and fits set lines into given viewport.

func (*Fitting) Size added in v0.3.2

func (f *Fitting) Size(viewport image.Rectangle) image.Point

Size implements Widget.Size returns the biggest size of set Lines which still fits into viewport.

type FittingLayout added in v0.3.2

type FittingLayout = image.Rectangle

FittingLayout is the definition of a Fitting-widget. FittingLayout is the message context of a FittingMsg.

type GUI

type GUI struct {
	// contains filtered or unexported fields
}

GUI provides an api to build graphical user interfaces.

func (*GUI) Display

func (gui *GUI) Display(ww ...Widgeter)

Display reports given widgets to the event handler which will layout and draw them on the next app.FrameEvent.

func (*GUI) Main

func (gui *GUI) Main(observer chan *Message, oo ...Option) error

Main ensures that the event-loop is started, the application window is shown and provides the main-thread to the underlying graphics system. On most systems Main will block forever. Main will panic if given observer is nil otherwise given GUI g reports its events to given observer. Main will fail on any subsequent call.

func (*GUI) Mtx

func (gui *GUI) Mtx(m *Message) any

Mtx returns last set context for a message with given message's ID, i.e. the context of a window resize event is overwritten by the next resize.

type HAxis

type HAxis struct {
	Y      int
	Length int
}

HAxis defines the horizontal line of a Crosshair widget.

type Message

type Message struct {
	// contains filtered or unexported fields
}

A Message is reported by an GUI to an initially given observer.

func (Message) ID

func (m Message) ID() int

func (Message) Txt

func (m Message) Txt() string

Txt returns given message m's text.

type Metricer

type Metricer interface {
	SetMetric(unit.Metric)
}

Metricer indicates a widget whose painting depends on the current pixel metrics.

type MsgID

type MsgID = int
const (
	// Exit ids the context of an event handler's exit message whose
	// context a potential error is.
	Exit MsgID = -iota - 1
	// InitialWindowSize is reported by a GUI's setup having the Size
	// option set.
	InitialWindowSize
	// Resize is reported by the event handler on a frame event
	// providing a different size than the previous frame event.
	Resize

	ContextFree MsgID = 0
)

type Option

type Option = internal.Option

An Option can be pass into GUI.Main to set a GUI's options.

type Padded

type Padded struct {
	Widgeter
	Top, Right, Bottom, Left int
}

func (*Padded) Paint

func (p *Padded) Paint(viewport image.Rectangle, ops *op.Ops)

func (*Padded) Size

func (p *Padded) Size(viewport image.Rectangle) image.Point

type Painter

type Painter interface {
	// Paint a widget in given viewport.
	Paint(viewport image.Rectangle, ops *op.Ops)
}

Painter implementations are paintable widgets.

type SizedPainter

type SizedPainter interface {
	Sizer
	Painter
}

SizedPainter implementations provide a size relative to a given viewport and are paintable.

type Sizer

type Sizer interface {
	// Size returns the size a widget would like to use of a given
	// viewport.
	Size(viewport image.Rectangle) image.Point
}

Sizer implementations provide a size relative to a given viewport.

type String

type String struct {

	// Sequence to paint and measure set string.
	giorune.Sequence

	// S is the string to paint on the window.
	S string

	// Options for painting set string like foreground or background
	// color.
	Options []giorune.Option
	// contains filtered or unexported fields
}

String wraps a set giorune.Sequence together with a string into a widget allowing for the sequence to be layed out in the gui.

func (*String) Paint

func (s *String) Paint(viewport image.Rectangle, ops *op.Ops)

Paint implements Widget.Paint and paints set string into given viewport utilizing set giorune.Sequence.

func (*String) SetMetric

func (s *String) SetMetric(mtr unit.Metric)

func (*String) Size

func (s *String) Size(viewport image.Rectangle) image.Point

Size implements Widget.Size and provides the dimensions of set String measured with set giorune.Sequence.

type StringLayout

type StringLayout = image.Rectangle

StringLayout is the definition of a Runes layout which is reported as a message context if a Runes-widget is painted with a viewport different from the last.

type VAxis

type VAxis struct {
	X      int
	Length int
}

VAxis defines the vertical line of a Crosshair widget.

type Widget

type Widget struct {
	// contains filtered or unexported fields
}

Widget implements what all Widgets of the view package have in common. Any widget must embed an instance of this type because it also implements private methods of the Widgeter interface.

func (Widget) ID

func (w Widget) ID() int

ID returns the unique ID of a widget whose main use is to recognize messages referring to given widget w.

func (*Widget) Paint

func (w *Widget) Paint(viewport image.Rectangle, _ *op.Ops)

Paint of given widget w is a noop when it comes to painting but it reports its viewport each time it changes any of its dimensions.

func (Widget) Size

func (w Widget) Size(viewport image.Rectangle) image.Point

Size consumes by default all available size of given viewport.

func (*Widget) Update

func (w *Widget) Update(viewport image.Rectangle) (delta image.Rectangle)

Update currently set viewport of given Widget w iff it has changed and returns the position and size deltas: delta.Min indicates the position delta of w's viewport while delta.Max indicates the size delta of w's viewport.

type Widgeter

type Widgeter interface {
	SizedPainter
	Update(viewport image.Rectangle) (delta image.Rectangle)
	// contains filtered or unexported methods
}

A Widgeter is something which is layout- and paintable by calling its layout method provided with a graphics/layout-context.

Directories

Path Synopsis
Package internal provides functions/types that should be accessible for the testing backend and for the view but not for any one else.
Package internal provides functions/types that should be accessible for the testing backend and for the view but not for any one else.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL