#include "editor.hpp" #include #include #include #include #include #include "imgui-SFML.h" #include "imgui.h" #include "nfd.h" #include "nfd.hpp" #include "tileset.hpp" namespace silly::editor { void Editor::update(const sf::RenderWindow &window) { if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) || sf::Mouse::isButtonPressed(sf::Mouse::Button::Right)) { sf::Vector2i mousePosition = sf::Mouse::getPosition(window); for (int x = 0; x < this->floor.get_width(); x++) { for (int y = 0; y < this->floor.get_height(); y++) { int rx = x * 16, ry = y * 16; if ((rx < mousePosition.x && mousePosition.x < rx + 16) && (ry < mousePosition.y && mousePosition.y < ry + 16)) { sf::Vector2i pos(x, y); if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && this->selectedTile.has_value()) { this->floor.place_tile(this->selectedTile.value(), pos); } else if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Right)) { this->floor.remove_tile(pos); } } } } } } void Editor::render(const sf::RenderWindow &window) { sf::Vector2u windowSize = window.getSize(); int width = 400; int height = windowSize.y; int x = windowSize.x - width; int y = 0; ImGui::SetNextWindowPos(ImVec2(x, y)); ImGui::SetNextWindowSize(ImVec2(width, height)); ImGui::Begin("Editor", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); // --- SELECTED TILE --- if (this->selectedTile.has_value()) { TilesetTile *t = this->selectedTile->get(); if (t->id == TILE_FLOOR) { ImGui::Text("FLOOR"); } else if (t->id == TILE_WALL) { ImGui::Text("WALL"); } else { ImGui::Text("UNKNOWN"); } ImGui::Image(t->texture, sf::Vector2f(64, 64)); } else { ImGui::Text("NO TILE SELECTED!"); ImGui::Dummy(ImVec2(64, 64)); } // --- TILE SELECTION --- ImGui::BeginChild("TileSelectionRegion", ImVec2(0, 400), ImGuiChildFlags_Border, ImGuiWindowFlags_HorizontalScrollbar); float padding = 10.0f; float imageSize = TILE_WIDTH * 2.5f; int columns = ImGui::GetContentRegionAvail().x / (imageSize + padding); int count = 0; for (auto it = this->tileset.get_tiles().begin(); it != this->tileset.get_tiles().end(); ++it) { if (ImGui::ImageButton(std::to_string(it->get()->id).c_str(), it->get()->texture, sf::Vector2f(imageSize, imageSize))) { this->selectedTile = std::make_optional(*it); } count++; if (count % columns != 0) { ImGui::SameLine(); } } ImGui::EndChild(); // --- "CREATING A NEW TILE" WINDOW --- if (ImGui::Button("Add tile") && !this->newTileState.has_value()) { this->newTileState = std::make_optional((NewTileState){"", {}, TILE_FLOOR}); } if (this->newTileState.has_value()) { NewTileState &state = this->newTileState.value(); ImGui::SetNextWindowPos( ImVec2(windowSize.x / 2.0f - 200, windowSize.y / 2.0f - 250)); ImGui::SetNextWindowSize(ImVec2(400, 500)); ImGui::Begin("Creating a new tile", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize); // -- Tile type -- ImGui::Text("Tile type"); if (ImGui::RadioButton("Floor", state.type == TILE_FLOOR)) { state.type = TILE_FLOOR; } ImGui::SameLine(); if (ImGui::RadioButton("Wall", state.type == TILE_WALL)) { state.type = TILE_WALL; } // -- Texture loading -- ImGui::Text("2D"); if (!state.path.empty()) { ImGui::Image(state.texture); ImGui::SameLine(); } if (ImGui::Button("Load texture file")) { NFD::UniquePath outPath; nfdfilteritem_t filterItem[1] = {{"Images", "png"}}; nfdresult_t result = NFD::OpenDialog(outPath, filterItem, 1); if (result == NFD_OKAY) { state.path = outPath.get(); if (!state.texture.loadFromFile(state.path)) { state.path = ""; } } } // -- Tile preview -- if (!state.path.empty()) { for (int y = 0; y <= 5; y++) { for (int x = 0; x <= 10; x++) { ImGui::Image(state.texture); if (x < 10) { ImGui::SameLine(0, 0); } } } } // -- Tile creation -- if (ImGui::Button("Create a new tile")) { this->tileset.add_tile(state.path, state.type); ImGui::SetWindowCollapsed(true); } if (ImGui::IsWindowCollapsed()) { ImGui::SetWindowCollapsed(false); this->newTileState = std::nullopt; } ImGui::End(); } ImGui::End(); } }