Documentation ¶
Overview ¶
Package layout implements layouts common to GUI programs.
Constraints and dimensions ¶
Constraints and dimensions form the interface between layouts and interface child elements. This package operates on Widgets, functions that compute Dimensions from a a set of constraints for acceptable widths and heights. Both the constraints and dimensions are maintained in an implicit Context to keep the Widget declaration short.
For example, to add space above a widget:
gtx := layout.NewContext(...) gtx.Reset(...) // Configure a top inset. inset := layout.Inset{Top: unit.Dp(8), ...} // Use the inset to lay out a widget. inset.Layout(gtx, func() { // Lay out widget and determine its size given the constraints. ... dims := layout.Dimensions{...} gtx.Dimensions = dims })
Note that the example does not generate any garbage even though the Inset is transient. Layouts that don't accept user input are designed to not escape to the heap during their use.
Layout operations are recursive: a child in a layout operation can itself be another layout. That way, complex user interfaces can be created from a few generic layouts.
This example both aligns and insets a child:
inset := layout.Inset{...} inset.Layout(gtx, func() { align := layout.Align(...) align.Layout(gtx, func() { widget.Layout(gtx, ...) }) })
More complex layouts such as Stack and Flex lay out multiple children, and stateful layouts such as List accept user input.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Align ¶
type Align Direction
Align aligns a widget in the available space.
Example ¶
package main import ( "fmt" "image" "github.com/gop9/olt/gio/layout" ) func main() { gtx := new(layout.Context) // Rigid constraints with both minimum and maximum set. gtx.Reset(nil, image.Point{X: 100, Y: 100}) align := layout.Align(layout.Center) align.Layout(gtx, func() { // Lay out a 50x50 sized widget. layoutWidget(gtx, 50, 50) fmt.Println(gtx.Dimensions.Size) }) fmt.Println(gtx.Dimensions.Size) } func layoutWidget(ctx *layout.Context, width, height int) { ctx.Dimensions = layout.Dimensions{ Size: image.Point{ X: width, Y: height, }, } }
Output: (50,50) (100,100)
type Constraint ¶
type Constraint struct {
Min, Max int
}
Constraint is a range of acceptable sizes in a single dimension.
func (Constraint) Constrain ¶
func (c Constraint) Constrain(v int) int
Constrain a value to the range [Min; Max].
type Constraints ¶
type Constraints struct { Width Constraint Height Constraint }
Constraints represent a set of acceptable ranges for a widget's width and height.
func RigidConstraints ¶
func RigidConstraints(size image.Point) Constraints
RigidConstraints returns the constraints that can only be satisfied by the given dimensions.
type Context ¶
type Context struct { // Constraints track the constraints for the active widget or // layout. Constraints Constraints // Dimensions track the result of the most recent layout // operation. Dimensions Dimensions *op.Ops // contains filtered or unexported fields }
Context carries the state needed by almost all layouts and widgets. A zero value Context never returns events, map units to pixels with a scale of 1.0, and returns the zero time from Now.
func NewContext ¶
NewContext returns a Context for an event queue.
func (*Context) Events ¶
Events returns the events available for the key. If no queue is configured, Events returns nil.
type Dimensions ¶
Dimensions are the resolved size and baseline for a widget.
type Direction ¶
type Direction uint8
Direction is the alignment of widgets relative to a containing space.
type Flex ¶
type Flex struct { // Axis is the main axis, either Horizontal or Vertical. Axis Axis // Spacing controls the distribution of space left after // layout. Spacing Spacing // Alignment is the alignment in the cross axis. Alignment Alignment }
Flex lays out child elements along an axis, according to alignment and weights.
Example ¶
package main import ( "fmt" "image" "github.com/gop9/olt/gio/layout" ) func main() { gtx := new(layout.Context) gtx.Reset(nil, image.Point{X: 100, Y: 100}) layout.Flex{}.Layout(gtx, // Rigid 10x10 widget. layout.Rigid(func() { fmt.Printf("Rigid: %v\n", gtx.Constraints.Width) layoutWidget(gtx, 10, 10) }), // Child with 50% space allowance. layout.Flexed(0.5, func() { fmt.Printf("50%%: %v\n", gtx.Constraints.Width) layoutWidget(gtx, 10, 10) }), ) } func layoutWidget(ctx *layout.Context, width, height int) { ctx.Dimensions = layout.Dimensions{ Size: image.Point{ X: width, Y: height, }, } }
Output: Rigid: {0 100} 50%: {45 45}
type FlexChild ¶
type FlexChild struct {
// contains filtered or unexported fields
}
FlexChild is the descriptor for a Flex child.
type Inset ¶
Inset adds space around a widget.
Example ¶
package main import ( "fmt" "image" "github.com/gop9/olt/gio/layout" "github.com/gop9/olt/gio/unit" ) func main() { gtx := new(layout.Context) gtx.Reset(nil, image.Point{X: 100, Y: 100}) // Loose constraints with no minimal size. gtx.Constraints.Width.Min = 0 gtx.Constraints.Height.Min = 0 // Inset all edges by 10. inset := layout.UniformInset(unit.Dp(10)) inset.Layout(gtx, func() { // Lay out a 50x50 sized widget. layoutWidget(gtx, 50, 50) fmt.Println(gtx.Dimensions.Size) }) fmt.Println(gtx.Dimensions.Size) } func layoutWidget(ctx *layout.Context, width, height int) { ctx.Dimensions = layout.Dimensions{ Size: image.Point{ X: width, Y: height, }, } }
Output: (50,50) (70,70)
func UniformInset ¶
UniformInset returns an Inset with a single inset applied to all edges.
type List ¶
type List struct { Axis Axis // ScrollToEnd instructs the list to stay scrolled to the far end position // once reached. A List with ScrollToEnd == true and Position.BeforeEnd == // false draws its content with the last item at the bottom of the list // area. ScrollToEnd bool // Alignment is the cross axis alignment of list elements. Alignment Alignment // Position is updated during Layout. To save the list scroll position, // just save Position after Layout finishes. To scroll the list // programatically, update Position (e.g. restore it from a saved value) // before calling Layout. Position Position // contains filtered or unexported fields }
List displays a subsection of a potentially infinitely large underlying list. List accepts user input to scroll the subsection.
Example ¶
package main import ( "fmt" "image" "github.com/gop9/olt/gio/layout" ) func main() { gtx := new(layout.Context) gtx.Reset(nil, image.Point{X: 100, Y: 100}) // The list is 1e6 elements, but only 5 fit the constraints. const listLen = 1e6 var list layout.List count := 0 list.Layout(gtx, listLen, func(i int) { count++ layoutWidget(gtx, 20, 20) }) fmt.Println(count) } func layoutWidget(ctx *layout.Context, width, height int) { ctx.Dimensions = layout.Dimensions{ Size: image.Point{ X: width, Y: height, }, } }
Output: 5
type ListElement ¶
type ListElement func(index int)
ListElement is a function that computes the dimensions of a list element.
type Position ¶
type Position struct { // BeforeEnd tracks whether the List position is before the very end. We // use "before end" instead of "at end" so that the zero value of a // Position struct is useful. // // When laying out a list, if ScrollToEnd is true and BeforeEnd is false, // then First and Offset are ignored, and the list is drawn with the last // item at the bottom. If ScrollToEnd is false then BeforeEnd is ignored. BeforeEnd bool // First is the index of the first visible child. First int // Offset is the distance in pixels from the top edge to the child at index // First. Offset int }
Position is a List scroll offset represented as an offset from the top edge of a child element.
type Spacing ¶
type Spacing uint8
Spacing determine the spacing mode for a Flex.
const ( // SpaceEnd leaves space at the end. SpaceEnd Spacing = iota // SpaceStart leaves space at the start. SpaceStart // SpaceSides shares space between the start and end. SpaceSides // SpaceAround distributes space evenly between children, // with half as much space at the start and end. SpaceAround // SpaceBetween distributes space evenly between children, // leaving no space at the start and end. SpaceBetween // SpaceEvenly distributes space evenly between children and // at the start and end. SpaceEvenly )
type Stack ¶
type Stack struct { // Alignment is the direction to align children // smaller than the available space. Alignment Direction }
Stack lays out child elements on top of each other, according to an alignment direction.
Example ¶
package main import ( "fmt" "image" "github.com/gop9/olt/gio/layout" ) func main() { gtx := new(layout.Context) gtx.Reset(nil, image.Point{X: 100, Y: 100}) gtx.Constraints.Width.Min = 0 gtx.Constraints.Height.Min = 0 layout.Stack{}.Layout(gtx, // Force widget to the same size as the second. layout.Expanded(func() { fmt.Printf("Expand: %v\n", gtx.Constraints) layoutWidget(gtx, 10, 10) }), // Rigid 50x50 widget. layout.Stacked(func() { layoutWidget(gtx, 50, 50) }), ) } func layoutWidget(ctx *layout.Context, width, height int) { ctx.Dimensions = layout.Dimensions{ Size: image.Point{ X: width, Y: height, }, } }
Output: Expand: {{50 100} {50 100}}
func (Stack) Layout ¶
func (s Stack) Layout(gtx *Context, children ...StackChild)
Layout a stack of children. The position of the children are determined by the specified order, but Stacked children are laid out before Expanded children.
type StackChild ¶
type StackChild struct {
// contains filtered or unexported fields
}
StackChild represents a child for a Stack layout.
func Expanded ¶
func Expanded(w Widget) StackChild
Expanded returns a Stack child that is forced to take up at least the the space as the largest Stacked.
func Stacked ¶
func Stacked(w Widget) StackChild
Stacked returns a Stack child that laid out with the same maximum constraints as the Stack.