1use nifty_runtime::{
8 Axis, Backdrop, ButtonStyle, Icon, ImageSize, LabelStyle, Shortcut, StackStyle, TextStyle,
9};
10
11use crate::context::Context;
12use crate::ffi::{Slice, Str};
13use crate::show::Sink;
14use crate::value::{Slot, TypeDesc};
15
16pub const ABI_VERSION: u32 = 5;
19
20pub type InitFn = unsafe extern "C" fn(context: *const Context, out: *mut Slot) -> bool;
22pub type ReadFn =
25 unsafe extern "C" fn(context: *const Context, frame: *const Slot, out: *mut Slot) -> bool;
26pub type WriteFn =
28 unsafe extern "C" fn(context: *const Context, frame: *const Slot, value: Slot) -> bool;
29pub type ActionFn = unsafe extern "C" fn(context: *const Context, frame: *mut Slot) -> bool;
31pub type ExpandFn =
33 unsafe extern "C" fn(context: *const Context, frame: *const Slot, sink: *mut Sink) -> bool;
34
35#[derive(Debug)]
37#[repr(C)]
38pub struct ProgramDesc {
39 pub abi_version: u32,
40 pub states: Slice<StateDesc>,
41 pub windows: Slice<WindowDesc>,
42 pub views: Slice<ViewDesc>,
44 pub functions: Slice<Str>,
46 pub spans: Slice<SpanDesc>,
48 pub menus: Slice<MenuDesc>,
50 pub menu_frame: FrameDesc,
52}
53
54#[derive(Debug)]
56#[repr(C)]
57pub struct MenuDesc {
58 pub title: Str,
59 pub entries: Slice<MenuEntryDesc>,
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq)]
63#[repr(u8)]
64pub enum MenuEntryKind {
65 Item,
66 Separator,
67 Submenu,
68}
69
70#[derive(Debug)]
75#[repr(C)]
76pub struct MenuEntryDesc {
77 pub kind: MenuEntryKind,
78 pub title: Str,
79 pub shortcut: ShortcutDesc,
80 pub action: Option<ActionFn>,
81 pub entries: Slice<MenuEntryDesc>,
82}
83
84#[derive(Clone, Copy, Debug)]
86#[repr(C)]
87pub struct ShortcutDesc {
88 pub present: bool,
89 pub shortcut: Shortcut,
90}
91
92#[derive(Debug)]
93#[repr(C)]
94pub struct StateDesc {
95 pub ty: &'static TypeDesc,
96 pub init: InitFn,
97}
98
99#[derive(Debug)]
100#[repr(C)]
101pub struct SpanDesc {
102 pub file: Str,
103 pub line: u32,
104 pub column: u32,
105}
106
107#[derive(Debug)]
109#[repr(C)]
110pub struct FrameDesc {
111 pub locals: Slice<&'static TypeDesc>,
112}
113
114#[derive(Debug)]
115#[repr(C)]
116pub struct WindowDesc {
117 pub title: Str,
118 pub width: f32,
119 pub height: f32,
120 pub backdrop: Backdrop,
121 pub starts_open: bool,
123 pub style: StackStyle,
124 pub children: Slice<TemplateDesc>,
125 pub frame: FrameDesc,
126}
127
128#[derive(Debug)]
129#[repr(C)]
130pub struct ViewDesc {
131 pub body: Slice<TemplateDesc>,
132 pub frame: FrameDesc,
134}
135
136#[derive(Clone, Copy, Debug, PartialEq, Eq)]
137#[repr(u8)]
138pub enum TemplateKind {
139 Stack,
140 Label,
141 Button,
142 TextField,
143 Checkbox,
144 Spacer,
145 Divider,
146 Region,
147 NavItem,
148 Progress,
149 Scroll,
150 Switch,
151 Slider,
152 Picker,
153 Image,
154 ContextMenu,
155 DropTarget,
156}
157
158#[derive(Clone, Copy, Debug)]
159#[repr(C)]
160pub struct BindingDesc {
161 pub read: Option<ReadFn>,
162 pub write: Option<WriteFn>,
163}
164
165#[derive(Debug)]
166#[repr(C)]
167pub struct RegionDesc {
168 pub expand: Option<ExpandFn>,
169 pub lists: Slice<Slice<TemplateDesc>>,
172}
173
174#[derive(Debug)]
196#[repr(C)]
197pub struct TemplateDesc {
198 pub kind: TemplateKind,
199 pub button: ButtonStyle,
200 pub icon: Icon,
201 pub deps: Slice<u32>,
202 pub stack: StackStyle,
203 pub label: LabelStyle,
204 pub image: ImageSize,
205 pub text: Option<ReadFn>,
206 pub value: Option<ReadFn>,
207 pub badge: Option<ReadFn>,
208 pub binding: BindingDesc,
209 pub min: i64,
210 pub max: i64,
211 pub lines: u32,
212 pub action: Option<ActionFn>,
213 pub placeholder: Str,
214 pub children: Slice<TemplateDesc>,
215 pub menu: Slice<MenuEntryDesc>,
216 pub region: RegionDesc,
217}
218
219impl TemplateDesc {
220 #[must_use]
222 pub const fn empty(kind: TemplateKind) -> Self {
223 Self {
224 kind,
225 button: ButtonStyle::Normal,
226 icon: Icon::None,
227 deps: Slice::EMPTY,
228 stack: StackStyle::new(Axis::Vertical),
229 label: LabelStyle::new(TextStyle::Body),
230 image: ImageSize {
231 width: ImageSize::FIT,
232 height: ImageSize::FIT,
233 },
234 text: None,
235 value: None,
236 badge: None,
237 binding: BindingDesc {
238 read: None,
239 write: None,
240 },
241 min: 0,
242 max: 0,
243 lines: 1,
244 action: None,
245 placeholder: Str::EMPTY,
246 children: Slice::EMPTY,
247 menu: Slice::EMPTY,
248 region: RegionDesc {
249 expand: None,
250 lists: Slice::EMPTY,
251 },
252 }
253 }
254}