This commit is contained in:
2023-05-06 00:34:04 +02:00
parent 2d3dfe3ae4
commit b16f76bcec
3 changed files with 92 additions and 13 deletions

View File

@@ -6,13 +6,16 @@ pub enum UiTag {
Menu(UiMenu), Menu(UiMenu),
Image(UiImage), Image(UiImage),
TextButton(UiTextButton), TextButton(UiTextButton),
TextArea(UiTextArea),
StaticText(UiStaticText),
ToggleButton(UiToggleButton),
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct UiMenu { pub struct UiMenu {
pub selected: String, pub selected: String,
#[serde(rename = "OnBack")] #[serde(rename = "OnBack")]
pub on_back: String, pub on_back: Option<String>,
#[serde(rename = "$value")] #[serde(rename = "$value")]
pub children: Vec<UiTag>, pub children: Vec<UiTag>,
} }
@@ -42,10 +45,59 @@ pub struct UiTextButton {
pub on_select: String, pub on_select: String,
} }
#[derive(Debug, Deserialize)]
pub struct UiTextArea {
#[serde(deserialize_with = "deserialize_vec2")]
pub position: [i32; 2],
#[serde(deserialize_with = "deserialize_vec2")]
pub size: [i32; 2],
#[serde(rename = "$value")]
pub children: Vec<UiTag>,
}
#[derive(Debug, Deserialize)]
pub struct UiStaticText {
pub text: String,
#[serde(deserialize_with = "deserialize_vec2")]
pub position: [i32; 2],
#[serde(rename = "halign")]
pub horizontal_align: HorizontalAlign,
#[serde(rename = "fademode")]
pub fade_mode: FadeMode,
}
#[derive(Debug, Deserialize)]
pub struct UiToggleButton {
pub name: Option<String>,
pub text: String,
#[serde(deserialize_with = "deserialize_vec2")]
pub position: [i32; 2],
pub value: String,
#[serde(rename = "minValue")]
pub min_value: i32,
#[serde(rename = "maxValue")]
pub max_value: i32,
#[serde(rename = "valueStep")]
pub value_step: i32,
pub target: String,
#[serde(rename = "targetLOffset", deserialize_with = "deserialize_vec2")]
pub target_l_offset: [i32; 2],
#[serde(rename = "targetROffset", deserialize_with = "deserialize_vec2")]
pub target_r_offset: [i32; 2],
#[serde(rename = "noSound")]
pub no_sound: Option<bool>,
#[serde(rename = "OnChange")]
pub on_change: String,
#[serde(rename = "OnSelect")]
pub on_select: String,
}
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum HorizontalAlign { pub enum HorizontalAlign {
Left,
Center, Center,
Right,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]

View File

@@ -178,9 +178,9 @@ impl ResourceFormatLoaderVirtual for DatafileLoader {
game_object.to_variant() game_object.to_variant()
} }
Ok(DatafileFile::Ui(ui)) => { Ok(DatafileFile::Ui(ui)) => {
let ui = convert_ui(ui); let ui = convert_ui(ui, None);
let mut scene = PackedScene::new(); let mut scene = PackedScene::new();
scene.pack(ui.upcast()); scene.pack(ui);
self.save_to_cache(scene.share().upcast(), format!("{}.scn", datafile_path)); self.save_to_cache(scene.share().upcast(), format!("{}.scn", datafile_path));
scene.to_variant() scene.to_variant()

View File

@@ -1,25 +1,30 @@
use crate::formats::ui_xml::{HorizontalAlign, UiTag}; use crate::formats::ui_xml::{HorizontalAlign, UiTag};
use godot::builtin::{GodotString, Vector2}; use godot::builtin::{Array, Dictionary, GodotString, Signal, ToVariant, Vector2};
use godot::engine::global::HorizontalAlignment; use godot::engine::global::HorizontalAlignment;
use godot::engine::node::InternalMode; use godot::engine::node::InternalMode;
use godot::engine::{Button, Container, Control, TextureRect}; use godot::engine::{Button, Control, Node, TextureRect};
use godot::prelude::*; use godot::obj::{Gd, Share};
use godot::sys::GDEXTENSION_VARIANT_TYPE_STRING;
use itertools::Itertools;
pub fn convert_ui(ui: UiTag) -> Gd<Control> { const ACTION_META_NAME: &str = "action";
pub fn convert_ui(ui: UiTag, owner: Option<Gd<Node>>) -> Gd<Node> {
match ui { match ui {
UiTag::Menu(menu) => { UiTag::Menu(menu) => {
let mut gd_menu = Container::new_alloc(); let mut gd_menu = Control::new_alloc();
let owner_node = owner.unwrap_or_else(|| gd_menu.share().upcast());
for child in menu.children { for child in menu.children {
gd_menu.add_child( let mut child = convert_ui(child, Some(owner_node.share()));
convert_ui(child).upcast(), gd_menu.add_child(child.share(), false, InternalMode::INTERNAL_MODE_FRONT);
false, child.set_owner(owner_node.share());
InternalMode::INTERNAL_MODE_FRONT,
);
} }
gd_menu.upcast() gd_menu.upcast()
} }
UiTag::Image(image) => { UiTag::Image(image) => {
let mut gd_image = TextureRect::new_alloc(); let mut gd_image = TextureRect::new_alloc();
gd_image.set_name(image.texture.into());
gd_image.set_position( gd_image.set_position(
Vector2 { Vector2 {
x: image.position[0] as f32, x: image.position[0] as f32,
@@ -52,6 +57,28 @@ pub fn convert_ui(ui: UiTag) -> Gd<Control> {
gd_button.set_name(GodotString::from(name)); gd_button.set_name(GodotString::from(name));
} }
gd_button.set_text(GodotString::from(button.text)); gd_button.set_text(GodotString::from(button.text));
let mut call = button.on_select.split_whitespace().collect_vec();
if let Some((name,)) = call.drain(..1).collect_tuple() {
gd_button.set_meta(
ACTION_META_NAME.into(),
Dictionary::from([
(&"name".to_variant(), &name.to_variant()),
(
&"args".to_variant(),
&Array::from(
call.into_iter()
.map(GodotString::from)
.collect::<Vec<GodotString>>()
.as_slice(),
)
.to_variant(),
),
])
.to_variant(),
);
}
gd_button.upcast() gd_button.upcast()
} }
} }