1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! UI related utilities.

pub mod action;
pub mod align;
pub mod render;
pub mod texture;
pub mod window;

#[cfg(feature = "log")]
pub mod log;

pub use arcdps::imgui::Ui;
pub use window::{Window, WindowOptions};

/// Interface for UI components.
// TODO: replace trait with closures?
pub trait Component<Props> {
    /// Renders the component.
    fn render(&mut self, ui: &Ui, props: Props);
}

impl<T, P> Component<P> for T
where
    T: FnMut(&Ui, P),
{
    fn render(&mut self, ui: &Ui, props: P) {
        self(ui, props)
    }
}

/// Interface for windowable UI components.
pub trait Windowable<Props>: Component<Props> {
    /// Whether to enable the context menu.
    const CONTEXT_MENU: bool;

    /// Whether to enable the default menu entries.
    const DEFAULT_OPTIONS: bool = true;

    /// Renders the window context menu contents.
    fn render_menu(&mut self, _ui: &Ui, _props: &mut Props) {}
}

/// Interface for hideable UI components.
pub trait Hideable {
    /// Returns whether the component is currently visible.
    fn is_visible(&self) -> bool;

    /// Returns a mutable reference to the component's visibility state.
    fn visible_mut(&mut self) -> &mut bool;

    /// Hides the component.
    fn hide(&mut self) {
        *self.visible_mut() = false;
    }

    /// Shows the component.
    fn show(&mut self) {
        *self.visible_mut() = true;
    }

    /// Toggles the component's visibility.
    fn toggle_visibility(&mut self) {
        let shown = self.visible_mut();
        *shown = !*shown;
    }

    /// Sets the component's visibility state.
    fn set_visibility(&mut self, visible: bool) {
        *self.visible_mut() = visible;
    }
}