template class EE::UI::UIDataBind

Overview

Synchronizes a value with one or more UIWidget properties. More…

#include <uidatabind.hpp>

template <typename T>
class UIDataBind {
public:
    // typedefs

    typedef T ValueType;
    typedef UIValueConverter<T> Converter;
    typedef typename ObservableValue<T>::Callback Callback;
    typedef typename ObservableValue<Uint64>::Connection Connection;

    // classes

    class CallbackSlot;

    // fields

    CallbackSlot onValueChangeCb;

    // construction

    UIDataBind();
    UIDataBind(const UIDataBind&);
    UIDataBind(UIDataBind&&);
    UIDataBind(T* t, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    UIDataBind(T* t, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    UIDataBind(std::shared_ptr<T> value, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    UIDataBind(std::shared_ptr<T> value, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    ~UIDataBind();

    // methods

    static Converter converterDefault();
    static Converter converterString();
    static Converter converterBool();
    static std::unique_ptr<UIDataBind<T>> New(T* t, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    static std::unique_ptr<UIDataBind<T>> New(T* t, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    static std::unique_ptr<UIDataBind<T>> New(std::shared_ptr<T> value, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    static std::unique_ptr<UIDataBind<T>> New(std::shared_ptr<T> value, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    UIDataBind& operator=(const UIDataBind&);
    UIDataBind& operator=(UIDataBind&&);
    void init(T* t, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    void init(T* t, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    void init(std::shared_ptr<T> value, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);
    void init(std::shared_ptr<T> value, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);

    template <typename Widgets>
    void initRetained(T* value, std::shared_ptr<void> owner, Widgets&& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange);

    UIValueValidationResult set(const T& t);
    UIValueValidationResult set(T&& t);
    const T& get() const;
    Connection observe(Callback callback);
    bool isInitialized() const;
    void reset();
    void bind(UIWidget* widget);
    void unbind(UIWidget* widget);
    const PropertyDefinition* getPropertyDefinition() const;
    const UnorderedSet<UIWidget*>& getWidgets() const;
    UIWidget* getValidationEmitter() const;
    UIValueValidationState& validationState();
    const UIValueValidationState& validationState() const;
    bool isValid() const;
};

Detailed Documentation

Synchronizes a value with one or more UIWidget properties.

UIDataBind observes each widget’s value event and writes converted values back to the external object supplied at construction. Calling set() updates that object and propagates the converted value to every bound widget.

The converter maps directly between T and the widget property string. Its toValue() callback decides whether widget input is acceptable. Values passed to set() are authoritative model state and are formatted through fromValue().

Raw-pointer bindings do not own their value. The external object must outlive the UIDataBind and every synchronous callback delivery, or reset() must be called before it is destroyed. The shared_ptr overload retains the value through binding lifetime and callback delivery without copying T. UIProperty uses that retained form automatically.

Widgets are also observed without ownership: EventConnection handles remove listeners when the binding dies, while the widget-level Event::OnClose notification removes widgets that die before the binding. All binding operations and widget events must run on the widgets’ owning UI thread. The class is non-copyable and non-movable because its listeners capture its address.

Use UIDataBind when adapting an existing externally owned value and its lifetime is already controlled by the caller. Prefer UIProperty for small UI-local state, or ObservableValue with UIValueBinding when the model must publish changes without depending on the UI.

bool showDetails = false;
auto binding = UIDataBind<bool>::New(
    &showDetails, checkbox, UIValueConverter<bool>::converterBool() );
// 'binding' must be destroyed or reset before 'showDetails'.

Methods

static std::unique_ptr<UIDataBind<T>> New(std::shared_ptr<T> value, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange)

Creates a binding that retains value through callback delivery.

static std::unique_ptr<UIDataBind<T>> New(std::shared_ptr<T> value, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange)

Creates a binding that retains value through callback delivery.

void init(std::shared_ptr<T> value, const UnorderedSet<UIWidget*>& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange)

Reinitializes the binding while retaining value.

void init(std::shared_ptr<T> value, UIWidget* widget, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange)

Reinitializes the binding for one widget while retaining value.

template <typename Widgets>
void initRetained(T* value, std::shared_ptr<void> owner, Widgets&& widgets, const Converter& converter = Converter::converterDefault(), const std::string& valueKey = "value", const Event::EventType& eventType = Event::OnValueChange)

Reinitializes the binding with externally retained storage.

owner must keep value alive. This supports values embedded in a larger shared state without constructing an aliasing shared_ptr or allocating a separate value control block.

UIValueValidationResult set(const T& t)

Propagates the authoritative model value and reports formatting failures.

UIValueValidationResult set(T&& t)

Propagates the authoritative model value and reports formatting failures.

Connection observe(Callback callback)

Observes later changes made through this binding.

Direct writes through the external pointer cannot be observed; use set() for model-originated changes that must be published. Notifications publish an integer revision internally, so T is never copied for observer delivery. Shared bindings retain their value in each observer adapter; raw bindings require the external value to survive the complete callback sequence.

Returns:

A scoped connection, or an empty connection when the binding is not initialized.

bool isInitialized() const

Returns:

True when the binding has a valid external value, property, and converter.

void reset()

Disconnects every widget and releases the reference to the external value.

After reset(), the binding must be initialized again before get() or set() is used.

void bind(UIWidget* widget)

Adds widget to the synchronized widget set. Duplicate binds are ignored.

void unbind(UIWidget* widget)

Disconnects and removes widget from the synchronized widget set.

UIWidget* getValidationEmitter() const

Returns:

The widget that produced the current input error, or nullptr for valid state or a model-to-widget formatting error.

UIValueValidationState& validationState()

Returns:

Observable converter error state for this binding.