From e7631cda9aa763b07ab58e4cd0039cc791110c98 Mon Sep 17 00:00:00 2001 From: glaszczkoldre Date: Wed, 3 Jun 2026 22:48:10 +0200 Subject: [PATCH 1/2] refactor(ui): extract MapPropertiesDialog into MapPropertiesPanel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted map property editing logic into a reusable `MapPropertiesPanel` to unify UI patterns with `NewMapPanel` and added client version registry support. Improved dialog layout by using child containers for better space management and added support for escaping the dialog. - `ImguiMapEditor/Application/CallbackMediator.cpp` — injected version registry into `map_properties` dialog - `ImguiMapEditor/CMakeLists.txt` — added `MapPropertiesPanel.cpp` to build - `ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp` — improved modal layout using `BeginChild` and added Escape key handler - `ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.cpp` — refactored to use `MapPropertiesPanel` and added support for disabling on SEC maps - `ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.h` — updated to use `MapPropertiesPanel` component - `ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp` — implemented new panel for rendering and managing map properties - `ImguiMapEditor/UI/Panels/MapPropertiesPanel.h` — defined interface for `MapPropertiesPanel` - `ImguiMapEditor/UI/Panels/NewMapPanel.cpp` — updated child container borders and height configuration --- .../Application/CallbackMediator.cpp | 5 + ImguiMapEditor/CMakeLists.txt | 1 + ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp | 26 ++- .../Properties/MapPropertiesDialog.cpp | 219 +++++++----------- .../Dialogs/Properties/MapPropertiesDialog.h | 68 ++---- .../UI/Panels/MapPropertiesPanel.cpp | 174 ++++++++++++++ ImguiMapEditor/UI/Panels/MapPropertiesPanel.h | 40 ++++ ImguiMapEditor/UI/Panels/NewMapPanel.cpp | 6 +- 8 files changed, 344 insertions(+), 195 deletions(-) create mode 100644 ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp create mode 100644 ImguiMapEditor/UI/Panels/MapPropertiesPanel.h diff --git a/ImguiMapEditor/Application/CallbackMediator.cpp b/ImguiMapEditor/Application/CallbackMediator.cpp index 2420711..f9a067b 100644 --- a/ImguiMapEditor/Application/CallbackMediator.cpp +++ b/ImguiMapEditor/Application/CallbackMediator.cpp @@ -90,6 +90,11 @@ void CallbackMediator::wireAll(Context &ctx) { }); } + // === Map Properties dialog — inject version registry once === + if (ctx.map_properties && ctx.versions) { + ctx.map_properties->initialize(ctx.versions); + } + wirePlatformCallbacks(ctx); wireTabCallbacks(ctx); wireMapOperationCallbacks(ctx); diff --git a/ImguiMapEditor/CMakeLists.txt b/ImguiMapEditor/CMakeLists.txt index b3ea327..d80f1e4 100644 --- a/ImguiMapEditor/CMakeLists.txt +++ b/ImguiMapEditor/CMakeLists.txt @@ -283,6 +283,7 @@ set(UI_SOURCES UI/Map/MapViewCamera.cpp UI/Map/SelectionMenu.cpp UI/Panels/NewMapPanel.cpp + UI/Panels/MapPropertiesPanel.cpp UI/Panels/BrushSizePanel.cpp UI/PreferencesDialog.cpp UI/Ribbon/Panels/BrushesPanel.cpp diff --git a/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp b/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp index 402890d..52ac66f 100644 --- a/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp @@ -31,15 +31,25 @@ void NewMapDialog::render() { ImGui::SetNextWindowSize( ImVec2(Config::UI::NEW_MAP_DIALOG_W, Config::UI::NEW_MAP_DIALOG_H), ImGuiCond_Appearing); + ImGui::SetNextWindowSizeConstraints( + ImVec2(Config::UI::NEW_MAP_DIALOG_W, Config::UI::NEW_MAP_DIALOG_H), + ImVec2(FLT_MAX, FLT_MAX)); ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 8.0f); ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 6.0f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f); if (ImGui::BeginPopupModal("New Map##EditorModal", nullptr, - ImGuiWindowFlags_NoResize)) { + ImGuiWindowFlags_None)) { + + // Content area: fill all space minus footer + float footer_h = ImGui::GetFrameHeightWithSpacing() + ImGui::GetStyle().ItemSpacing.y * 2; + float content_h = ImGui::GetContentRegionAvail().y - footer_h; + if (content_h < 100.0f) content_h = 100.0f; + + // === TABS + CONTENT === + ImGui::BeginChild("##content", ImVec2(0, content_h), ImGuiChildFlags_None); - // === TABS === if (ImGui::BeginTabBar("##NewMapTabs")) { if (ImGui::BeginTabItem("OTBM")) { ImGui::Spacing(); @@ -60,11 +70,11 @@ void NewMapDialog::render() { ImGui::EndTabBar(); } - ImGui::Spacing(); + ImGui::EndChild(); + + // === FOOTER: always visible at the bottom === ImGui::Separator(); - ImGui::Spacing(); - // === FOOTER === float button_width = Config::UI::MODAL_BUTTON_W; float total_width = button_width * 2 + 10.0f; ImGui::SetCursorPosX((ImGui::GetWindowWidth() - total_width) / 2.0f); @@ -110,6 +120,12 @@ void NewMapDialog::render() { } } + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + visible_ = false; + state_ = {}; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); } diff --git a/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.cpp b/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.cpp index d3de573..c4b485e 100644 --- a/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.cpp @@ -1,19 +1,27 @@ #include "MapPropertiesDialog.h" +#include "Core/Config.h" #include "Presentation/NotificationHelper.h" -#include -#include +#include "UI/Core/Theme.h" +#include "ext/fontawesome6/IconsFontAwesome6.h" +#include #include namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + +void MapPropertiesDialog::initialize(Services::ClientVersionRegistry *registry) { + panel_.initialize(registry); +} + void MapPropertiesDialog::show(Domain::ChunkedMap *map) { if (!map) return; map_ = map; + state_ = panel_.loadFromMap(map); should_open_ = true; - loadFromMap(); } MapPropertiesDialog::Result MapPropertiesDialog::render() { @@ -25,114 +33,77 @@ MapPropertiesDialog::Result MapPropertiesDialog::render() { is_open_ = true; } - // Center dialog ImVec2 center = ImGui::GetMainViewport()->GetCenter(); ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - ImGui::SetNextWindowSize(ImVec2(450, 420), ImGuiCond_Appearing); - - if (ImGui::BeginPopupModal("Map Properties###MapPropertiesDialog", nullptr, - ImGuiWindowFlags_NoResize)) { - - // === Description === - ImGui::Text(ICON_FA_FILE_LINES " Description:"); - ImGui::SetNextItemWidth(-1); - ImGui::InputTextMultiline("##Description", description_buffer_, - sizeof(description_buffer_), ImVec2(-1, 80)); - - ImGui::Separator(); - - // === Dimensions === - ImGui::Text(ICON_FA_RULER_COMBINED " Map Size:"); - - ImGui::Text("Width:"); - ImGui::SameLine(80); - ImGui::SetNextItemWidth(100); - ImGui::InputInt("##Width", &width_, 0, 0); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Map width in tiles (Min: 256, Max: 65535)"); - } - width_ = std::clamp(width_, 256, 65535); - - ImGui::SameLine(); - ImGui::Text("Height:"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(100); - ImGui::InputInt("##Height", &height_, 0, 0); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Map height in tiles (Min: 256, Max: 65535)"); - } - height_ = std::clamp(height_, 256, 65535); - - ImGui::Separator(); - - // === Version Info (read-only for now) === - ImGui::Text(ICON_FA_CODE_BRANCH " Version Information:"); - ImGui::TextDisabled("(Version conversion coming in future update)"); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("To change map version, create a new map and copy " - "content.\nDirect conversion is not yet supported."); - } - - ImGui::Text("OTBM Version:"); - ImGui::SameLine(120); - ImGui::Text("%u", otbm_version_); - - ImGui::Text("Client Version:"); - ImGui::SameLine(120); - ImGui::Text("%u", client_version_); - - ImGui::Separator(); - - // === External Files === - ImGui::Text(ICON_FA_LINK " External Files:"); - - ImGui::Text("House File:"); - ImGui::SameLine(100); - ImGui::SetNextItemWidth(-1); - ImGui::InputText("##HouseFile", house_filename_, sizeof(house_filename_)); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip( - "External XML file for house data (e.g., map-houses.xml)"); - } - - ImGui::Text("Spawn File:"); - ImGui::SameLine(100); - ImGui::SetNextItemWidth(-1); - ImGui::InputText("##SpawnFile", spawn_filename_, sizeof(spawn_filename_)); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip( - "External XML file for spawn data (e.g., map-spawns.xml)"); - } + constexpr float PROPERTIES_DIALOG_H = Config::UI::NEW_MAP_DIALOG_H + 50.0f; + ImGui::SetNextWindowSize(ImVec2(Config::UI::NEW_MAP_DIALOG_W, PROPERTIES_DIALOG_H), ImGuiCond_Appearing); + ImGui::SetNextWindowSizeConstraints(ImVec2(Config::UI::NEW_MAP_DIALOG_W, PROPERTIES_DIALOG_H), + ImVec2(FLT_MAX, FLT_MAX)); - ImGui::Separator(); + ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 8.0f); + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 6.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f); - // === OK / Cancel === - float button_width = 120.0f; - float spacing = ImGui::GetStyle().ItemSpacing.x; - float total_width = button_width * 2 + spacing; - float start_x = (ImGui::GetContentRegionAvail().x - total_width) * 0.5f; - - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + start_x); - - if (ImGui::Button(ICON_FA_CHECK " OK", ImVec2(button_width, 0))) { - applyToMap(); - result = Result::Applied; - Presentation::showSuccess("Map properties updated!"); - ImGui::CloseCurrentPopup(); - is_open_ = false; - } - if (ImGui::IsItemHovered()) ImGui::SetTooltip("Apply changes and close"); - - ImGui::SameLine(); - - if (ImGui::Button(ICON_FA_BAN " Cancel", ImVec2(button_width, 0))) { - result = Result::Cancelled; - ImGui::CloseCurrentPopup(); - is_open_ = false; + if (ImGui::BeginPopupModal("Map Properties###MapPropertiesDialog", nullptr, + ImGuiWindowFlags_None)) { + + bool is_otbm = map_ && + std::filesystem::path(map_->getFilename()).extension() == ".otbm"; + + if (!is_otbm) { + ImGui::Spacing(); + ImGui::TextColored(SC::TextDim(), + ICON_FA_TRIANGLE_EXCLAMATION + " Map properties are not supported for SEC maps."); + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + float button_width = Config::UI::MODAL_BUTTON_W; + ImGui::SetCursorPosX((ImGui::GetWindowWidth() - button_width) / 2.0f); + if (ImGui::Button("Close", ImVec2(button_width, 0))) { + result = Result::Cancelled; + ImGui::CloseCurrentPopup(); + is_open_ = false; + } + } else { + // Content area: fill all space minus footer + float footer_h = ImGui::GetFrameHeightWithSpacing() + ImGui::GetStyle().ItemSpacing.y * 2; + float content_h = ImGui::GetContentRegionAvail().y - footer_h; + if (content_h < 100.0f) content_h = 100.0f; + + ImGui::BeginChild("##content", ImVec2(0, content_h), ImGuiChildFlags_None); + panel_.render(state_); + ImGui::EndChild(); + + // Footer: always visible at the bottom + ImGui::Separator(); + float button_width = Config::UI::MODAL_BUTTON_W; + float total_width = button_width * 2 + 10.0f; + ImGui::SetCursorPosX((ImGui::GetWindowWidth() - total_width) / 2.0f); + + if (ImGui::Button("Cancel", ImVec2(button_width, 0))) { + result = Result::Cancelled; + ImGui::CloseCurrentPopup(); + is_open_ = false; + } + + ImGui::SameLine(0, 10.0f); + + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); + + if (ImGui::Button(ICON_FA_CHECK " OK", ImVec2(button_width, 0))) { + applyToMap(); + result = Result::Applied; + Presentation::showSuccess("Map properties updated!"); + ImGui::CloseCurrentPopup(); + is_open_ = false; + } + + ImGui::PopStyleColor(2); } - if (ImGui::IsItemHovered()) ImGui::SetTooltip("Discard changes (Esc)"); - // Escape to close if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { result = Result::Cancelled; ImGui::CloseCurrentPopup(); @@ -141,50 +112,22 @@ MapPropertiesDialog::Result MapPropertiesDialog::render() { ImGui::EndPopup(); } else if (is_open_) { - // Popup was closed externally is_open_ = false; result = Result::Cancelled; } - return result; -} - -void MapPropertiesDialog::loadFromMap() { - if (!map_) - return; + ImGui::PopStyleVar(3); - // Description - strncpy(description_buffer_, map_->getDescription().c_str(), - sizeof(description_buffer_) - 1); - description_buffer_[sizeof(description_buffer_) - 1] = '\0'; - - // Dimensions - width_ = map_->getWidth(); - height_ = map_->getHeight(); - - // Version info - const auto &version = map_->getVersion(); - otbm_version_ = version.otbm_version; - client_version_ = version.client_version; - - // External files - strncpy(house_filename_, map_->getHouseFile().c_str(), - sizeof(house_filename_) - 1); - house_filename_[sizeof(house_filename_) - 1] = '\0'; - - strncpy(spawn_filename_, map_->getSpawnFile().c_str(), - sizeof(spawn_filename_) - 1); - spawn_filename_[sizeof(spawn_filename_) - 1] = '\0'; + return result; } void MapPropertiesDialog::applyToMap() { if (!map_) return; - map_->setDescription(description_buffer_); - map_->setSize(static_cast(width_), static_cast(height_)); - map_->setHouseFile(house_filename_); - map_->setSpawnFile(spawn_filename_); + map_->setDescription(state_.description); + map_->setHouseFile(state_.house_file); + map_->setSpawnFile(state_.spawn_file); } } // namespace UI diff --git a/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.h b/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.h index 13515da..d3ee072 100644 --- a/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.h +++ b/ImguiMapEditor/UI/Dialogs/Properties/MapPropertiesDialog.h @@ -1,63 +1,33 @@ #pragma once #include "Domain/ChunkedMap.h" +#include "UI/Panels/MapPropertiesPanel.h" #include namespace MapEditor { namespace UI { -/** - * Dialog for editing map properties/metadata. - * - * Editable properties: - * - Description (multi-line text) - * - Width and Height - * - External house/spawn file references - * - * Note: Version conversion is deferred to a future release. - * The dialog displays version info but doesn't allow changes yet. - */ class MapPropertiesDialog { public: - enum class Result { - None, // Dialog still open - Applied, // User clicked OK - changes applied - Cancelled // User cancelled - no changes - }; - - /** - * Show the dialog with the given map. - */ - void show(Domain::ChunkedMap* map); - - /** - * Render the dialog. Call every frame. - * @return Result of user action - */ - Result render(); - - /** - * Check if dialog is open - */ - bool isOpen() const { return is_open_; } + enum class Result { + None, + Applied, + Cancelled + }; + + void initialize(Services::ClientVersionRegistry *registry); + void show(Domain::ChunkedMap *map); + Result render(); + bool isOpen() const { return is_open_; } private: - void loadFromMap(); - void applyToMap(); - - bool should_open_ = false; - bool is_open_ = false; - Domain::ChunkedMap* map_ = nullptr; - - // Buffers for editing - char description_buffer_[4096] = {}; - int width_ = 2048; - int height_ = 2048; - char house_filename_[256] = {}; - char spawn_filename_[256] = {}; - - // Read-only version display - uint32_t otbm_version_ = 0; - uint32_t client_version_ = 0; + void applyToMap(); + + bool should_open_ = false; + bool is_open_ = false; + Domain::ChunkedMap *map_ = nullptr; + + MapPropertiesPanel panel_; + MapPropertiesPanel::State state_; }; } // namespace UI diff --git a/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp b/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp new file mode 100644 index 0000000..3ae6ae5 --- /dev/null +++ b/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp @@ -0,0 +1,174 @@ +#include "UI/Panels/MapPropertiesPanel.h" +#include "Core/Config.h" +#include "Domain/ChunkedMap.h" +#include "UI/Core/Theme.h" +#include "ext/fontawesome6/IconsFontAwesome6.h" +#include +#include +#include + +namespace MapEditor { +namespace UI { + +namespace SC = SemanticColors; + +void MapPropertiesPanel::initialize(Services::ClientVersionRegistry *registry) { + registry_ = registry; +} + +MapPropertiesPanel::State +MapPropertiesPanel::loadFromMap(Domain::ChunkedMap *map) { + State s; + if (!map) + return s; + + s.map_name = map->getName(); + s.description = map->getDescription(); + s.map_width = map->getWidth(); + s.map_height = map->getHeight(); + s.house_file = map->getHouseFile(); + s.spawn_file = map->getSpawnFile(); + + const auto &ver = map->getVersion(); + s.otbm_version = ver.otbm_version; + s.items_major = ver.items_major_version; + s.items_minor = ver.items_minor_version; + + if (registry_) { + auto *cv = registry_->findBestMatch(ver.items_minor_version, + ver.items_major_version); + if (cv) { + s.client_version_name = + std::format("{} ({})", cv->getName(), cv->getVersion()); + } else { + s.client_version_name = + std::format("Unknown (v{})", ver.client_version); + } + } + + return s; +} + +bool MapPropertiesPanel::render(State &state) { + bool changed = false; + auto avail = ImGui::GetContentRegionAvail(); + + float right_w = avail.x * RIGHT_RATIO - ImGui::GetStyle().ItemSpacing.x * 0.5f; + float left_w = avail.x - right_w - ImGui::GetStyle().ItemSpacing.x; + + auto label = SC::TextDim(); + + // ========================================================= + // LEFT COLUMN + // ========================================================= + ImGui::BeginChild("##left", ImVec2(left_w, avail.y), ImGuiChildFlags_Borders); + + // ---- Map Name (read-only) ---- + ImGui::TextColored(label, ICON_FA_FILE " Map Name"); + ImGui::BeginDisabled(); + ImGui::SetNextItemWidth(-1); + ImGui::InputText("##mapname", &state.map_name, ImGuiInputTextFlags_ReadOnly); + ImGui::EndDisabled(); + ImGui::Spacing(); + + // ---- Client Version (read-only) ---- + ImGui::TextColored(label, ICON_FA_CODE_BRANCH " Client Version"); + ImGui::BeginDisabled(); + ImGui::SetNextItemWidth(-1); + ImGui::InputText("##clientver", &state.client_version_name, + ImGuiInputTextFlags_ReadOnly); + ImGui::EndDisabled(); + ImGui::Spacing(); + + // ---- Version Details (read-only) ---- + ImGui::Spacing(); + ImGui::BeginDisabled(); + + float fw = 60.0f; + ImGui::TextColored(label, "OTBM"); ImGui::SameLine(72); + ImGui::TextColored(label, "Major"); ImGui::SameLine(144); + ImGui::TextColored(label, "Minor"); + + ImGui::SetNextItemWidth(fw); + int ov = (int)state.otbm_version; + ImGui::InputInt("##otbm", &ov, 0, 0); + ImGui::SameLine(0, 7); + ImGui::SetNextItemWidth(fw); + int ma = (int)state.items_major; + ImGui::InputInt("##major", &ma, 0, 0); + ImGui::SameLine(0, 7); + ImGui::SetNextItemWidth(fw); + int mi = (int)state.items_minor; + ImGui::InputInt("##minor", &mi, 0, 0); + + ImGui::EndDisabled(); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + // ---- Size (read-only) ---- + ImGui::BeginDisabled(); + ImGui::TextColored(label, "Size"); + ImGui::SameLine(90); + ImGui::TextColored(label, "X"); + ImGui::SameLine(175); + ImGui::TextColored(label, "Y"); + + ImGui::SetNextItemWidth(80); + int w = state.map_width; + ImGui::InputInt("##w", &w, 0, 0); + ImGui::SameLine(0, 8); + ImGui::SetNextItemWidth(80); + int h = state.map_height; + ImGui::InputInt("##h", &h, 0, 0); + ImGui::EndDisabled(); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + // ---- External Files (editable) ---- + ImGui::TextColored(label, ICON_FA_LINK " External Files"); + + ImGui::Text("House File:"); + ImGui::SameLine(100); + ImGui::SetNextItemWidth(-1); + if (ImGui::InputText("##housefile", &state.house_file)) + changed = true; + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("External XML file for house data (e.g., map-houses.xml)"); + } + + ImGui::Text("Spawn File:"); + ImGui::SameLine(100); + ImGui::SetNextItemWidth(-1); + if (ImGui::InputText("##spawnfile", &state.spawn_file)) + changed = true; + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("External XML file for spawn data (e.g., map-spawns.xml)"); + } + + ImGui::EndChild(); + + ImGui::SameLine(); + + // ========================================================= + // RIGHT COLUMN — Description + // ========================================================= + ImGui::BeginChild("##right", ImVec2(right_w, avail.y), ImGuiChildFlags_Borders); + ImGui::TextColored(label, ICON_FA_FILE_LINES " Description"); + ImGui::Spacing(); + auto desc_before = state.description; + ImGui::InputTextMultiline("##desc", &state.description, + ImVec2(-1, ImGui::GetContentRegionAvail().y - 1), + ImGuiInputTextFlags_None); + if (state.description != desc_before) + changed = true; + ImGui::EndChild(); + + return changed; +} + +} // namespace UI +} // namespace MapEditor diff --git a/ImguiMapEditor/UI/Panels/MapPropertiesPanel.h b/ImguiMapEditor/UI/Panels/MapPropertiesPanel.h new file mode 100644 index 0000000..915aa2d --- /dev/null +++ b/ImguiMapEditor/UI/Panels/MapPropertiesPanel.h @@ -0,0 +1,40 @@ +#pragma once +#include "Services/ClientVersionRegistry.h" +#include +#include + +namespace MapEditor { +namespace Domain { +class ChunkedMap; +} + +namespace UI { + +class MapPropertiesPanel { +public: + static constexpr float LEFT_RATIO = 0.60f; + static constexpr float RIGHT_RATIO = 0.40f; + + struct State { + std::string map_name; + uint32_t otbm_version = 0; + uint32_t items_major = 0; + uint32_t items_minor = 0; + std::string client_version_name; + uint16_t map_width = 0; + uint16_t map_height = 0; + std::string description; + std::string house_file; + std::string spawn_file; + }; + + void initialize(Services::ClientVersionRegistry *registry); + State loadFromMap(Domain::ChunkedMap *map); + bool render(State &state); + +private: + Services::ClientVersionRegistry *registry_ = nullptr; +}; + +} // namespace UI +} // namespace MapEditor diff --git a/ImguiMapEditor/UI/Panels/NewMapPanel.cpp b/ImguiMapEditor/UI/Panels/NewMapPanel.cpp index 32cd9af..8302e05 100644 --- a/ImguiMapEditor/UI/Panels/NewMapPanel.cpp +++ b/ImguiMapEditor/UI/Panels/NewMapPanel.cpp @@ -44,8 +44,8 @@ bool NewMapPanel::render(State &state) { // ========================================================= // LEFT COLUMN // ========================================================= - float content_h = 200.0f; - ImGui::BeginChild("##left", ImVec2(left_w, content_h), ImGuiChildFlags_None); + float content_h = avail.y; + ImGui::BeginChild("##left", ImVec2(left_w, content_h), ImGuiChildFlags_Borders); // ---- Map Name ---- ImGui::TextColored(label, ICON_FA_FILE " Map Name"); @@ -156,7 +156,7 @@ bool NewMapPanel::render(State &state) { // ========================================================= // RIGHT COLUMN — Description (compact, ~3 lines) // ========================================================= - ImGui::BeginChild("##right", ImVec2(right_w, content_h), ImGuiChildFlags_None); + ImGui::BeginChild("##right", ImVec2(right_w, content_h), ImGuiChildFlags_Borders); ImGui::TextColored(label, ICON_FA_FILE_LINES " Description"); ImGui::Spacing(); auto desc_before = state.description; From 6a79be981573dcdb0bdf541411d44bf762d3e1c0 Mon Sep 17 00:00:00 2001 From: glaszczkoldre Date: Wed, 3 Jun 2026 22:57:19 +0200 Subject: [PATCH 2/2] refactor(ui): streamline description inputs and version display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplified description input change detection in map panels and streamlined client version naming logic in properties. Replaced manual state comparison with return-value checking for ImGui inputs and consolidated version formatting defaults. - `ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp` — initialized client_version_name before lookup, simplified InputTextMultiline change detection - `ImguiMapEditor/UI/Panels/NewMapPanel.cpp` — simplified InputTextMultiline change detection using function return value --- ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp | 12 ++++-------- ImguiMapEditor/UI/Panels/NewMapPanel.cpp | 8 +++----- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp b/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp index 3ae6ae5..488215d 100644 --- a/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp +++ b/ImguiMapEditor/UI/Panels/MapPropertiesPanel.cpp @@ -34,15 +34,13 @@ MapPropertiesPanel::loadFromMap(Domain::ChunkedMap *map) { s.items_major = ver.items_major_version; s.items_minor = ver.items_minor_version; + s.client_version_name = std::format("Unknown (v{})", ver.client_version); if (registry_) { auto *cv = registry_->findBestMatch(ver.items_minor_version, ver.items_major_version); if (cv) { s.client_version_name = std::format("{} ({})", cv->getName(), cv->getVersion()); - } else { - s.client_version_name = - std::format("Unknown (v{})", ver.client_version); } } @@ -159,11 +157,9 @@ bool MapPropertiesPanel::render(State &state) { ImGui::BeginChild("##right", ImVec2(right_w, avail.y), ImGuiChildFlags_Borders); ImGui::TextColored(label, ICON_FA_FILE_LINES " Description"); ImGui::Spacing(); - auto desc_before = state.description; - ImGui::InputTextMultiline("##desc", &state.description, - ImVec2(-1, ImGui::GetContentRegionAvail().y - 1), - ImGuiInputTextFlags_None); - if (state.description != desc_before) + if (ImGui::InputTextMultiline("##desc", &state.description, + ImVec2(-1, ImGui::GetContentRegionAvail().y - 1), + ImGuiInputTextFlags_None)) changed = true; ImGui::EndChild(); diff --git a/ImguiMapEditor/UI/Panels/NewMapPanel.cpp b/ImguiMapEditor/UI/Panels/NewMapPanel.cpp index 8302e05..e77f8ae 100644 --- a/ImguiMapEditor/UI/Panels/NewMapPanel.cpp +++ b/ImguiMapEditor/UI/Panels/NewMapPanel.cpp @@ -159,11 +159,9 @@ bool NewMapPanel::render(State &state) { ImGui::BeginChild("##right", ImVec2(right_w, content_h), ImGuiChildFlags_Borders); ImGui::TextColored(label, ICON_FA_FILE_LINES " Description"); ImGui::Spacing(); - auto desc_before = state.description; - ImGui::InputTextMultiline("##desc", &state.description, - ImVec2(-1, ImGui::GetContentRegionAvail().y - 1), - ImGuiInputTextFlags_None); - if (state.description != desc_before) + if (ImGui::InputTextMultiline("##desc", &state.description, + ImVec2(-1, ImGui::GetContentRegionAvail().y - 1), + ImGuiInputTextFlags_None)) changed = true; ImGui::EndChild();