use crate::ui::dialogs::PendingAction;
use crate::{EditorState, EditorViewMode};
use bevy_egui::egui;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum EditorTool {
#[default]
Select,
Paint,
Erase,
Fill,
Terrain,
Entity,
}
impl EditorTool {
pub fn supports_modes(&self) -> bool {
matches!(
self,
EditorTool::Paint | EditorTool::Erase | EditorTool::Terrain
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum ToolMode {
#[default]
Point,
Rectangle,
Line,
}
impl ToolMode {
pub fn label(&self) -> &'static str {
match self {
ToolMode::Point => "Point",
ToolMode::Rectangle => "Rect",
ToolMode::Line => "Line",
}
}
}
pub fn render_toolbar(ctx: &egui::Context, editor_state: &mut EditorState) {
egui::TopBottomPanel::top("toolbar").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.label("View:");
if ui
.selectable_label(editor_state.view_mode == EditorViewMode::Level, "Level")
.on_hover_text("Edit level (L)")
.clicked()
{
editor_state.view_mode = EditorViewMode::Level;
}
if ui
.selectable_label(editor_state.view_mode == EditorViewMode::World, "World")
.on_hover_text("World overview (W)")
.clicked()
{
editor_state.view_mode = EditorViewMode::World;
}
ui.separator();
let tools_enabled = editor_state.view_mode == EditorViewMode::Level;
if !tools_enabled {
ui.disable();
}
ui.label("Tools:");
if ui
.selectable_label(editor_state.current_tool == EditorTool::Select, "Select")
.clicked()
{
editor_state.current_tool = EditorTool::Select;
}
ui.separator();
let paint_tools = [
(EditorTool::Paint, "Paint"),
(EditorTool::Erase, "Erase"),
(EditorTool::Fill, "Fill"),
];
for (tool, name) in paint_tools {
if ui
.selectable_label(editor_state.current_tool == tool, name)
.clicked()
{
editor_state.current_tool = tool;
}
}
ui.separator();
if ui
.selectable_label(editor_state.current_tool == EditorTool::Terrain, "Terrain")
.clicked()
{
editor_state.current_tool = EditorTool::Terrain;
}
ui.separator();
if ui
.selectable_label(editor_state.current_tool == EditorTool::Entity, "Entity")
.clicked()
{
editor_state.current_tool = EditorTool::Entity;
}
ui.separator();
if editor_state.current_tool.supports_modes() {
ui.label("Mode:");
egui::ComboBox::from_id_salt("tool_mode")
.selected_text(editor_state.tool_mode.label())
.width(80.0)
.show_ui(ui, |ui| {
ui.selectable_value(
&mut editor_state.tool_mode,
ToolMode::Point,
ToolMode::Point.label(),
);
ui.selectable_value(
&mut editor_state.tool_mode,
ToolMode::Rectangle,
ToolMode::Rectangle.label(),
);
ui.selectable_value(
&mut editor_state.tool_mode,
ToolMode::Line,
ToolMode::Line.label(),
);
});
if editor_state.current_tool == EditorTool::Paint {
ui.toggle_value(&mut editor_state.random_paint, "Random")
.on_hover_text(
"Paint random tiles from selection (Ctrl+click to add tiles)",
);
}
if editor_state.current_tool == EditorTool::Paint {
ui.toggle_value(&mut editor_state.paint_flip_x, "X")
.on_hover_text("Flip tile horizontally (X key)");
ui.toggle_value(&mut editor_state.paint_flip_y, "Y")
.on_hover_text("Flip tile vertically (Y key)");
}
ui.separator();
}
ui.label("Layer:");
if let Some(layer_idx) = editor_state.selected_layer {
ui.label(format!("{}", layer_idx));
} else {
ui.label("(none)");
}
ui.separator();
ui.checkbox(&mut editor_state.show_grid, "Grid");
ui.separator();
if ui.button("-").clicked() {
editor_state.zoom = (editor_state.zoom / 1.25).max(0.25);
}
ui.label(format!("{}%", (editor_state.zoom * 100.0) as i32));
if ui.button("+").clicked() {
editor_state.zoom = (editor_state.zoom * 1.25).min(4.0);
}
ui.separator();
if ui.button("Tileset Editor").clicked() {
editor_state.show_tileset_editor = true;
}
ui.separator();
if ui
.button("Run Game")
.on_hover_text("Run the game (saves project first)")
.clicked()
{
editor_state.pending_action = Some(PendingAction::RunGame);
}
});
});
}