+ atomic build.sh
+ implemented editor buttons
This commit is contained in:
125
src/editor/editor.rs
Normal file
125
src/editor/editor.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use godot::classes::EditorInterface;
|
||||
use godot::classes::EditorPlugin;
|
||||
use godot::classes::IEditorPlugin;
|
||||
use godot::classes::ImageTexture;
|
||||
use godot::classes::MenuButton;
|
||||
use godot::classes::ResourceLoader;
|
||||
use godot::classes::Texture2D;
|
||||
use godot::classes::editor_plugin::CustomControlContainer;
|
||||
use godot::prelude::*;
|
||||
|
||||
use crate::world::World;
|
||||
|
||||
#[derive(GodotClass)]
|
||||
#[class(init, base=EditorPlugin, tool)]
|
||||
pub struct WorldPlugin {
|
||||
#[base]
|
||||
base: Base<EditorPlugin>,
|
||||
toolbar_button: Option<Gd<MenuButton>>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl WorldPlugin {
|
||||
// Called when a menu item is selected
|
||||
#[func]
|
||||
fn on_menu_item_pressed(&self, id: i32) {
|
||||
let mut world = match self.find_world_node() {
|
||||
Some(world) => world,
|
||||
None => {
|
||||
godot_error!(
|
||||
"No World node found in the current scene. Make sure it's named 'World' and is a child of the scene root."
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match id {
|
||||
0 => {
|
||||
world.call("clear_terrain", &[]);
|
||||
world.call("generate_terrain", &[]);
|
||||
}
|
||||
1 => {
|
||||
world.call("clear_terrain", &[]);
|
||||
}
|
||||
_ => {
|
||||
godot_print!("Unknown item");
|
||||
}
|
||||
}
|
||||
// Here you can call your actual world management methods.
|
||||
// For example:
|
||||
// if let Some(world_manager) = self.get_world_manager() {
|
||||
// match id {
|
||||
// 0 => world_manager.call("rebuild_world", &[]),
|
||||
// 1 => world_manager.call("clear_world", &[]),
|
||||
// 2 => world_manager.call("reload_chunks", &[]),
|
||||
// _ => (),
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fn find_world_node(&self) -> Option<Gd<World>> {
|
||||
let editor = EditorInterface::singleton();
|
||||
let scene_root = editor.get_edited_scene_root()?;
|
||||
// Assuming the World node is a direct child of the root and named "World"
|
||||
scene_root.try_get_node_as::<World>("World")
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl IEditorPlugin for WorldPlugin {
|
||||
fn enter_tree(&mut self) {
|
||||
// Create the MenuButton
|
||||
let mut menu_button = MenuButton::new_alloc();
|
||||
menu_button.set_text("FastVoxel"); // Button label
|
||||
// menu_button.set_flat(false); // Make it look like a normal button (optional)
|
||||
|
||||
// --- Load an SVG icon and set it ---
|
||||
// Path to your SVG file (relative to the project, e.g., in addons/fastvoxel/fastvoxel.svg)
|
||||
if let Some(icon) = ResourceLoader::singleton().load("res://addons/fastvoxel/fastvoxel.svg")
|
||||
{
|
||||
let icon_texture: Gd<Texture2D> = icon.cast(); // Cast to Texture2D
|
||||
// Get image data, resize, create new texture
|
||||
let mut image = icon_texture.get_image(); // Requires Texture2D to have image data
|
||||
image
|
||||
.as_mut()
|
||||
.expect("failed to load the fastvoxel icon")
|
||||
.resize(24, 24);
|
||||
let small_texture = ImageTexture::create_from_image(image.as_ref());
|
||||
|
||||
menu_button.set_button_icon(small_texture.as_ref());
|
||||
} else {
|
||||
godot_error!("Failed to load plugin icon");
|
||||
}
|
||||
|
||||
// --- Build the dropdown menu ---
|
||||
let mut popup = menu_button.get_popup(); // Returns a PopupMenu
|
||||
popup.as_mut().expect("no popup").add_item("Rebuild World"); // item text, id
|
||||
popup.as_mut().expect("no popup").add_item("Clear World");
|
||||
popup.as_mut().expect("no popup").add_item("Reload Chunks");
|
||||
// You can also add separators, submenus, etc.
|
||||
|
||||
// Connect the popup's "id_pressed" signal to our handler
|
||||
let callable = self.base().callable("on_menu_item_pressed");
|
||||
popup.unwrap().connect("id_pressed", &callable);
|
||||
|
||||
// Add the button to the editor's main toolbar (top row, next to play buttons)
|
||||
self.base_mut().add_control_to_container(
|
||||
CustomControlContainer::SPATIAL_EDITOR_MENU,
|
||||
menu_button.to_godot(),
|
||||
);
|
||||
|
||||
// Store the button reference so we can remove it later
|
||||
self.toolbar_button = Some(menu_button);
|
||||
}
|
||||
|
||||
fn exit_tree(&mut self) {
|
||||
// Clean up: remove the button from the toolbar
|
||||
if let Some(button) = self.toolbar_button.take() {
|
||||
self.base_mut().remove_control_from_container(
|
||||
CustomControlContainer::SPATIAL_EDITOR_MENU,
|
||||
button.to_godot(),
|
||||
);
|
||||
// The button will be freed automatically when no longer referenced
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user