UIs and Composition


#1

This is probably gonna be a silly thing but think about this:

trait UiElement {
    fn draw<T: RenderingContext>(&self, ctx: &T);
}

#[derive(Copy, Clone)]
enum ClickButton {
    Primary,
    Secondary,
    Middle,
    Others, // ???
}
#[derive(Copy, Clone)]
struct ClickTarget {
    x: f64,
    y: f64,
    button: ClickButton,
}
trait ClickableUiElement : UiElement {
    fn click(&self, ct: ClickTarget) -> bool;
}

trait Screen : UiElement, ClickableUiElement, ... {
    fn get_elements(&self) -> &[UiElement];
    fn get_clickable_elements(&self) -> &[ClickableUiElement];
}

default impl<T> ClickableUiElement for T where T: Screen { // I feel like this should go inside `trait Screen {}`...
    fn click(&self, ct: ClickTarget) -> bool {
        // etc
    }
}

trait MySpecialClickableUiElement {
    fn click(&self, ct: ClickTarget, mydata: &mut MyData) -> bool;
}

impl Screen for MyScreen {
    fn click(&self, ct: ClickTarget) -> bool {
        self.default.click(ct) || self.my_special_clickable_ui_element.click(ct, &mut self.i_am_very_unhappy_with_the_standard_click_fn_so_i_made_my_own)
    }
}

Composition is the ability to say “fuck this” to one of the defaults and make one that fits your needs. An UI framework that looks like this would be quite nice and - I feel - quite compatible with Rust.

We don’t need inheritance.