#[property]
Expand description
Expands a function to a widget property.
Property functions take one UiNode
child input and one or more other inputs and produces an UiNode
that implements
the property feature.
The attribute expansion does not modify the function, it can still be used as a function directly. Some properties are implemented by calling other property functions to generate a derived effect.
The attribute expansion generates a hidden trait of the same name and visibility, the trait is implemented for widget builders,
the widget macros use this to set the property. Because it has the same name it is imported together with the property
function, in practice this only matters in doc links where you must use the fn@
disambiguator.
§Attribute
The property attribute has one required argument and three optional.
§Nest Group
The first argument is the property NestGroup
. The group defines the overall nest position
of the property, for example, LAYOUT
properties always wrap FILL
properties. This is important as widgets are open and any combination
of properties may end-up instantiated in the same widget.
use zng::prelude_wgt::*;
#[property(LAYOUT)]
pub fn align(child: impl UiNode, align: impl IntoVar<Align>) -> impl UiNode {
// ..
}
The nest group can be tweaked, by adding or subtracting integers, in the example bellow both properties are in the SIZE
group,
but size
is always inside max_size
.
use zng::prelude_wgt::*;
#[property(SIZE+1)]
pub fn size(child: impl UiNode, size: impl IntoVar<Size>) -> impl UiNode {
// ..
}
#[property(SIZE)]
pub fn max_size(child: impl UiNode, size: impl IntoVar<Size>) -> impl UiNode {
// ..
}
§Default
The next argument is an optional default(args..)
. It defines the value to use when the property must be instantiated and no value was provided.
The defaults should cause the property to behave as if it is not set, as the default value will be used in widgets that only set the
property in when
blocks.
use zng::prelude_wgt::*;
#[property(FILL, default(rgba(0, 0, 0, 0)))]
pub fn background_color(child: impl UiNode, color: impl IntoVar<Rgba>) -> impl UiNode {
// ..
}
In the example above the background_color
defines a transparent color as the default, so if the background color is only set in a when
block if will only be visible when it is active.
For properties with multiple inputs the default args may be defined in a comma separated list of params, default(dft0, ..)
.
§Impl For
The last argument is an optional impl(<widget-type>)
, it strongly associates
the property with a widget, users can set this property on the widget without needing to import the property.
Note that this makes the property have priority over all others of the same name, only a derived widget can override with another strongly associated property.
Note that you can also use the widget_impl!
in widget declarations to implement existing properties for a widget.
§Capture
After the nest group and before default the , capture,
value indicates that the property is capture-only. This flag
changes how the property must be declared, the first argument is a property input and the function can have only one input,
no return type is allowed and the function body must be empty, unused input warnings are suppressed by the expanded code.
Capture-only properties must be captured by a widget and implemented as part of the widget’s intrinsics, the reason for a property function is purely to define the property signature and metadata, the capture-only property function can also be used to set a property dynamically, such as in a style widget that is applied on the actual widget that captures the property.
A documentation sections explaining capture-only properties is generated for the property, it is also tagged differently in the functions list.
use zng::prelude_wgt::*;
/// Children property, must be captured by panel widgets.
#[property(CONTEXT, capture)]
pub fn children(children: impl UiNodeList) { }
§Args
The property function requires at least two args, the first is the child node and the other(s) the input values. The number and type of inputs is validated at compile time, the types are limited and are identified and validated by their token name, so you cannot use renamed types.
§Child
The first function arg must be of type impl UiNode
, it represents the child node and the property node must
delegate to it so that the UI tree functions correctly. The type must be an impl
generic, a full path to UiNode
is allowed, but no import renames as the proc-macro attribute can only use tokens to identify the type.
§Inputs
The second arg and optional other args define the property inputs. When a property is assigned in a widget only these inputs
are defined by the user, the child arg is provided by the widget builder. Property inputs are limited, and must be identifiable
by their token name alone. The types are validated at compile time, they must be declared using impl
generics,
a full path to the generic traits is allowed, but no import renames.
§Input Types
These are the allowed input types:
§impl IntoVar<T>
The most common type, accepts any value that can be converted IntoVar<T>
, usually the property defines the T
, but it can be generic.
The property node must respond to var updates. The input kind is InputKind::Var
. No auto-default is generated for this type, property
implementation should provide a default value that causes the property to behave as if it was not set.
The input can be read in when
expressions and can be assigned in when
blocks.
§impl IntoValue<T>
Accepts any value that can be converted IntoValue<T>
that does not change, usually the property
defines the T
, but it can be generic. The input kind is InputKind::Value
. No auto-default is generated for this type.
The input can be read in when
expressions, but cannot be assigned in when
blocks.
§impl UiNode
This input accepts another UiNode
, the implementation must handle it like it handles the child node, delegating all methods. The
input kind is InputKind::UiNode
. The NilUiNode
is used as the default value if no other is provided.
The input cannot be read in when
expressions, but can be assigned in when
blocks.
§impl UiNodeList
This input accepts an UiNodeList
, the implementation must handle it like it handles the child node, delegating all methods. The
input kind is InputKind::UiNodeList
. An empty list is used as the default value if no other is provided.
The input cannot be read in when
expressions, but can be assigned in when
blocks.
§impl WidgetHandler<A>
This input accepts any WidgetHandler<A>
for the argument type A
, usually the property defines the A
, but it can be generic.
The input kind is InputKind::WidgetHandler
. A no-op handler is used for the default if no other is provided.
Event handler properties usually have the on_
name prefix. You can use the event_property!
macro to generate standard event properties.
The input cannot be read in when
expressions, but can be assigned in when
blocks.
§Getter Properties
Most properties with var inputs are setters, that is the inputs affect the widget. Some properties
can be getters, detecting widget state and setting it on the input variable. These properties are usually named with
a prefix that indicates their input is actually for getting state, the prefixes is_
and has_
mark a property with
a single bool
input that reads a widget state, the prefix get_
and actual_
marks a property that reads a non-boolean state from
the widget.
Getter properties are configured with a default read-write variable, so that they can be used in when
expressions directly,
for example, when *#is_pressed
, the is_pressed
property has a default(var(false))
, so it automatically initializes
with a read-write variable that is used in the when condition. The property attribute generates defaults automatically
based on the prefix, the default is var(T::default())
, this can be overwritten just by setting the default,
it is not possible to declare a getter property without default.
Note that if a property is used in when
condition without being set and without default value the when block is discarded on
widget build. If you are implementing a getter property that is not named using the prefixes listed above you must set default(var(T::default())
.
§Generics
Apart from the impl
generics of inputs and child, there is some support for named generic types, only one named generic is allowed
for inputs impl IntoVar<T>
, impl IntoValue<T>
and impl WidgetHandler<A>
.
§Output
The property output type must be any type that implements UiNode
, usually an opaque type impl UiNode
is used. The property
node can be anything, as long as it delegates to the child node, see match_node
or ui_node
about implementing a node.
Some common property patterns have helper functions, for example, to setup a context var you can use the with_context_var
function.
§More Details
See property_id!
and property_args!
for more details about what kind of meta-code is generated for properties.
Expands a function to a widget property.
§Full Documentation
Read the documentation in the zng::widget::property
page.