use crate::if_node_is_valid; use godot::classes::control::SizeFlags; use godot::classes::{ AnimationLibrary, AnimationMixer, Control, EditorInspectorPlugin, EditorResourcePicker, HBoxContainer, IEditorInspectorPlugin, Label, }; use godot::prelude::*; #[derive(GodotClass)] #[class(base = EditorInspectorPlugin, tool, init)] pub struct GlobalLibraryButtonPlugin { base: Base<EditorInspectorPlugin>, } #[godot_api] impl IEditorInspectorPlugin for GlobalLibraryButtonPlugin { fn can_handle(&self, object: Option<Gd<Object>>) -> bool { object .map(|object| object.is_class(&GString::from("AnimationMixer"))) .unwrap_or(false) } fn parse_category(&mut self, object: Option<Gd<Object>>, category: GString) { if category == GString::from("AnimationMixer") { let animation_player: Gd<AnimationMixer> = if_node_is_valid!([AnimationMixer]; object); self.base_mut() .add_custom_control(&build_setter_control(animation_player)); } } } fn build_setter_control(mut animation_player: Gd<AnimationMixer>) -> Gd<Control> { let mut hbox = HBoxContainer::new_alloc(); hbox.add_theme_constant_override("spacing", 5); let mut label = Label::new_alloc(); label.set_text(&GString::from("Set global")); label.set_h_size_flags(SizeFlags::EXPAND_FILL); hbox.add_child(&label); let mut resource_picker = EditorResourcePicker::new_alloc(); resource_picker.set_base_type("AnimationLibrary"); resource_picker.connect( "resource_changed", &Callable::from_local_fn("set_root_anim_library", move |args| { let library = match args.first().and_then(|r| r.try_to::<Gd<AnimationLibrary>>().ok()) { Some(library) => library, None => return Ok(Variant::nil()), }; // A library without an identifier is set as the global library, and doesn't need a prefix in gdscript animation_player.add_animation_library("", &library); Ok(Variant::nil()) }), ); resource_picker.set_h_size_flags(SizeFlags::EXPAND_FILL); hbox.add_child(&resource_picker); hbox.upcast::<Control>() }