Documentation ¶
Overview ¶
Package base provides interfaces for the description, creation, and updating of GUI widgets. Any users interested in creating new widgets will need to implement the interfaces Widget and Element described herein.
GUI state is managed using three groups of types. There are 'widgets', which are data-only representations of a desired GUI. These widgets can be mounted to create 'elements', which manage actual, visible GUI resources. The elements manage child elements, some number of platform-specific resources, called 'controls', or both.
Additionally, this package contains geometric types. These types support the automatic layout of widgets in a platform independent manner. The layout algorithm is roughly based on Flutter.
Index ¶
- Variables
- func CloseElements(children []Element)
- type Constraints
- func (bc Constraints) Constrain(size Size) Size
- func (bc Constraints) ConstrainAndAttemptToPreserveAspectRatio(size Size) Size
- func (bc Constraints) ConstrainHeight(height Length) Length
- func (bc Constraints) ConstrainWidth(width Length) Length
- func (bc Constraints) HasBoundedHeight() bool
- func (bc Constraints) HasBoundedWidth() bool
- func (bc Constraints) HasTightHeight() bool
- func (bc Constraints) HasTightWidth() bool
- func (bc Constraints) Inset(width Length, height Length) Constraints
- func (bc Constraints) IsBounded() bool
- func (bc Constraints) IsNormalized() bool
- func (bc Constraints) IsSatisfiedBy(size Size) bool
- func (bc Constraints) IsTight() bool
- func (bc Constraints) IsZero() bool
- func (bc Constraints) Loosen() Constraints
- func (bc Constraints) LoosenHeight() Constraints
- func (bc Constraints) LoosenWidth() Constraints
- func (bc Constraints) Tighten(size Size) Constraints
- func (bc Constraints) TightenHeight(height Length) Constraints
- func (bc Constraints) TightenWidth(width Length) Constraints
- type Control
- type Element
- type Kind
- type Length
- type NativeElement
- type Point
- type Rectangle
- type Size
- type Widget
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // DPI contains the current DPI (dots per inch) of the monitor. // User code should not need to set this directly, as drivers will update // this variable as necessary. DPI image.Point )
Functions ¶
func CloseElements ¶
func CloseElements(children []Element)
CloseElements closes all of the elements contained in a slice. This is a utility function to help containers close all of their children when required.
Types ¶
type Constraints ¶
type Constraints struct {
Min, Max Size
}
Constraints represents box constraints on width and height for the layout of rectangular widgets. For each dimension, the constraints specify the minimum and maximum allowed size for a widget.
The constraints on a dimension are called 'tight' if the minimum and maximum values are equal, which essential requires the widget to take a fixed size. On the other hand, if the minimum allowed value is zero, then the constraints on that dimension is 'loose'.
A sentinel value can be used to indicate that the maximum size for a dimension is infinite. The constraints on that dimension are called 'unbounded'.
(This type is similar to BoxConstraints type in flutter library rendering)
func Expand ¶
func Expand() Constraints
Expand creates box constraints that allows elements to expand to as large as possible. The constraints for both width and height will be loose and unbounded.
func ExpandHeight ¶
func ExpandHeight(width Length) Constraints
ExpandHeight creates box constraints with a fixed width and that forces elements to expand to as high as possible. The constraint for width will be tight. The constraint for height will be loose and unbounded.
func ExpandWidth ¶
func ExpandWidth(height Length) Constraints
ExpandWidth creates box constraints with a fixed height and that forces elements to expand to as wide as possible. The constraint for width will be loose and unbounded. The constraint for height will be tight.
func Loose ¶
func Loose(size Size) Constraints
Loose creates box constraints that forbid sizes larger than the given size. The constraints for both width and height will be loose and bounded.
func Tight ¶
func Tight(size Size) Constraints
Tight creates a box constraints that is respected only by the given size.
func TightHeight ¶
func TightHeight(height Length) Constraints
TightHeight creates a box constraints that is respected only by sizes with the given height. The width is unconstrained (i.e. loose and unbounded).
func TightWidth ¶
func TightWidth(width Length) Constraints
TightWidth creates a box constraints that is respected only by sizes with the given width. The height is unconstrained (i.e. loose and unbounded).
func (Constraints) Constrain ¶
func (bc Constraints) Constrain(size Size) Size
Constrain returns the size that satisfies the constraints while staying as close as possible to the passed size.
func (Constraints) ConstrainAndAttemptToPreserveAspectRatio ¶
func (bc Constraints) ConstrainAndAttemptToPreserveAspectRatio(size Size) Size
ConstrainAndAttemptToPreserveAspectRatio returns the size that satisfies the constraints while staying close to the passed size and maintaining the aspect ratio of the passed size.
func (Constraints) ConstrainHeight ¶
func (bc Constraints) ConstrainHeight(height Length) Length
ConstrainHeight returns the length that satisfies the constraints for height while staying as close as possible to the passed height.
func (Constraints) ConstrainWidth ¶
func (bc Constraints) ConstrainWidth(width Length) Length
ConstrainWidth returns the length that satisfies the constraints for width while staying as close as possible to the passed height.
func (Constraints) HasBoundedHeight ¶
func (bc Constraints) HasBoundedHeight() bool
HasBoundedHeight is true if the maximum height is bounded.
func (Constraints) HasBoundedWidth ¶
func (bc Constraints) HasBoundedWidth() bool
HasBoundedWidth is true if the maximum width is bounded.
func (Constraints) HasTightHeight ¶
func (bc Constraints) HasTightHeight() bool
HasTightHeight is true if the height is tight (only one value of height satisfies the constraint).
func (Constraints) HasTightWidth ¶
func (bc Constraints) HasTightWidth() bool
HasTightWidth is true if the width is tight (only one value of width satisfies the constraint).
func (Constraints) Inset ¶
func (bc Constraints) Inset(width Length, height Length) Constraints
Inset returns a new set of box constraints such that a size that satisfies those new constraints can be increased by width and height and will satisfy the original constrains.
func (Constraints) IsBounded ¶
func (bc Constraints) IsBounded() bool
IsBounded is true if both the width and height are bounded.
func (Constraints) IsNormalized ¶
func (bc Constraints) IsNormalized() bool
IsNormalized is true if both the width and height constraints are normalized. A set of constraints are normalized if 0 <= Min <= Max.
func (Constraints) IsSatisfiedBy ¶
func (bc Constraints) IsSatisfiedBy(size Size) bool
IsSatisfiedBy returns true if the passed size satisfies the both the width and height constraints. Additionally, both width and height must be finite (i.e. not equal to the sentinal value Inf).
func (Constraints) IsTight ¶
func (bc Constraints) IsTight() bool
IsTight returns true if both the width and height are tightly constrained.
func (Constraints) IsZero ¶
func (bc Constraints) IsZero() bool
IsZero returns true if the bc is the zero value.
func (Constraints) Loosen ¶
func (bc Constraints) Loosen() Constraints
Loosen creates a new box constraint with the minimum width and height requirements removed.
func (Constraints) LoosenHeight ¶
func (bc Constraints) LoosenHeight() Constraints
LoosenHeight creates a new box constraint with the minimum height requirement removed.
func (Constraints) LoosenWidth ¶
func (bc Constraints) LoosenWidth() Constraints
LoosenWidth creates a new box constraint with the minimum width requirement removed.
func (Constraints) Tighten ¶
func (bc Constraints) Tighten(size Size) Constraints
Tighten creates a new box constraint with tight width and height requirements matching as closely as possible the passed size. The new constrains will be tight, but will only match the requested size if the size satisfies the original constraints.
func (Constraints) TightenHeight ¶
func (bc Constraints) TightenHeight(height Length) Constraints
TightenHeight creates a new box constraint with a tight height requirements matching as closely as possible the length. The new height constraints will be tight, but will only match the requested height if the height satisfies the original constraints.
func (Constraints) TightenWidth ¶
func (bc Constraints) TightenWidth(width Length) Constraints
TightenWidth creates a new box constraint with a tight width requirements matching as closely as possible the length. The new width constraints will be tight, but will only match the requested width if the width satisfies the original constraints.
type Control ¶
Control is an opaque type used as a platform-specific handle to a control created using the platform GUI. As an example, this will refer to a HWND when targeting Windows, but a *GtkContainer when targeting GTK.
Unless developping new widgets, users should not need to use this type.
Any methods on this type will be platform specific.
type Element ¶
type Element interface { // NativeElement provides platform-dependent methods. These should // not be used by client libraries, but exist for the internal implementation // of platform dependent code. NativeElement // Close removes the element from the GUI, and frees any associated resources. Close() // Kind returns the concrete type for the Element. // Users should not need to use this method directly. Kind() *Kind // Layout determines the best size for an element that satisfies the // constraints. Layout(Constraints) Size // MinIntrinsicHeight returns the minimum height that this element requires // to be correctly displayed. MinIntrinsicHeight(width Length) Length // MinIntrinsicWidth returns the minimum width that this element requires // to be correctly displayed. MinIntrinsicWidth(height Length) Length // SetBounds updates the position of the widget. SetBounds(bounds Rectangle) // UpdateProps will update the properties of the widget. The Kind for // the parameter data must match the Kind for the interface. UpdateProps(data Widget) error }
Element is an interface that wraps any type representing a control, or group of controls, created using the platform GUI. An element represents an instantiation of a Widget into visible parts of the GUI.
func DiffChild ¶
DiffChild adds and removes controls in a GUI to reconcile differences between the desired and current GUI state. Depending on the kind for both lhs and rhs, the current element may either be updated or replaced.
The element lhs should be considered as 'sunk' by this function, and will be closed if necessary. On the other hand, the caller will be responsible for the returned element. Note that the returned element may be non-nil even in the presence of an error.
If the rhs is nil, DiffChild will still return a non-nil element. See the function Method for more details.
func DiffChildren ¶
DiffChildren will update the list of elements to match the desired state. As necessary, widgets will be mounted to create new elements, and existing elements will be updated or closed to reconcile differences between the desired and current GUI state.
The elements contained in lhs should be considered as 'sunk' by this function, and will be closed if necessary. On the other hand, the caller will be responsible for all of the returned elements. Note that the returned slice of elements may be non-nil even in the presence of an error. Use CloseElements as necessary to avoid leaking controls.
DiffChildren will try to reuse the underlying array from lhs for the returned slice.
func Mount ¶
Mount will try to mount a widget. In the case where the widget is non-nil, this function is a simple wrapper around calling the method Mount directly. If widget is nil, this function will instead return a non-nil element, but an element with an intrinsic size of zero and no visible elements in the GUI.
Example ¶
// This won't work in real code, as the zero value for a control is not // generally useable. parent := Control{} // It is okay to mount a nil widget. elem, err := Mount(parent, nil) if err != nil { panic("Unexpected error!") } defer elem.Close() fmt.Println("The value of elem is nil...", elem == nil) fmt.Println("The kind of elem is...", elem.Kind())
Output: The value of elem is nil... false The kind of elem is... github.com/kjk/goey/base.nil
type Kind ¶
type Kind struct {
// contains filtered or unexported fields
}
Kind identifies the different kinds of widgets. Most widgets have two concrete types associated with their behaviour. First, there is a type with data to describe the widget when unmounted, which should implement the interface Widget. Second, there is a type with a handle to the windowing system when mounted, which should implement the interface Element. Automatic reconciliation of two widget trees relies on Kind to match the unmounted and mounted widgets.
Note that comparison of kinds is done by address, and not done using the value of any fields. Any internal state is simply to help with debugging.
type Length ¶
Length is a distance measured in device-independent pixels. There are nominally 96 DIPs per inch. This definition corresponds with the definition of a pixel for both CSS and on Windows.
Example ¶
// Since there are 96 device-independent pixels per inch, and 6 picas // per inch, the following two lengths should be equal. length1 := 96 * DIP length2 := 6 * PC if length1 == length2 { fmt.Printf("All is OK with the world.") } else { fmt.Printf("This should not happen, unless there is a rounding error.") }
Output: All is OK with the world.
const ( DIP Length = (1 << 6) // Device-independent pixel (1/96 inch) PT Length = ((96 << 6) / 72) // Point (1/72 inch) PC Length = ((96 << 6) / 6) // Pica (1/6 inch or 12 points) Inch Length = (96 << 6) // Inch from the British imperial system of measurements )
Common lengths used when describing GUIs. Note that the DIP (device-independent pixel) is the natural unit for this package. Because of limited precision, the PT listed here is somewhat smaller than its correct value.
const ( // Inf is a sentinel value indicating an unbounded (or infinite) length. Inf Length = 0x7fffffff )
func FromPixelsX ¶
FromPixelsX converts a distance measurement in physical pixels to DIPs, based on the current DPI settings for horizontal scaling.
func FromPixelsY ¶
FromPixelsY converts a distance measurement in physical pixels to DIPs, based on the current DPI settings for vertical scaling.
func (Length) Clamp ¶
Clamp ensures that the length is between the minimum and maximum values specified. Normally, min should be less than max. If that is not the case, then the returned will preferentially respect min.
func (Length) PixelsX ¶
PixelsX converts the distance measurement in DIPs to physical pixels, based on the current DPI settings for horizontal scaling.
func (Length) PixelsY ¶
PixelsY converts the distance measurement in DIPs to physical pixels, based on the current DPI settings for vertical scaling.
func (Length) Scale ¶
Scale scales the distance by the ratio of num:den.
Example ¶
// There are 96 DIP in an inch, and 6 pica in a inch, so the following // should work. if length := (1 * DIP).Scale(96, 6); length == (1 * PC) { fmt.Printf("The ratio of pica to DIP is 96 to 6.") }
Output: The ratio of pica to DIP is 96 to 6.
func (Length) String ¶
String returns a human readable distance.
Example ¶
fmt.Printf("Converting: 1pt is equal to %sdip\n", 1*PT) fmt.Printf("Converting: 1pt is equal to %1.2fdip\n", (1 * PT).DIP()) fmt.Printf("Converting: 1pc is equal to %1.1fdip\n", (1 * PC).DIP())
Output: Converting: 1pt is equal to 1:21dip Converting: 1pt is equal to 1.33dip Converting: 1pc is equal to 16.0dip
type NativeElement ¶
type NativeElement interface { }
NativeElement contains platform-specific methods that all widgets must support on GTK.
type Point ¶
type Point struct {
X, Y Length
}
A Point is an X, Y coordinate pair. The axes increase right and down. This type is a close analogy to image.Pixel, except that the coordinate pair is represented by Length rather than int.
type Rectangle ¶
type Rectangle struct {
Min, Max Point
}
A Rectangle contains the points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y. It is well-formed if Min.X <= Max.X and likewise for Y. Points are always well-formed. A rectangle's methods always return well-formed outputs for well-formed inputs.
This type is a close analogy to image.Rectangle, except that the coordinates are represented by Length rather than int.
Example ¶
r := Rectangle{Point{10 * DIP, 20 * DIP}, Point{90 * DIP, 80 * DIP}} fmt.Printf("Rectangle %s has dimensions %.0fdip by %.0fdip.", r, r.Dx().DIP(), r.Dy().DIP(), )
Output: Rectangle (10:00,20:00)-(90:00,80:00) has dimensions 80dip by 60dip.
func Rect ¶
Rect is shorthand for Rectangle{Point(x0, y0), Point(x1, y1)}. The returned rectangle has minimum and maximum coordinates swapped if necessary so that it is well-formed.
func (Rectangle) Pixels ¶
Pixels returns the rectangle with the X and Y coordinates measured in pixels.
Example ¶
// The following line is for the example only, and should not appear in // user code, as the platform-specific code should update the DPI based // on the system. However, for the purpose of this example, set a known // DPI. DPI = image.Point{2 * 96, 2 * 96} // Construct an example rectangle. r := Rectangle{Point{10 * DIP, 20 * DIP}, Point{90 * DIP, 80 * DIP}} rpx := r.Pixels() fmt.Printf("Rectangle %s when translated to pixels is %s.", r, rpx)
Output: Rectangle (10:00,20:00)-(90:00,80:00) when translated to pixels is (20,40)-(180,160).
type Size ¶
type Size struct {
Width, Height Length
}
Size represents the size of a rectangular element.
func FromPixels ¶
FromPixels converts the pixels into lengths based on the current DPI, and return the size.
Example ¶
// Most code should not need to worry about setting the DPI. Windows will // ensure that the DPI is set. DPI = image.Point{96, 96} size := FromPixels(48, 96+96) fmt.Printf("The size is %s.\n", size.String())
Output: The size is (48:00x192:00).
type Widget ¶
type Widget interface { // Kind returns the concrete type's Kind. The returned value should // be constant, and the same for all instances of a concrete type. // Users should not need to use this method directly. Kind() *Kind // Mount creates a widget or control in the GUI. The newly created widget // will be a child of the widget specified by parent. If non-nil, the returned // Element must have a matching kind. Mount(parent Control) (Element, error) }
Widget is an interface that wraps any type describing part of a GUI. A widget can be 'mounted' to create controls using the platform GUI.