1
//! Built-in widgets for the Azul GUI system
2

            
3
/// Implements `Display, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Hash`
4
/// for a Callback with a `.cb` field.
5
///
6
/// This is necessary to work around for https://github.com/rust-lang/rust/issues/54508
7
///
8
/// # Host-invoker plumbing for managed-FFI bindings
9
///
10
/// Widget callbacks have varying shapes — some are
11
/// `(RefAny, CallbackInfo) -> Update` (Button), others add a state
12
/// struct (CheckBox/Tab/etc.), a few have two extras (ListView). The
13
/// macro therefore does **not** auto-emit an `impl_managed_callback!`
14
/// invocation; per-widget files apply it themselves with the right
15
/// extras list. The base invocation still produces the standard
16
/// `Display`/`Debug`/`Clone`/`From<CallbackType>`/`From<Callback>` impls
17
/// that all widget callbacks share.
18
#[macro_export]
19
macro_rules! impl_widget_callback {
20
    (
21
        $callback_wrapper:ident,
22
        $option_callback_wrapper:ident,
23
        $callback_value:ident,
24
        $callback_ty:ident
25
    ) => {
26
        #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
27
        #[repr(C)]
28
        pub struct $callback_wrapper {
29
            pub refany: RefAny,
30
            pub callback: $callback_value,
31
        }
32

            
33
        #[repr(C)]
34
        pub struct $callback_value {
35
            pub cb: $callback_ty,
36
            /// For FFI: stores the foreign callable (e.g., PyFunction)
37
            /// Native Rust code sets this to None
38
            pub ctx: azul_core::refany::OptionRefAny,
39
        }
40

            
41
        azul_css::impl_option!(
42
            $callback_wrapper,
43
            $option_callback_wrapper,
44
            copy = false,
45
            [Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash]
46
        );
47

            
48
        impl $callback_value {
49
            /// Create a new callback with just a function pointer (for native Rust code)
50
            pub fn create<I: Into<$callback_value>>(cb: I) -> $callback_value {
51
                cb.into()
52
            }
53
        }
54

            
55
        impl ::core::fmt::Display for $callback_value {
56
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
57
                write!(f, "{:?}", self)
58
            }
59
        }
60

            
61
        impl ::core::fmt::Debug for $callback_value {
62
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
63
                let callback = stringify!($callback_value);
64
                write!(f, "{} @ 0x{:x}", callback, self.cb as *const () as usize)
65
            }
66
        }
67

            
68
        impl Clone for $callback_value {
69
            fn clone(&self) -> Self {
70
                $callback_value {
71
                    cb: self.cb.clone(),
72
                    ctx: self.ctx.clone(),
73
                }
74
            }
75
        }
76

            
77
        impl core::hash::Hash for $callback_value {
78
            fn hash<H>(&self, state: &mut H)
79
            where
80
                H: ::core::hash::Hasher,
81
            {
82
                state.write_usize(self.cb as *const () as usize);
83
            }
84
        }
85

            
86
        impl PartialEq for $callback_value {
87
            fn eq(&self, rhs: &Self) -> bool {
88
                self.cb as *const () as usize == rhs.cb as usize
89
            }
90
        }
91

            
92
        impl PartialOrd for $callback_value {
93
            fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
94
                Some((self.cb as *const () as usize).cmp(&(other.cb as usize)))
95
            }
96
        }
97

            
98
        impl Ord for $callback_value {
99
            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
100
                (self.cb as *const () as usize).cmp(&(other.cb as usize))
101
            }
102
        }
103

            
104
        impl Eq for $callback_value {}
105

            
106
        /// Allow creating callback from a raw function pointer
107
        /// Sets callable to None (for native Rust/C usage)
108
        impl From<$callback_ty> for $callback_value {
109
            fn from(cb: $callback_ty) -> $callback_value {
110
                $callback_value {
111
                    cb,
112
                    ctx: azul_core::refany::OptionRefAny::None,
113
                }
114
            }
115
        }
116

            
117
        /// Allow creating widget callback from a generic Callback
118
        /// This enables Python/FFI code to pass generic callbacks to widget methods
119
        impl From<crate::callbacks::Callback> for $callback_value {
120
            fn from(cb: crate::callbacks::Callback) -> $callback_value {
121
                $callback_value {
122
                    cb: unsafe { core::mem::transmute(cb.cb) },
123
                    ctx: cb.ctx,
124
                }
125
            }
126
        }
127
    };
128
}
129

            
130
/// Button widget
131
pub mod button;
132
/// Checkbox widget
133
pub mod check_box;
134
/// Box displaying a color which opens a color picker dialog on being clicked
135
pub mod color_input;
136
/// File input widget
137
pub mod file_input;
138
/// Label widget (centered text)
139
pub mod label;
140
/// Drop-down select widget
141
pub mod drop_down;
142
/// Frame container widget
143
pub mod frame;
144
/// List view widget
145
pub mod list_view;
146
/// Shared core for the video-ish widgets (camera/screencap/video): the
147
/// `VideoFrame` type + the GL-texture `present_frame` writeback. See
148
/// `capture_common.rs`.
149
pub mod capture_common;
150
/// Camera-preview widget (P6) — a "dumb widget" owning a background capture
151
/// thread + a GL-texture ImageRef; no camera logic in core. Same RefAny-
152
/// dataset + merge-callback design as the map widget. See `camera.rs`.
153
pub mod camera;
154
/// Screen-capture widget (P6) — identical "dumb widget" architecture to the
155
/// camera widget, capturing a display/window instead. See `screencap.rs`.
156
pub mod screencap;
157
/// Video-playback widget (P6) — same "dumb widget" architecture, decoding a
158
/// video source (vk-video) into a GL texture. See `video.rs`.
159
pub mod video;
160
/// Microphone-capture widget (P7) — same "dumb widget" architecture as the
161
/// capture widgets, audio instead of video (no GL): a background thread feeds
162
/// each `AudioFrame` to the user's `on_frame` hook. See `microphone.rs`.
163
pub mod microphone;
164
/// Map widget — MVT tile + MapCSS → SVG → DOM (AzulMaps goal app, P3).
165
/// Cache lives in a dataset RefAny owned by a merge callback so it
166
/// survives relayout. See `layout/src/widgets/map.rs` for the design.
167
pub mod map;
168
/// Node graph widget
169
pub mod node_graph;
170
/// Same as text input, but only allows numeric input
171
pub mod number_input;
172
/// Progress bar widget
173
pub mod progressbar;
174
/// Ribbon widget
175
pub mod ribbon;
176
/// Tab container widgets
177
pub mod tabs;
178
/// Single line text input widget
179
pub mod text_input;
180
/// Titlebar widget for custom window chrome
181
pub mod titlebar;
182
/// Tree view widget
183
pub mod tree_view;
184
// /// Spreadsheet (virtualized view) widget
185
// pub mod spreadsheet;
186
// /// Slider widget
187
// pub mod slider;
188
// /// Multi-line text input
189
// pub mod text_edit;