inkanim_types/ink/widget/
mod.rs

1//! All widgets in Cyberpunk 2077 UI
2//! are similar to web and traditional UI frameworks.
3
4pub mod font;
5pub mod image;
6pub(crate) mod implementation;
7pub mod layout;
8pub mod properties;
9
10use enum_dispatch::enum_dispatch;
11pub use implementation::*;
12
13use serde::{Deserialize, Serialize};
14use serde_aux::prelude::deserialize_bool_from_anything;
15
16use crate::{DepotPath, Name};
17
18use self::{
19    font::{
20        fontStyle, inkFontFamilyResource, textHorizontalAlignment, textLetterCase,
21        textOverflowPolicy, textVerticalAlignment,
22    },
23    image::{inkBrushMirrorType, inkBrushTileType, inkTextureAtlas},
24    layout::{inkEHorizontalAlign, inkEVerticalAlign, inkMargin, textJustificationType},
25};
26
27use super::{HandleId, InkWrapper, LocalizationString};
28
29/// belongs to the same level or is nested below, in a tree hierarchy
30pub trait SiblingOrNested {
31    fn sibling_or_nested(&self, searched: &[usize]) -> bool;
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35#[non_exhaustive]
36pub enum Flags {
37    Default,
38    Soft,
39    Hard,
40}
41
42macro_rules! native_compound_widget {
43    ($ty:ident) => {
44        #[doc=concat!("see [NativeDB](https://nativedb.red4ext.com/", stringify!($ty), ")")]
45        #[allow(non_camel_case_types)]
46        #[derive(Debug, Clone, Serialize, Deserialize)]
47        #[serde(rename_all = "camelCase")]
48        pub struct $ty {
49            pub children: InkWrapper<inkMultiChildren>,
50            pub name: $crate::Name,
51            pub child_order: self::layout::inkEChildOrder,
52            pub child_margin: self::layout::inkMargin,
53        }
54    };
55}
56
57macro_rules! native_leaf_widget {
58    ($ty:ident { $($tt:tt)* }) => {
59        #[doc=concat!("🌿 see [NativeDB](https://nativedb.red4ext.com/", stringify!($ty), ")")]
60        #[allow(non_camel_case_types)]
61        #[derive(Debug, Clone, Serialize, Deserialize)]
62        #[serde(rename_all = "camelCase")]
63        pub struct $ty {
64            pub name: $crate::Name,
65            pub layout: self::layout::inkWidgetLayout,
66            pub property_manager: Option<self::properties::PropertyManager>,
67            pub render_transform_pivot: crate::Vector2,
68            pub render_transform: self::layout::inkUITransform,
69            pub size: crate::Vector2,
70            $($tt)*
71        }
72    };
73    ($ty:ident) => {
74        native_leaf_widget!($ty {});
75    };
76}
77
78native_compound_widget!(inkCanvasWidget);
79native_compound_widget!(inkHorizontalPanelWidget);
80native_compound_widget!(inkVerticalPanelWidget);
81native_compound_widget!(inkScrollAreaWidget);
82native_compound_widget!(inkUniformGridWidget);
83native_compound_widget!(inkVirtualCompoundWidget);
84native_compound_widget!(inkFlexWidget);
85native_compound_widget!(inkCacheWidget);
86
87/// see [NativeDB](https://nativedb.red4ext.com/inkMultiChildren)
88#[allow(non_camel_case_types)]
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct inkMultiChildren {
91    pub children: Vec<InkWrapper<Widget>>,
92}
93
94native_leaf_widget!(inkTextWidget {
95  pub localization_string: LocalizationString,
96  pub text: String,
97  pub font_family: inkFontFamilyResource,
98  pub font_style: fontStyle,
99  pub justification: textJustificationType,
100  pub text_letter_case: Option<textLetterCase>,
101  pub line_height_percentage: f32,
102  pub text_horizontal_alignment: textHorizontalAlignment,
103  pub text_vertical_alignment: textVerticalAlignment,
104  pub text_overflow_policy: textOverflowPolicy,
105  pub content_h_align: inkEHorizontalAlign,
106  pub content_v_align: inkEVerticalAlign,
107  pub scroll_delay: u16,
108  pub scroll_text_speed: f32,
109});
110native_leaf_widget!(inkImageWidget {
111    #[serde(deserialize_with = "deserialize_bool_from_anything")]
112    pub use_external_dynamic_texture: bool,
113    pub external_dynamic_texture: Name,
114    #[serde(deserialize_with = "deserialize_bool_from_anything")]
115    pub use_nine_slice_scale: bool,
116    pub nine_slice_scale: inkMargin,
117    pub mirror_type: inkBrushMirrorType,
118    pub tile_type: inkBrushTileType,
119    pub horizontal_tile_crop: f32,
120    pub vertical_tile_crop: f32,
121    pub texture_atlas: inkTextureAtlas,
122    pub texture_part: Name,
123    pub content_h_align: inkEHorizontalAlign,
124    pub content_v_align: inkEVerticalAlign,
125    pub tile_h_align: inkEHorizontalAlign,
126    pub tile_v_align: inkEVerticalAlign,
127});
128native_leaf_widget!(inkVideoWidget);
129native_leaf_widget!(inkMaskWidget);
130native_leaf_widget!(inkBorderWidget);
131native_leaf_widget!(inkShapeWidget);
132native_leaf_widget!(inkCircleWidget);
133native_leaf_widget!(inkRectangleWidget);
134native_leaf_widget!(inkVectorGraphicWidget);
135
136/// any widget
137#[allow(clippy::enum_variant_names)]
138#[allow(non_camel_case_types)]
139#[non_exhaustive]
140#[derive(Debug, Clone, Serialize, Deserialize)]
141#[enum_dispatch(Classname)]
142#[serde(tag = "$type")]
143pub enum Widget {
144    inkMultiChildren(inkMultiChildren),
145
146    inkCanvasWidget(inkCanvasWidget),
147    inkHorizontalPanelWidget(inkHorizontalPanelWidget),
148    inkVerticalPanelWidget(inkVerticalPanelWidget),
149    inkScrollAreaWidget(inkScrollAreaWidget),
150    inkUniformGridWidget(inkUniformGridWidget),
151    inkVirtualCompoundWidget(inkVirtualCompoundWidget),
152    inkFlexWidget(inkFlexWidget),
153    inkCacheWidget(inkCacheWidget),
154
155    inkTextWidget(inkTextWidget),
156    inkImageWidget(inkImageWidget),
157    inkVideoWidget(inkVideoWidget),
158    inkMaskWidget(inkMaskWidget),
159    inkBorderWidget(inkBorderWidget),
160    inkShapeWidget(inkShapeWidget),
161    inkCircleWidget(inkCircleWidget),
162    inkRectangleWidget(inkRectangleWidget),
163    inkVectorGraphicWidget(inkVectorGraphicWidget),
164}
165
166/// see [NativeDB](https://nativedb.red4ext.com/inkWidgetLibraryItemInstance)
167#[allow(non_camel_case_types)]
168#[derive(Debug, Clone, Serialize, Deserialize)]
169#[serde(rename_all = "camelCase")]
170pub struct inkWidgetLibraryItemInstance {
171    pub root_widget: InkWrapper<inkCanvasWidget>,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
175#[serde(rename_all = "PascalCase")]
176pub struct Data {
177    pub file: crate::Data<inkWidgetLibraryItemInstance>,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(rename_all = "PascalCase")]
182pub struct Package {
183    pub data: self::Data,
184}
185
186/// see [NativeDB](https://nativedb.red4ext.com/inkWidgetLibraryItem)
187#[allow(non_camel_case_types)]
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct inkWidgetLibraryItem {
190    pub name: Name,
191    pub package: Package,
192}
193
194/// see [NativeDB](https://nativedb.red4ext.com/inkanimAnimationLibraryResource)
195#[allow(non_camel_case_types)]
196#[derive(Debug, Clone, Serialize, Deserialize)]
197#[serde(rename_all = "PascalCase")]
198pub struct inkanimAnimationLibraryResource {
199    depot_path: DepotPath,
200    flags: Flags,
201}
202
203/// see [NativeDB](https://nativedb.red4ext.com/inkWidgetLibraryResource)
204#[allow(non_camel_case_types)]
205#[derive(Debug, Clone, Serialize, Deserialize)]
206#[serde(rename_all = "camelCase")]
207pub struct inkWidgetLibraryResource {
208    pub animation_library_res_ref: inkanimAnimationLibraryResource,
209    pub library_items: Vec<inkWidgetLibraryItem>,
210}
211
212/// widget aggregated informations summary
213#[allow(non_snake_case)]
214#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct WidgetSummary {
216    /// unique handle ID
217    pub HandleId: HandleId,
218    /// widget name
219    pub Name: Name,
220}