Skip to main content

ui/
style.rs

1// style -- the contract between the core and a style                (ASMLIB/inc/style.inc)
2//
3// The core holds every widget's logic (measuring, placing, input, state, semantics); how
4// things look comes from exactly one style crate, chosen when the app is linked
5// (build_rs.py --style S, the app passes `&style::STYLE` to run).  Size functions return
6// the widget's size and may keep what they computed in Sp::s for the paint call; paint
7// functions see the placed rectangle and the state and emit draw commands -- no layout,
8// no input, no semantic records.
9//
10// The contract is split like the files of a style (ASMLIB/styles/<name>/*.s): Style (theme,
11// type ramp, fonts) and one sub-trait per widget family -- StyleBasic (basic.s), StyleValue
12// (value.s), StyleEdit (edit.s), StyleList (list.s), StylePopup (popup.s), StyleChrome
13// (chrome.s), StyleMisc (misc.s).  R5: the default bodies (empty / zero) exist only while
14// the widget families are being ported; a finished style overrides every function.
15
16use alloc::rc::Rc;
17
18use crate::consts::T_COUNT;
19use crate::value::Track;
20use crate::Ui;
21
22/// the SP record: inputs of a widget's size / paint call (SP_* of style.inc)
23#[derive(Clone, Copy, Default)]
24pub struct Sp<'a> {
25    /// placed rectangle (px; filled before the paint call)
26    pub x: i32,
27    pub y: i32,
28    pub w: i32,
29    pub h: i32,
30    /// 0 rest, 1 hover, 2 pressed, 3 disabled
31    pub state: u32,
32    /// EV_* of behave()
33    pub ev: u32,
34    /// ST_* / BOX_* / MIF_* / RG_* flags of the widget
35    pub flags: u32,
36    /// icon code point (0 = none)
37    pub icon: u32,
38    pub label: Option<&'a str>,
39    pub value: i32,
40    pub value2: i32,
41    /// kept by the style from its size call to its paint call (SP_S0 .. SP_S3)
42    pub s: [i32; 4],
43    /// the 8-byte SP_VALUE variants: a second text (menu accelerator, info bar message)
44    pub label2: Option<&'a str>,
45    /// ... an f64 (angle degrees)
46    pub f: f64,
47    /// SP_LABEL variants: a thumbnail (pan), a TRACK record (value sliders: flags, n, stops)
48    // ui-list: the thumbnail as the Rc draw_image takes, with its version (img_ver); the
49    // TRACK record as value::Track (it may carry a custom drawing)
50    pub img: Option<&'a Rc<gfx::Surface>>,
51    pub img_ver: u32,
52    pub track: Option<&'a Track>,
53}
54
55impl Sp<'_> {
56    pub fn rect(&self) -> [i32; 4] {
57        [self.x, self.y, self.w, self.h]
58    }
59
60    pub fn place(&mut self, r: [i32; 4]) {
61        self.x = r[0];
62        self.y = r[1];
63        self.w = r[2];
64        self.h = r[3];
65    }
66}
67
68/// a style: tokens, type ramp, fonts and every widget family's paint functions
69pub trait Style: StyleBasic + StyleValue + StyleEdit + StyleList + StylePopup + StyleChrome + StyleMisc + Sync {
70    /// the style's short name, as build_rs.py --style knows it ("winui", "kde"): the name
71    /// Ui::set_style switches to (several styles linked into one app)
72    fn name(&self) -> &'static str {
73        ""
74    }
75    /// Ribbon height in DIP. Existing styles retain the original 110-DIP layout.
76    fn ribbon_height(&self) -> i32 { 110 }
77    /// Outer ribbon padding in DIP, independently styled from control content heights.
78    fn ribbon_padding(&self) -> u32 { 8 }
79    /// Optional document-style gallery face, size in 24.8 DIP and ink color.
80    /// None preserves the ordinary UI type ramp in existing style previews.
81    fn ribbon_preview(&self, _typography: u32) -> Option<(u32, i32, u32)> { None }
82    /// Group sizing and overflow policy. Existing styles preserve compact flyouts.
83    fn ribbon_metrics(&self) -> crate::RibbonMetrics { crate::RibbonMetrics::default() }
84    /// Optional optical offset of a preview card in 24.8 DIP. Opts into the
85    /// fractional panel painter; None keeps the original integer painter.
86    fn preview_card_offset(&self) -> Option<[i32; 2]> { None }
87    // ---- colours, type ramp, fonts (theme.s, fonts.s)
88    /// the T_* tokens (light or dark; accent entries may be 0: accent() fills them)
89    fn tokens(&self, dark: bool) -> [u32; T_COUNT];
90    /// fill T_ACCENT, _HOVER, _PRESSED and T_ACCENT_TEXT from 0xRRGGBB (0 = the default)
91    fn accent(&self, theme: &mut [u32; T_COUNT], dark: bool, rgb: u32);
92    /// font px / line px / FONT_* of TS_CAPTION .. TS_DISPLAY (+ one spare) at 100 %
93    fn ts_size(&self) -> [u8; 8];
94    /// Font sizes in 24.8 DIP. The default keeps every existing integer type ramp exact.
95    fn ts_size_fx(&self) -> [u16; 8] {
96        self.ts_size().map(|size| u16::from(size) * 256)
97    }
98    fn ts_line(&self) -> [u8; 8];
99    fn ts_font(&self) -> [u8; 8];
100    /// Embedded SGF1 or TrueType/OpenType assets of FONT_REG, FONT_SEMI, FONT_BOLD, FONT_ICON.
101    fn fonts(&self) -> [&'static [u8]; 4];
102    /// Raster policy for the four embedded UI faces. Runtime/document fonts keep
103    /// their own defaults. Existing styles preserve their pixel output.
104    fn font_raster(&self) -> [text::FontRaster; 4] { [text::FontRaster::Legacy; 4] }
105    /// per embedded font: family, style, full, typographic family, typographic style
106    /// (sty_font_names)
107    fn font_names(&self) -> [[&'static str; 5]; 4];
108    /// Paint a semantic icon with the shared rasterizer; false uses the icon font.
109    /// Coordinates are target pixels, size is 24.8 pixels; dpi permits fixed DIP details.
110    /// Application icon hooks
111    /// run first. Existing styles retain their original monochrome font rendering.
112    #[allow(clippy::too_many_arguments)]
113    fn paint_icon(&self, _g: &mut crate::Gfx, _cp: u32, _x: i32, _y: i32,
114                  _size_fx: i32, _color: u32, _accent: u32, _dark: bool, _disabled: bool, _dpi: u32) -> bool {
115        false
116    }
117    /// The painters of the data views (grids, trees, badges, meters, charts).  The default
118    /// paints them from the theme tokens (stock.rs), so every style shows them; a style
119    /// returns its own StyleData to give them its look.
120    fn data(&self) -> &'static dyn StyleData {
121        &crate::stock::Stock
122    }
123    /// The painters of the app shell parts (navigation pane, command bar, splitter,
124    /// breadcrumb, segmented control, wizard steps, toasts, spinner, calendar).  Default:
125    /// token-based (stock.rs).
126    fn shell(&self) -> &'static dyn StyleShell {
127        &crate::stock::Stock
128    }
129}
130
131/// data views: grid header / rows, tree rows, badges, status dots, meters, charts  (data.rs,
132/// chart.rs).  Every method has a token-based default (stock.rs); a style overrides what it
133/// wants to look different.
134pub trait StyleData {
135    /// (header strip height, row height, cell padding) in DIP
136    fn grid_metrics(&self, _ui: &Ui) -> (i32, i32, i32) {
137        (32, 36, 12)
138    }
139    /// the header strip behind the header cells (rect = the strip)
140    fn grid_header_bg(&self, ui: &mut Ui, sp: &Sp) {
141        crate::stock::grid_header_bg(ui, sp)
142    }
143    /// header cell: label, ev, flags GH_*; s[0] = the label inset (px)
144    fn grid_header(&self, ui: &mut Ui, sp: &Sp) {
145        crate::stock::grid_header(ui, sp)
146    }
147    /// row background: ev, value 1 = selected, value2 = row index, flags GR_*
148    fn grid_row(&self, ui: &mut Ui, sp: &Sp) {
149        crate::stock::grid_row(ui, sp)
150    }
151    /// tree expander glyph: value 1 = expanded, ev
152    fn tree_twisty(&self, ui: &mut Ui, sp: &Sp) {
153        crate::stock::tree_twisty(ui, sp)
154    }
155    /// badge: flags BADGE_*, label; size -> (w, h)
156    fn badge_size(&self, ui: &mut Ui, sp: &mut Sp) -> (i32, i32) {
157        crate::stock::badge_size(ui, sp)
158    }
159    fn badge(&self, ui: &mut Ui, sp: &Sp) {
160        crate::stock::badge(ui, sp)
161    }
162    /// status dot: flags BADGE_*
163    fn status_dot(&self, ui: &mut Ui, sp: &Sp) {
164        crate::stock::status_dot(ui, sp)
165    }
166    /// meter (capacity bar): value, value2 maximum, flags BADGE_* of the fill
167    fn meter(&self, ui: &mut Ui, sp: &Sp) {
168        crate::stock::meter(ui, sp)
169    }
170    /// the categorical colours of charts (series 0 .. 7, 0xAARRGGBB)
171    fn chart_palette(&self, ui: &Ui) -> [u32; 8] {
172        crate::stock::chart_palette(ui)
173    }
174}
175
176/// app shell parts: navigation pane and items, command bar, splitter grip, breadcrumb,
177/// segmented control, wizard steps, toasts, spinner, indeterminate progress, calendar cells
178/// (shell.rs, notify.rs, datepick.rs).  Token-based defaults in stock.rs.
179pub trait StyleShell {
180    /// the navigation pane's surface (rect = the pane), flags 1 = compact
181    fn nav_pane(&self, ui: &mut Ui, sp: &Sp) {
182        crate::stock::nav_pane(ui, sp)
183    }
184    /// navigation item: ev, value 1 = selected, icon, label, label2 = badge text, flags
185    /// NAV_*; size -> (w, h)
186    fn nav_item_size(&self, ui: &mut Ui, sp: &mut Sp) -> (i32, i32) {
187        crate::stock::nav_item_size(ui, sp)
188    }
189    fn nav_item(&self, ui: &mut Ui, sp: &Sp) {
190        crate::stock::nav_item(ui, sp)
191    }
192    /// section header of the navigation pane: label, flags NAV_COMPACT (then a divider)
193    fn nav_section_size(&self, ui: &mut Ui, sp: &mut Sp) -> (i32, i32) {
194        crate::stock::nav_section_size(ui, sp)
195    }
196    fn nav_section(&self, ui: &mut Ui, sp: &Sp) {
197        crate::stock::nav_section(ui, sp)
198    }
199    /// the bar behind a command bar (rect = the bar)
200    fn command_bar(&self, ui: &mut Ui, sp: &Sp) {
201        crate::stock::command_bar(ui, sp)
202    }
203    /// splitter grip: ev, flags 1 = vertical split (a horizontal grip)
204    fn split_grip(&self, ui: &mut Ui, sp: &Sp) {
205        crate::stock::split_grip(ui, sp)
206    }
207    /// breadcrumb separator (rect = its place)
208    fn breadcrumb_sep(&self, ui: &mut Ui, sp: &Sp) {
209        crate::stock::breadcrumb_sep(ui, sp)
210    }
211    /// segmented control item: ev, value 1 = selected, label, flags SEG_FIRST / SEG_LAST
212    fn segment(&self, ui: &mut Ui, sp: &Sp) {
213        crate::stock::segment(ui, sp)
214    }
215    /// wizard step row: value step number (from 1), value2 WS_* state, label, ev
216    fn wizard_step(&self, ui: &mut Ui, sp: &Sp) {
217        crate::stock::wizard_step(ui, sp)
218    }
219    /// toast card: flags IB_* severity, label title, label2 message; s[0] = close button
220    /// x, s[1] its size (set by the painter, hence &mut)
221    fn toast(&self, ui: &mut Ui, sp: &mut Sp) {
222        crate::stock::toast(ui, sp)
223    }
224    /// spinner: value phase 0 .. 1023 (one turn), rect = its square
225    fn spinner(&self, ui: &mut Ui, sp: &Sp) {
226        crate::stock::spinner(ui, sp)
227    }
228    /// indeterminate progress bar: value phase 0 .. 1023
229    fn progress_indeterminate(&self, ui: &mut Ui, sp: &Sp) {
230        crate::stock::progress_indeterminate(ui, sp)
231    }
232    /// day cell of a calendar: label, value 1 = selected, value2 1 = today, flags 1 = other
233    /// month, ev
234    fn calendar_day(&self, ui: &mut Ui, sp: &Sp) {
235        crate::stock::calendar_day(ui, sp)
236    }
237    /// a dock group's surface (rect = tab strip and content; dock.rs), value 1 = the keyboard
238    /// focus is in the group
239    fn dock_group(&self, ui: &mut Ui, sp: &Sp) {
240        crate::stock::dock_group(ui, sp)
241    }
242    /// the tab strip of a dock group (rect = the strip, SM_DOCK_HDR high), value as dock_group
243    fn dock_header(&self, ui: &mut Ui, sp: &Sp) {
244        crate::stock::dock_header(ui, sp)
245    }
246    /// a tab of a dock group: label, icon, ev, value 1 = the shown panel, value2 1 = the focus
247    /// is in the group, flags DOCK_TAB_HOLD = held long enough to be dragged (show it through
248    /// the tokens); size -> (w, h), the core takes w (a tab is as high as the strip)
249    fn dock_tab_size(&self, ui: &mut Ui, sp: &mut Sp) -> (i32, i32) {
250        crate::stock::dock_tab_size(ui, sp)
251    }
252    fn dock_tab(&self, ui: &mut Ui, sp: &Sp) {
253        crate::stock::dock_tab(ui, sp)
254    }
255    /// the rail of a collapsed dock side (rect), flags DOCK_LEFT / DOCK_RIGHT / DOCK_BOTTOM
256    fn dock_rail(&self, ui: &mut Ui, sp: &Sp) {
257        crate::stock::dock_rail(ui, sp)
258    }
259    /// a drop marker while a panel is dragged: value DOCK_MK_* (the part of the place it
260    /// fills), ev EV_HOVER while the pointer is over it
261    fn dock_marker(&self, ui: &mut Ui, sp: &Sp) {
262        crate::stock::dock_marker(ui, sp)
263    }
264    /// where the dragged panel would go (rect), value 1 = a floating window there
265    fn dock_preview(&self, ui: &mut Ui, sp: &Sp) {
266        crate::stock::dock_preview(ui, sp)
267    }
268    /// (L7) the background of a window area (desk.rs; rect = the area)
269    fn desk_bg(&self, ui: &mut Ui, sp: &Sp) {
270        crate::stock::desk_bg(ui, sp)
271    }
272    /// a window inside an area: shadow, surface and frame (rect = the window), value 1 = the
273    /// active window, flags 1 = maximised (it fills the area: no shadow, square)
274    fn desk_window(&self, ui: &mut Ui, sp: &Sp) {
275        crate::stock::desk_window(ui, sp)
276    }
277    /// its title bar (rect = the bar over the whole width, the buttons are drawn after it):
278    /// value 1 = active, icon, label = the title; s[0], s[1] = x and width of the icon and title
279    /// (px)
280    fn desk_titlebar(&self, ui: &mut Ui, sp: &Sp) {
281        crate::stock::desk_titlebar(ui, sp)
282    }
283    /// a button of its title bar: ev, flags HB_MIN / HB_MAX / HB_CLOSE, icon IC_CHROME_*,
284    /// value 1 = the window is active; default: the style's caption_button
285    fn desk_button(&self, ui: &mut Ui, sp: &Sp) {
286        let st = ui.style;
287        st.caption_button(ui, sp)
288    }
289    /// where a dragged window snaps when it is released now (rect), value 1 = maximised
290    fn desk_snap(&self, ui: &mut Ui, sp: &Sp) {
291        crate::stock::desk_snap(ui, sp)
292    }
293    /// the bar behind a taskbar (rect)
294    fn taskbar(&self, ui: &mut Ui, sp: &Sp) {
295        crate::stock::taskbar(ui, sp)
296    }
297    /// a window's button in a taskbar: label, icon, ev, value 1 = the active window, value2 1 =
298    /// minimised, flags DTB_ICONS (icons only); size -> (w, h), the core takes w (a button is
299    /// as high as the bar)
300    fn taskbar_button_size(&self, ui: &mut Ui, sp: &mut Sp) -> (i32, i32) {
301        crate::stock::taskbar_button_size(ui, sp)
302    }
303    fn taskbar_button(&self, ui: &mut Ui, sp: &Sp) {
304        crate::stock::taskbar_button(ui, sp)
305    }
306}
307
308/// buttons, check boxes, radios, switches, sliders, progress, separators  (basic.s)
309pub trait StyleBasic {
310    /// focus visual around rectangle r (px) of a control with that corner radius (DIP)
311    fn focus_ring(&self, _ui: &mut Ui, _r: [i32; 4], _radius_dip: i32) {}
312    /// a drop target with a matching drag over it (rectangle r, px; drop_target): by default
313    /// a 2 DIP accent frame over a light accent tint
314    fn drop_highlight(&self, ui: &mut Ui, r: [i32; 4]) {
315        let c = ui.color(crate::consts::T_ACCENT);
316        let tint = (c & 0x00FF_FFFF) | 0x2E00_0000;
317        let (t, rad) = (ui.dp(2), ui.dp(4));
318        ui.cmd_rrect(r[0], r[1], r[2], r[3], rad, t, tint, c, c);
319    }
320    /// buttons (ST_ACCENT, ST_SUBTLE, ST_CHECKED, ST_LARGE, ST_COMPACT, ST_ICON_ONLY)
321    fn button_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
322        (0, 0)
323    }
324    fn button(&self, _ui: &mut Ui, _sp: &Sp) {}
325    /// value 0 / 1 / 2 (indeterminate)
326    fn checkbox_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
327        (0, 0)
328    }
329    fn checkbox(&self, _ui: &mut Ui, _sp: &Sp) {}
330    /// value 1 = selected
331    fn radio_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
332        (0, 0)
333    }
334    fn radio(&self, _ui: &mut Ui, _sp: &Sp) {}
335    /// value 0 / 1, value2 knob position 0 .. 256 (animated)
336    fn switch_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
337        (0, 0)
338    }
339    fn switch(&self, _ui: &mut Ui, _sp: &Sp) {}
340    /// size: value 1 = vertical; must set s[0] = thumb px along the axis; paint: value thumb
341    /// offset, value2 track length (px)
342    fn slider_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
343        (0, 0)
344    }
345    fn slider(&self, _ui: &mut Ui, _sp: &Sp) {}
346    /// value, value2 maximum
347    fn progress_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
348        (0, 0)
349    }
350    fn progress(&self, _ui: &mut Ui, _sp: &Sp) {}
351    /// thickness incl. margins; paint: value 1 = horizontal line (in a vertical box)
352    fn separator_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> i32 {
353        0
354    }
355    fn separator(&self, _ui: &mut Ui, _sp: &Sp) {}
356}
357
358/// value sliders (gradient tracks), angle, pan  (value.s)
359pub trait StyleValue {
360    /// flags RG_*, value t 0..65536 along the travel, track (gradient) or None; state held = 2
361    fn value_slider_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
362        (0, 0)
363    }
364    fn value_slider(&self, _ui: &mut Ui, _sp: &Sp) {}
365    /// thumb length px (travel = length - thumb)
366    fn value_slider_thumb(&self, _ui: &mut Ui) -> i32 {
367        0
368    }
369    /// f degrees, s[0] 1 = focus visual
370    fn angle_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
371        (0, 0)
372    }
373    fn angle(&self, _ui: &mut Ui, _sp: &Sp) {}
374    /// img thumbnail or None; paint: value, value2 = the point (px)
375    fn pan_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
376        (0, 0)
377    }
378    fn pan(&self, _ui: &mut Ui, _sp: &Sp) {}
379}
380
381/// text boxes  (edit.s)
382pub trait StyleEdit {
383    /// Select the single-line input face and return its line height and baseline in px.
384    /// Default preserves the body font; icon inputs may use a compact search-field face.
385    fn textbox_font(&self, ui: &mut Ui, _sp: &Sp) -> (i32, i32) {
386        (ui.ts_line(crate::consts::TS_BODY), ui.ts_base(crate::consts::TS_BODY))
387    }
388    /// value natural width (DIP), flags 1 = multi-line (value2 line height px); must set
389    /// s[0], s[1], s[2] = left, right, top text inset (px)
390    fn textbox_metrics(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
391        (0, 0)
392    }
393    /// ev (hover), value 1 = editing, value2 1 = disabled; the core draws text, selection, caret
394    fn textbox_frame(&self, _ui: &mut Ui, _sp: &Sp) {}
395    /// value view h, value2 content h, s[0] scroll y, s[1] text top (px)
396    fn textbox_vbar(&self, _ui: &mut Ui, _sp: &Sp) {}
397}
398
399/// focus rectangles, scroll bars, list rows, tabs, expanders  (list.s)
400pub trait StyleList {
401    /// focus visual drawn ON a rectangle (rows, tabs, headers)
402    fn focus_rect(&self, _ui: &mut Ui, _x: i32, _y: i32, _w: i32, _h: i32) {}
403    /// hover area, track margin at both ends, shortest thumb (px)
404    fn scrollbar_thickness(&self, _ui: &mut Ui) -> i32 {
405        0
406    }
407    fn scrollbar_margin(&self, _ui: &mut Ui) -> i32 {
408        0
409    }
410    fn scrollbar_min_thumb(&self, _ui: &mut Ui) -> i32 {
411        0
412    }
413    /// flags 1 = vertical, value expansion 0..256, s[0] track start, s[1] thumb length,
414    /// value2 thumb offset (px)
415    fn scrollbar(&self, _ui: &mut Ui, _sp: &Sp) {}
416    /// reorder marker centred on y across x .. + w
417    fn list_drop_line(&self, _ui: &mut Ui, _sp: &Sp) {}
418    /// ev, value 1 = selected, value2 1 = disabled, flags 1 = dragged row, 2 = focus visual
419    fn list_row(&self, _ui: &mut Ui, _sp: &Sp) {}
420    /// sets s[0] label padding, s[1] height, s[2] pill width
421    fn tab_metrics(&self, _ui: &mut Ui, _sp: &mut Sp) {}
422    /// Select the font used to measure or paint a tab; default preserves the body face.
423    fn tab_font(&self, ui: &mut Ui, _selected: bool) {
424        ui.ts_font(crate::consts::TS_BODY);
425    }
426    /// tab: ev, value selected, value2 disabled, label; pill: strip rect, value pill x
427    fn tab(&self, _ui: &mut Ui, _sp: &Sp) {}
428    fn tab_pill(&self, _ui: &mut Ui, _sp: &Sp) {}
429    /// header: ev, value open, value2 disabled, label; body: the content card's rectangle
430    fn expander_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
431        (0, 0)
432    }
433    fn expander_header(&self, _ui: &mut Ui, _sp: &Sp) {}
434    fn expander_body(&self, _ui: &mut Ui, _sp: &Sp) {}
435}
436
437/// flyouts, menus, menu bars, drop-downs, split buttons, combo boxes, tooltips  (popup.s)
438pub trait StylePopup {
439    /// px
440    fn flyout_pad(&self, _ui: &mut Ui) -> i32 {
441        0
442    }
443    /// BOX_* | PAD_* flags of the content
444    fn flyout_box(&self, _ui: &mut Ui) -> u32 {
445        0
446    }
447    /// shadow + surface of a flyout / menu (rect = the flyout)
448    fn flyout_frame(&self, _ui: &mut Ui, _sp: &Sp) {}
449    /// row height px
450    fn menu_item_h(&self, _ui: &mut Ui) -> i32 {
451        0
452    }
453    /// flags MIF_*, label, label2 accelerator text, icon, ev; size must set s[1] =
454    /// accelerator width
455    fn menu_item_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
456        (0, 0)
457    }
458    fn menu_item(&self, _ui: &mut Ui, _sp: &Sp) {}
459    fn menu_sep_size(&self, _ui: &mut Ui) -> i32 {
460        0
461    }
462    fn menu_sep(&self, _ui: &mut Ui, _sp: &Sp) {}
463    /// flags 1 open, 2 current item, value mnemonic byte index or -1, label, ev
464    fn menubar_item_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
465        (0, 0)
466    }
467    fn menubar_item(&self, _ui: &mut Ui, _sp: &Sp) {}
468    /// flags ST_*, icon, label, value open, value2 disabled
469    fn dropdown_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
470        (0, 0)
471    }
472    fn dropdown(&self, _ui: &mut Ui, _sp: &Sp) {}
473    /// size sets s[0] / s[1] = main / chevron part width; paint: ev main, s[2] chevron
474    /// events, value open, value2 1 main / 2 chevron disabled
475    fn split_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
476        (0, 0)
477    }
478    fn split(&self, _ui: &mut Ui, _sp: &Sp) {}
479    /// size: value widest text px; paint: label the selected text, ev, value2 disabled
480    fn combo_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
481        (0, 0)
482    }
483    fn combo(&self, _ui: &mut Ui, _sp: &Sp) {}
484    /// size sets s[0] text width, s[1] / s[2] gap below / above the pointer; paint: label
485    fn tooltip_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
486        (0, 0)
487    }
488    fn tooltip(&self, _ui: &mut Ui, _sp: &Sp) {}
489}
490
491/// layout metrics, dialogs, info bars, status / title bars, caption buttons, window frames
492/// (chrome.s)
493pub trait StyleChrome {
494    /// Background for navigation placed on a branded accent surface.
495    fn navigation_surface(&self, ui: &Ui) -> u32 {
496        ui.color(crate::consts::T_ACCENT)
497    }
498    /// layout value SM_* (sizes, gaps, box flags, text styles)
499    fn metric(&self, _id: u32) -> i32 {
500        0
501    }
502    fn dialog_smoke(&self, _ui: &mut Ui, _sp: &Sp) {}
503    /// dialog surface (value footer h)
504    fn dialog_frame(&self, _ui: &mut Ui, _sp: &Sp) {}
505    /// size: flags severity, label title, label2 message, sets s[0] / s[1] title / message
506    /// width; paint sets s[2] / s[3] = close button x / size (hence &mut); close: ev
507    fn infobar_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
508        (0, 0)
509    }
510    fn infobar(&self, _ui: &mut Ui, _sp: &mut Sp) {}
511    fn infobar_close(&self, _ui: &mut Ui, _sp: &Sp) {}
512    fn statusbar(&self, _ui: &mut Ui, _sp: &Sp) {}
513    /// ev, flags HB_* (HB_CLOSE), icon, value 1 = window active
514    fn caption_button(&self, _ui: &mut Ui, _sp: &Sp) {}
515    /// background of a library title bar: rect = the bar, value 1 = active
516    fn window_titlebar(&self, _ui: &mut Ui, _sp: &Sp) {}
517    /// value thickness px
518    fn window_border(&self, _ui: &mut Ui, _sp: &Sp) {}
519    fn window_dialog_fill(&self, _ui: &mut Ui, _sp: &Sp) {}
520}
521
522/// swatches, colour picker parts, box decorations, window background  (misc.s)
523pub trait StyleMisc {
524    /// value colour, value2 1 = selected, ev
525    fn swatch_size(&self, _ui: &mut Ui, _sp: &mut Sp) -> (i32, i32) {
526        (0, 0)
527    }
528    fn swatch(&self, _ui: &mut Ui, _sp: &Sp) {}
529    fn color_preview(&self, _ui: &mut Ui, _argb: u32, _r: [i32; 4]) {}
530    /// marker at 24.8 px
531    fn color_marker(&self, _ui: &mut Ui, _x_fx: i32, _y_fx: i32) {}
532    /// rect = the wheel's square, s[0] radius px, value hue (tenths of a degree), value2
533    /// saturation 0..1000, s[1] 1 = focus visual
534    fn color_wheel(&self, _ui: &mut Ui, _sp: &Sp) {}
535    /// BOX_BG / BOX_CARD / BOX_LAYER decoration (sp: rectangle, flags)
536    fn box_deco(&self, _ui: &mut Ui, _sp: &Sp) {}
537    /// the background of a window's whole surface (px)
538    fn window_bg(&self, _ui: &mut Ui, _w: i32, _h: i32) {}
539}