azul_core::callbacks

Struct Ref

Source
pub struct Ref<T: 'static>(/* private fields */);
Expand description

§The two-way binding system

A fundamental problem in UI development is where and how to store states of widgets, without impacting reusability, extensability or performance. Azul solves this problem using a type-erased Rc<RefCell<Box<Any>>> type (RefAny), whic can be up and downcasted to a Rc<RefCell<Box<T>>> type (Ref<T>). Ref and RefAny exist mostly to reduce typing and to prevent multiple mutable access to the inner RefCell at compile time. Azul stores all RefAnys inside the Dom tree and does NOT clone or mutate them at all. Only user-defined callbacks or the default callbacks have access to the RefAny data.

§Overriding the default behaviour of widgets

While Rust does not support inheritance with language constructs such as @override (Java) or the override keyword in C#, emulating structs that can change their behaviour at runtime is quite easy. Imagine a struct in which all methods are stored as public function pointers inside the struct itself:

// The struct has all methods as function pointers,
// so that they can be "overridden" and exchanged with other
// implementations if necessary
struct A {
    pub function_a: fn(&A, i32) -> i32,
    pub function_b: fn(&A) -> &'static str,
}

impl A {
    pub fn default_impl_a(&self, num: i32) -> i32 { num + num }
    pub fn default_impl_b(&self) -> &'static str { "default b method!" }

    // Don't call default_impl_a() directly, just the function pointer
    pub fn do_a(&self, num: i32) -> i32 { (self.function_a)(self, num) }
    pub fn do_b(&self) -> &'static str { (self.function_b)(self) }
}

// Here we provide the default ("base class") implementation
impl Default for A {
    fn default() -> A {
        A {
            function_a: A::default_impl_a,
            function_b: A::default_impl_b,
        }
    }
}

// Alternative function that will override the original method
fn override_a(_: &A, num: i32) -> i32 { num * num }

fn main() {
    let mut a = A::default();
    println!("{}", a.do_a(5)); // prints "10" (5 + 5)
    println!("{}", a.do_b());  // prints "default b method"

    a.function_a = override_a; // Here we override the behaviour
    println!("{}", a.do_a(5)); // prints "25" (5 * 5)
    println!("{}", a.do_b());  // still prints "default b method", since method isn't overridden
}

Applied to widgets, the “A” class (a placeholder for a “Button”, “Table” or other widget) can look something like this:

fn layout(&self, _: &LayoutInfo) -> Dom {
    Spreadsheet::new()
        .override_oncellchange(my_func_1)
        .override_onworkspacechange(my_func_2)
        .override_oncellselect(my_func_3)
    .dom()
}

The spreadsheet has some “default” event handlers, which can be exchanged for custom implementations via an open API. The benefit is that functions can be mixed and matched, and widgets can be composed of sub-widgets as well as be re-used. Another benefit is that now the widget can react to “custom” events such as “oncellchange” or “oncellselect”, without Azul knowing that such events even exist. The downside is that this coding style requires more work on behalf of the widget designer (but not the user).

Implementations§

Source§

impl<T: 'static> Ref<T>

Source

pub fn new(data: T) -> Self

Source

pub fn borrow(&self) -> StdRef<'_, T>

Source

pub fn borrow_mut(&mut self) -> StdRefMut<'_, T>

Source

pub fn get_type_name(&self) -> &'static str

Source

pub fn upcast(self) -> RefAny

Trait Implementations§

Source§

impl<T: 'static> Clone for Ref<T>

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + 'static> Debug for Ref<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default + 'static> Default for Ref<T>

Source§

fn default() -> Ref<T>

Returns the “default value” for a type. Read more
Source§

impl<T: 'static> From<Ref<T>> for RefAny

Source§

fn from(r: Ref<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: 'static + Hash> Hash for Ref<T>

Source§

fn hash<H>(&self, state: &mut H)
where H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<T: Ord + 'static> Ord for Ref<T>

Source§

fn cmp(&self, other: &Ref<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<T: PartialEq + 'static> PartialEq for Ref<T>

Source§

fn eq(&self, other: &Ref<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: PartialOrd + 'static> PartialOrd for Ref<T>

Source§

fn partial_cmp(&self, other: &Ref<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T: Eq + 'static> Eq for Ref<T>

Source§

impl<T: 'static> StructuralPartialEq for Ref<T>

Auto Trait Implementations§

§

impl<T> Freeze for Ref<T>

§

impl<T> !RefUnwindSafe for Ref<T>

§

impl<T> !Send for Ref<T>

§

impl<T> !Sync for Ref<T>

§

impl<T> Unpin for Ref<T>

§

impl<T> !UnwindSafe for Ref<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.