Documentation
¶
Overview ¶
Package component features a framework, inspired by React and Redux, that allows you to extend the basic ui package with custom Components on top of plain ui Elements.
Index ¶
- Variables
- func After(duration time.Duration, fn func())
- func CreateImage(img image.Image) *ui.Image
- func Defer(fn func())
- func Dispatch(action interface{})
- func GetFont(family, style string) *ui.Font
- func Initialize(window *ui.Window, instance Instance)
- func InjectContext(target interface{})
- func InjectStore(target interface{})
- func IsEqualData(old, new interface{}) bool
- func Once(fn func())
- func OpenFontCollection(uri string)
- func OpenImage(uri string) *ui.Image
- func RegisterContext(value interface{})
- func Schedule(fn func())
- func UseLifecycle(constructor func(handle LifecycleHandle) Lifecycle, target ...interface{})
- func Window() *ui.Window
- func WithCallbackData(callbackData interface{})
- func WithChild(key string, instance Instance)
- func WithChildren(children []Instance)
- func WithContext(context interface{})
- func WithData(data interface{})
- func WithLayoutData(layoutData interface{})
- type BaseController
- type BaseLifecycle
- type CallbackMapFunc
- type Component
- type ComponentFunc
- type ConnectMapping
- type Controller
- type ControllerCallback
- type ControllerSubscription
- type DataMapFunc
- type ElementData
- type Instance
- type Lifecycle
- type LifecycleHandle
- type Overlay
- type Properties
- func (p Properties) CallbackData() interface{}
- func (p Properties) Children() []Instance
- func (p Properties) Data() interface{}
- func (p Properties) InjectCallbackData(target interface{})
- func (p Properties) InjectData(target interface{})
- func (p Properties) InjectLayoutData(target interface{})
- func (p Properties) InjectOptionalCallbackData(target, defaultValue interface{})
- func (p Properties) InjectOptionalData(target, defaultValue interface{})
- func (p Properties) InjectOptionalLayoutData(target, defaultValue interface{})
- func (p Properties) LayoutData() interface{}
- type Reducer
- type State
- type Store
- type StoreProviderData
- type StoreProviderEntry
Constants ¶
This section is empty.
Variables ¶
var Element = Define(func(props Properties) Instance { var element *ui.Element UseState(func() interface{} { return uiCtx.CreateElement() }).Inject(&element) Defer(func() { element.Destroy() }) var data ElementData props.InjectData(&data) element.SetEssence(data.Essence) if data.Enabled.Specified { element.SetEnabled(data.Enabled.Value) } if data.Visible.Specified { element.SetVisible(data.Visible.Value) } if data.Focusable.Specified { element.SetFocusable(data.Focusable.Value) } if data.IdealSize.Specified { element.SetIdealSize(data.IdealSize.Value) } element.SetLayout(data.Layout) element.SetPadding(data.Padding) element.SetLayoutConfig(props.LayoutData()) return Instance{ element: element, children: props.Children(), } })
Element represents the most basic component, which is translated to an ui Element. All higher-order components will eventually boil down to an Element.
var StoreProvider = Define(func(props Properties) Instance { var ( data StoreProviderData stores []*Store ) props.InjectData(&data) UseState(func() interface{} { result := make([]*Store, len(data.Entries)) for i, entry := range data.Entries { result[i] = CreateStore(entry.Reducer, entry.InitialValue) } return result }).Inject(&stores) Defer(func() { for _, store := range stores { store.Destroy() } }) return New(Element, func() { WithData(ElementData{ Layout: ui.NewFillLayout(), }) WithChildren(props.children) }) })
StoreProvider is a convenience component that manages the lifecycle of a set of Stores.
Using StoreProvider can be used as an optimization, since the lifecycle of the Stores is determined by the lifecycle of the given StoreProvider. If certain Store should be available only in the context of a given component hierarchy (e.g. a wizard dialog) it might make sense to wrap that hierarchy with such a StoreProvider.
Should you go down this route, however, make sure that only nested components try to access Stores that are managed by this StoreProvider.
Functions ¶
func After ¶
After will schedule a closure function to be run after the specified amount of time. The closure is guaranteed to run on the UI thread and the framework ensures that the closure will not be called if the component had been destroyed in the meantime.
Normally, you would use this function within a Once block or as a result of a callback. Not doing so would cause the closure function to be scheduled on every rendering of the component. As the framework is free to render a component at any time it deems necessary, it is unlikely that a user would like to have a function scheduled in an undeterministic way.
func CreateImage ¶ added in v0.3.0
CreateImage delegates to the UI window context to create the specified image.
func Defer ¶
func Defer(fn func())
Defer can be used to perform a cleanup action. The framework will issue one final render of a component before it gets destroyed. During that final render all closure functions specified via the Defer function will be invoked in the respective order.
Similar to Once, Defer can be used multiple times within a component's render function.
func Dispatch ¶
func Dispatch(action interface{})
Dispatch is the mechanism through which Stores get modified. An action is provided and all Reducers attempt to process the action. Should a reducer change it's Store's value then all connected components are reconciled.
func GetFont ¶
GetFont retrieves the font with the specified family and style.
Keep in mind that the necessary fonts should have been loaded via OpenFontCollection beforehand, otherwise this method will panic if it is unable to find the requested font.
func Initialize ¶
Initialize wires the framework to the specified ui Window. The specified instance will be the root component used.
func InjectContext ¶
func InjectContext(target interface{})
InjectContext retrieves the appropriate context and assigns it to target.
The specified target must be a pointer to the type that was used in RegisterContext.
func InjectStore ¶
func InjectStore(target interface{})
InjectStore is a helper function that allows one to discover and access and arbitrary Store's value.
The function uses the type of the referenced value by the target pointer to determine which Store should be used.
func IsEqualData ¶ added in v0.3.0
func IsEqualData(old, new interface{}) bool
IsEqualData compares if the two data objects are equal
func Once ¶
func Once(fn func())
Once can be used to perform an initialization action in a component's render function. During subsequent renders for the same component instance, the specified closure function will not be called.
You can use Once multiple times within a component's render function and all closure functions will be called in the respective order.
func OpenFontCollection ¶
func OpenFontCollection(uri string)
OpenFontCollection delegates to the UI window context to open the specified font collection.
func RegisterContext ¶
func RegisterContext(value interface{})
RegisterContext registers a data structure that will be accessible from all components.
If used, this method should be use during bootstrapping and should not be called from within components.
The context is stored according to its type and there can be only one call per struct type. Once a context is set it is persisted for the whole lifecycle of the framework.
Contexts should be used only for global configurations that will not change, like graphics handles or translation functions.
func Schedule ¶
func Schedule(fn func())
Schedule will schedule a closure function to run as soon as possible on the UI thread.
Normally this would be used when a certain processing is being performed on a separate go routine and the result needs to be passed back to the UI thread.
The framework ensures that the closure will not be called if the component had been destroyed in the meantime.
func UseLifecycle ¶ added in v0.3.0
func UseLifecycle(constructor func(handle LifecycleHandle) Lifecycle, target ...interface{})
func WithCallbackData ¶
func WithCallbackData(callbackData interface{})
WithCallbackData specifies the callback data to be passed to the component during instantiation.
Callback data is a mechanism for one component to listen for events on instanced components.
As callback data is expected to be a struct of function fields, they are not comparable in Go and as such cannot follow the lifecycle of data or layout data.
func WithChild ¶
WithChild adds a child to the given component. The child is appended to all previously registered children via the same method.
The key property is important. If in a subsequent render a component's child changes key or component type, the old one will be destroyed and a new one will be created. As such, to maintain a more optimized rendering and to prevent state loss, children should have a key assigned to them.
func WithChildren ¶
func WithChildren(children []Instance)
WithChildren sets the children for the given component. Keep in mind that any former children assigned via WithChild are replaced.
func WithContext ¶
func WithContext(context interface{})
WithContext can be used during the instantiation of an Application in order to configure a context object.
This is a helper function in place of RegisterContext. While currently not enforced, you should use this function during the instantiation of your root component. Using it at a later point during the lifecycle of your application could indicate an improper usage of contexts. You may consider using reducers and global state instead.
func WithData ¶
func WithData(data interface{})
WithData specifies the data to be passed to the component during instantiation.
Your data should be comparable in order to enable optimizations done by the framework. If you'd like to pass functions, in case of callbacks, they can be passed through callback data.
func WithLayoutData ¶
func WithLayoutData(layoutData interface{})
WithLayoutData specifies the layout data to be passed to the component during instantiation.
LayoutData is kept separate by the framework as it is expected to have a different lifecycle (changes might be rare) and as such can be optimized.
Your layout data should be comparable in order to enable optimizations done by the framework.
Types ¶
type BaseController ¶ added in v0.3.0
type BaseController struct {
// contains filtered or unexported fields
}
func (*BaseController) Alter ¶ added in v0.3.0
func (c *BaseController) Alter(fn func() error) error
func (*BaseController) NotifyChanged ¶ added in v0.3.0
func (c *BaseController) NotifyChanged()
func (*BaseController) Subscribe ¶ added in v0.3.0
func (c *BaseController) Subscribe(callback ControllerCallback) ControllerSubscription
type BaseLifecycle ¶ added in v0.3.0
type BaseLifecycle struct { }
func (*BaseLifecycle) OnCreate ¶ added in v0.3.0
func (l *BaseLifecycle) OnCreate(props Properties)
func (*BaseLifecycle) OnDestroy ¶ added in v0.3.0
func (l *BaseLifecycle) OnDestroy()
func (*BaseLifecycle) OnUpdate ¶ added in v0.3.0
func (l *BaseLifecycle) OnUpdate(props Properties)
type CallbackMapFunc ¶
type CallbackMapFunc func(props Properties) interface{}
CallbackMapFunc controls how a connected component's data is calculated.
type Component ¶
type Component struct {
// contains filtered or unexported fields
}
Component represents a definition for a component.
func Connect ¶
func Connect(delegate Component, mapping ConnectMapping) Component
Connect is the mechanism through which a Component gets wired to the global Stores. A connected component will get invalidated when one of the Stores gets changed.
The Connect method is used to wrap an existing Component and the mapping configuration can be used to adjust the delegate component's data and callback data based on the Store state.
func Controlled ¶ added in v0.3.0
func Define ¶
func Define(fn ComponentFunc) Component
Define can be used to describe a new component. The provided component function (or render function) will be called by the framework to initialize, reconcicle, or destroy a component instance.
func ShallowCached ¶
ShallowCached can be used to wrap a component and optimize reconciliation by avoiding the rerendering of the component if the data and layout data are equal to their previous values when shallowly (==) compared.
type ComponentFunc ¶
type ComponentFunc func(props Properties) Instance
ComponentFunc holds the logic and layouting of the component.
type ConnectMapping ¶
type ConnectMapping struct { // Data, if specified, controls the data to be passed to the // delegate component. If nil, then the original data is passed through. Data DataMapFunc // Callback, if specified, controls the callback data to be passed to the // delegate component. If nil, then the original callback data is passed // through. Callback CallbackMapFunc }
ConnectMapping is a configuration mechanism to wire a connected component to its delegate.
type Controller ¶ added in v0.3.0
type Controller interface { Subscribe(callback ControllerCallback) ControllerSubscription Alter(func() error) error NotifyChanged() }
func NewBaseController ¶ added in v0.3.0
func NewBaseController() Controller
type ControllerCallback ¶ added in v0.3.0
type ControllerCallback func(controller Controller)
type ControllerSubscription ¶ added in v0.3.0
type ControllerSubscription interface {
Unsubscribe()
}
type DataMapFunc ¶
type DataMapFunc func(props Properties) interface{}
DataMapFunc controls how a connected component's data is calculated.
type ElementData ¶
type ElementData struct { Essence ui.Essence Enabled optional.Bool Visible optional.Bool Focusable optional.Bool IdealSize optional.Size Padding ui.Spacing Layout ui.Layout }
ElementData is the struct that should be used when configuring an Element component's data.
type Instance ¶
type Instance struct {
// contains filtered or unexported fields
}
Instance represents the instantiation of a given Component.
func New ¶
New instantiates the specified component. The setup function is used to apply configurations to the component in a user-friendly manner.
Note: creating an instance with New does not necessarily mean that a component will be freshly instantiated. If this occurs during rendering the framework will reuse former instances when possible.
type Lifecycle ¶ added in v0.3.0
type Lifecycle interface { OnCreate(props Properties) OnUpdate(props Properties) OnDestroy() }
func NewBaseLifecycle ¶ added in v0.3.0
func NewBaseLifecycle() Lifecycle
type LifecycleHandle ¶ added in v0.3.0
type LifecycleHandle struct {
// contains filtered or unexported fields
}
func (LifecycleHandle) NotifyChanged ¶ added in v0.3.0
func (h LifecycleHandle) NotifyChanged()
type Overlay ¶ added in v0.3.0
type Overlay struct {
// contains filtered or unexported fields
}
func OpenOverlay ¶ added in v0.3.0
type Properties ¶
type Properties struct {
// contains filtered or unexported fields
}
Properties is a holder for all data necessary to render a component.
func (Properties) CallbackData ¶
func (p Properties) CallbackData() interface{}
CallbackData returns the callback data that can be used by the component to notify its instantiator regarding key events.
func (Properties) Children ¶
func (p Properties) Children() []Instance
Children returns all the child instances that this component should host.
func (Properties) Data ¶
func (p Properties) Data() interface{}
Data returns the configuration data needed to render the component.
func (Properties) InjectCallbackData ¶
func (p Properties) InjectCallbackData(target interface{})
InjectCallbackData is a helper function that injects the CallbackData into the specified target, which should be a pointer to the correct type.
func (Properties) InjectData ¶
func (p Properties) InjectData(target interface{})
InjectData is a helper function that injects the Data into the specified target, which should be a pointer to the correct type.
func (Properties) InjectLayoutData ¶
func (p Properties) InjectLayoutData(target interface{})
InjectLayoutData is a helper function that injects the LayoutData into the specified target, which should be a pointer to the correct type.
func (Properties) InjectOptionalCallbackData ¶
func (p Properties) InjectOptionalCallbackData(target, defaultValue interface{})
InjectOptionalCallbackData is a helper function that injects the CallbackData into the specified target, which should be a pointer to the correct type or if there is no callback data, it injects the default one.
func (Properties) InjectOptionalData ¶
func (p Properties) InjectOptionalData(target, defaultValue interface{})
InjectOptionalData is a helper function that injects the Data into the specified target, which should be a pointer to the correct type of if there is no data, it injects the default one.
func (Properties) InjectOptionalLayoutData ¶
func (p Properties) InjectOptionalLayoutData(target, defaultValue interface{})
InjectOptionalLayoutData is a helper function that injects the LayoutData into the specified target, which should be a pointer to the correct type or if there is no layout data, it injects the default one.
func (Properties) LayoutData ¶
func (p Properties) LayoutData() interface{}
LayoutData returns the layout data needed to layout the component.
type Reducer ¶
type Reducer func(store *Store, action interface{}) interface{}
Reducer is a mechanism through which a Store's value is changed. It is sent actions and is required to return the changed value according to the specified action. If the Reducer returns the old state of the Store, then it is considered that the action is not applicable for this Reducer.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State represents a persistent state of a component. Every render operation for a component would return the same sequence of states.
func UseState ¶
func UseState(fn func() interface{}) *State
UseState registers a new State object to the given component.
During component initialization, the closure function will be called to retrieve an initial value to be assigned to the state.
The order in which this function is called inside a component's render function is important. As such, every component render should issue exactly the same UseState calls and in the exacly the same order.
func (*State) Get ¶
func (s *State) Get() interface{}
Ge returns the current value stored in this State.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store represents a state that can cross component boundaries, which allows multiple components to share the same source of truth.
func CreateStore ¶
CreateStore creates a new Store instance.
The specified reducer will be responsible for handling dispatched actions and adjusting the store's state.
The initialValue should be of the same type that the reducer will operate on and can be used to initialize the Store.
Note that similarly to Contexts, there can only be one Store instance per value type. Unlike Contexts, however, Stores are intended to have their value change throughout the lifecycle of the application.
type StoreProviderData ¶
type StoreProviderData struct { // Entries contains the definition of all Stores that should be managed // by the given StoreProvider. Entries []StoreProviderEntry }
StoreProviderData is the data necessary to instantiate a StoreProvider.
Note that the StoreProvider caches the Stores it creates and a reconciliation with a different data will be ignored.
type StoreProviderEntry ¶
type StoreProviderEntry struct { // Reducer specifies the Reducer that will be passed to CreateStore. Reducer Reducer // InitialValue specifies the initialValue that will be passed to CreateStore. InitialValue interface{} }
StoreProviderEntry represents a single Store instance.
func NewStoreProviderEntry ¶
func NewStoreProviderEntry(reducer Reducer, initialValue interface{}) StoreProviderEntry
NewStoreProviderEntry is a helper function to quickly create a StoreProviderEntry value.