feat: Implement Jump-to Functionality for Cross-Editor Navigation
- Added JumpToDungeonRoom and JumpToOverworldMap methods to facilitate quick navigation between dungeon and overworld editors. - Introduced SwitchToEditor method to manage editor tab activation based on the selected editor type. - Enhanced DungeonEditorV2 with room and entrance selection capabilities, improving user experience and workflow efficiency. - Updated header files to declare new methods and ensure proper integration within the editor management system.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "dungeon_editor_v2.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
@@ -55,7 +56,7 @@ absl::Status DungeonEditorV2::Load() {
|
||||
palette_editor_.Initialize(rom_);
|
||||
|
||||
// Wire palette changes to trigger room re-renders
|
||||
palette_editor_.SetOnPaletteChanged([this](int palette_id) {
|
||||
palette_editor_.SetOnPaletteChanged([this](int /*palette_id*/) {
|
||||
// Re-render all active rooms when palette changes
|
||||
for (int i = 0; i < active_rooms_.Size; i++) {
|
||||
int room_id = active_rooms_[i];
|
||||
@@ -118,6 +119,30 @@ void DungeonEditorV2::DrawToolset() {
|
||||
if (toolbar.AddAction(ICON_MD_ADD, "Open Room")) {
|
||||
OnRoomSelected(room_selector_.current_room_id());
|
||||
}
|
||||
|
||||
toolbar.AddSeparator();
|
||||
|
||||
if (toolbar.AddToggle(ICON_MD_LIST, &show_room_selector_, "Toggle Room Selector")) {
|
||||
// Toggled
|
||||
}
|
||||
|
||||
if (toolbar.AddToggle(ICON_MD_GRID_VIEW, &show_room_matrix_, "Toggle Room Matrix")) {
|
||||
// Toggled
|
||||
}
|
||||
|
||||
if (toolbar.AddToggle(ICON_MD_DOOR_FRONT, &show_entrances_list_, "Toggle Entrances List")) {
|
||||
// Toggled
|
||||
}
|
||||
|
||||
toolbar.AddSeparator();
|
||||
|
||||
if (toolbar.AddToggle(ICON_MD_CATEGORY, &show_object_selector_, "Toggle Object Selector")) {
|
||||
// Toggled
|
||||
}
|
||||
|
||||
if (toolbar.AddToggle(ICON_MD_PALETTE, &show_palette_editor_, "Toggle Palette Editor")) {
|
||||
// Toggled
|
||||
}
|
||||
|
||||
toolbar.End();
|
||||
}
|
||||
@@ -126,42 +151,43 @@ void DungeonEditorV2::DrawLayout() {
|
||||
// NO TABLE LAYOUT - All independent dockable EditorCards
|
||||
|
||||
// 1. Room Selector Card (independent, dockable)
|
||||
{
|
||||
static bool show_room_selector = true;
|
||||
gui::EditorCard selector_card(
|
||||
MakeCardTitle("Room Selector").c_str(),
|
||||
ICON_MD_LIST, &show_room_selector);
|
||||
if (selector_card.Begin()) {
|
||||
room_selector_.Draw();
|
||||
}
|
||||
selector_card.End();
|
||||
if (show_room_selector_) {
|
||||
DrawRoomsListCard();
|
||||
}
|
||||
|
||||
// 2. Room Matrix Card (visual navigation)
|
||||
if (show_room_matrix_) {
|
||||
DrawRoomMatrixCard();
|
||||
}
|
||||
|
||||
// 3. Entrances List Card
|
||||
if (show_entrances_list_) {
|
||||
DrawEntrancesListCard();
|
||||
}
|
||||
|
||||
// 2. Object Selector/Manager Card (independent, dockable)
|
||||
{
|
||||
static bool show_object_selector = true;
|
||||
// 4. Object Selector/Manager Card (independent, dockable)
|
||||
if (show_object_selector_) {
|
||||
gui::EditorCard object_card(
|
||||
MakeCardTitle("Object Selector").c_str(),
|
||||
ICON_MD_CATEGORY, &show_object_selector);
|
||||
ICON_MD_CATEGORY, &show_object_selector_);
|
||||
if (object_card.Begin()) {
|
||||
object_selector_.Draw();
|
||||
}
|
||||
object_card.End();
|
||||
}
|
||||
|
||||
// 3. Palette Editor Card (independent, dockable)
|
||||
{
|
||||
static bool show_palette_editor = true;
|
||||
// 5. Palette Editor Card (independent, dockable)
|
||||
if (show_palette_editor_) {
|
||||
gui::EditorCard palette_card(
|
||||
MakeCardTitle("Palette Editor").c_str(),
|
||||
ICON_MD_PALETTE, &show_palette_editor);
|
||||
ICON_MD_PALETTE, &show_palette_editor_);
|
||||
if (palette_card.Begin()) {
|
||||
palette_editor_.Draw();
|
||||
}
|
||||
palette_card.End();
|
||||
}
|
||||
|
||||
// 4. Active Room Cards (independent, dockable, no inheritance)
|
||||
// 6. Active Room Cards (independent, dockable, tracked for jump-to)
|
||||
for (int i = 0; i < active_rooms_.Size; i++) {
|
||||
int room_id = active_rooms_[i];
|
||||
bool open = true;
|
||||
@@ -177,14 +203,20 @@ void DungeonEditorV2::DrawLayout() {
|
||||
std::string card_name_str = absl::StrFormat("%s###RoomCard%d",
|
||||
MakeCardTitle(base_name).c_str(), room_id);
|
||||
|
||||
// Each room card is COMPLETELY independent - no parent windows
|
||||
gui::EditorCard room_card(card_name_str.c_str(), ICON_MD_GRID_ON, &open);
|
||||
if (room_card.Begin()) {
|
||||
// Track or create card for jump-to functionality
|
||||
if (room_cards_.find(room_id) == room_cards_.end()) {
|
||||
room_cards_[room_id] = std::make_shared<gui::EditorCard>(
|
||||
card_name_str.c_str(), ICON_MD_GRID_ON, &open);
|
||||
}
|
||||
|
||||
auto& room_card = room_cards_[room_id];
|
||||
if (room_card->Begin(&open)) {
|
||||
DrawRoomTab(room_id);
|
||||
}
|
||||
room_card.End();
|
||||
room_card->End();
|
||||
|
||||
if (!open) {
|
||||
room_cards_.erase(room_id);
|
||||
active_rooms_.erase(active_rooms_.Data + i);
|
||||
i--;
|
||||
}
|
||||
@@ -235,7 +267,8 @@ void DungeonEditorV2::OnRoomSelected(int room_id) {
|
||||
// Check if already open
|
||||
for (int i = 0; i < active_rooms_.Size; i++) {
|
||||
if (active_rooms_[i] == room_id) {
|
||||
// Optional: Focus the existing window if possible. For now, do nothing.
|
||||
// Focus the existing room card
|
||||
FocusRoom(room_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -245,5 +278,212 @@ void DungeonEditorV2::OnRoomSelected(int room_id) {
|
||||
room_selector_.set_active_rooms(active_rooms_);
|
||||
}
|
||||
|
||||
void DungeonEditorV2::OnEntranceSelected(int entrance_id) {
|
||||
if (entrance_id < 0 || entrance_id >= static_cast<int>(entrances_.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the room ID associated with this entrance
|
||||
int room_id = entrances_[entrance_id].room_;
|
||||
|
||||
// Open and focus the room
|
||||
OnRoomSelected(room_id);
|
||||
}
|
||||
|
||||
void DungeonEditorV2::add_room(int room_id) {
|
||||
OnRoomSelected(room_id);
|
||||
}
|
||||
|
||||
void DungeonEditorV2::FocusRoom(int room_id) {
|
||||
// Focus the room card if it exists
|
||||
auto it = room_cards_.find(room_id);
|
||||
if (it != room_cards_.end()) {
|
||||
it->second->Focus();
|
||||
}
|
||||
}
|
||||
|
||||
void DungeonEditorV2::DrawRoomsListCard() {
|
||||
gui::EditorCard selector_card(
|
||||
MakeCardTitle("Rooms List").c_str(),
|
||||
ICON_MD_LIST, &show_room_selector_);
|
||||
|
||||
if (selector_card.Begin()) {
|
||||
// Add text filter
|
||||
static char room_filter[256] = "";
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::InputTextWithHint("##RoomFilter", ICON_MD_SEARCH " Filter rooms...",
|
||||
room_filter, sizeof(room_filter))) {
|
||||
// Filter updated
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Scrollable room list with resource labels
|
||||
if (ImGui::BeginChild("##RoomsList", ImVec2(0, 0), true)) {
|
||||
std::string filter_str = room_filter;
|
||||
std::transform(filter_str.begin(), filter_str.end(), filter_str.begin(), ::tolower);
|
||||
|
||||
for (int i = 0; i < 0x128; i++) {
|
||||
std::string room_name;
|
||||
if (i < static_cast<int>(std::size(zelda3::kRoomNames))) {
|
||||
room_name = absl::StrFormat("%03X - %s", i, zelda3::kRoomNames[i].data());
|
||||
} else {
|
||||
room_name = absl::StrFormat("%03X - Room %d", i, i);
|
||||
}
|
||||
|
||||
// Apply filter
|
||||
if (!filter_str.empty()) {
|
||||
std::string room_name_lower = room_name;
|
||||
std::transform(room_name_lower.begin(), room_name_lower.end(),
|
||||
room_name_lower.begin(), ::tolower);
|
||||
if (room_name_lower.find(filter_str) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_selected = (current_room_id_ == i);
|
||||
if (ImGui::Selectable(room_name.c_str(), is_selected)) {
|
||||
OnRoomSelected(i);
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
|
||||
OnRoomSelected(i);
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
selector_card.End();
|
||||
}
|
||||
|
||||
void DungeonEditorV2::DrawEntrancesListCard() {
|
||||
gui::EditorCard entrances_card(
|
||||
MakeCardTitle("Entrances List").c_str(),
|
||||
ICON_MD_DOOR_FRONT, &show_entrances_list_);
|
||||
|
||||
if (entrances_card.Begin()) {
|
||||
// Add text filter
|
||||
static char entrance_filter[256] = "";
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::InputTextWithHint("##EntranceFilter", ICON_MD_SEARCH " Filter entrances...",
|
||||
entrance_filter, sizeof(entrance_filter))) {
|
||||
// Filter updated
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Scrollable entrance list with associated room names
|
||||
if (ImGui::BeginChild("##EntrancesList", ImVec2(0, 0), true)) {
|
||||
std::string filter_str = entrance_filter;
|
||||
std::transform(filter_str.begin(), filter_str.end(), filter_str.begin(), ::tolower);
|
||||
|
||||
for (int i = 0; i < static_cast<int>(entrances_.size()); i++) {
|
||||
int room_id = entrances_[i].room_;
|
||||
|
||||
std::string room_name = "Unknown";
|
||||
if (room_id >= 0 && room_id < static_cast<int>(std::size(zelda3::kRoomNames))) {
|
||||
room_name = zelda3::kRoomNames[room_id].data();
|
||||
}
|
||||
|
||||
std::string entrance_label = absl::StrFormat("%02X - %s (Room %03X)",
|
||||
i, room_name.c_str(), room_id);
|
||||
|
||||
// Apply filter
|
||||
if (!filter_str.empty()) {
|
||||
std::string entrance_label_lower = entrance_label;
|
||||
std::transform(entrance_label_lower.begin(), entrance_label_lower.end(),
|
||||
entrance_label_lower.begin(), ::tolower);
|
||||
if (entrance_label_lower.find(filter_str) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Selectable(entrance_label.c_str())) {
|
||||
OnEntranceSelected(i);
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
entrances_card.End();
|
||||
}
|
||||
|
||||
void DungeonEditorV2::DrawRoomMatrixCard() {
|
||||
gui::EditorCard matrix_card(
|
||||
MakeCardTitle("Room Matrix").c_str(),
|
||||
ICON_MD_GRID_VIEW, &show_room_matrix_);
|
||||
|
||||
matrix_card.SetDefaultSize(600, 600);
|
||||
|
||||
if (matrix_card.Begin()) {
|
||||
// Draw 8x8 grid of rooms (first 64 rooms)
|
||||
constexpr int kRoomsPerRow = 8;
|
||||
constexpr int kRoomsPerCol = 8;
|
||||
constexpr float kRoomCellSize = 64.0f;
|
||||
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
ImVec2 canvas_pos = ImGui::GetCursorScreenPos();
|
||||
|
||||
for (int row = 0; row < kRoomsPerCol; row++) {
|
||||
for (int col = 0; col < kRoomsPerRow; col++) {
|
||||
int room_id = row * kRoomsPerRow + col;
|
||||
|
||||
ImVec2 cell_min = ImVec2(canvas_pos.x + col * kRoomCellSize,
|
||||
canvas_pos.y + row * kRoomCellSize);
|
||||
ImVec2 cell_max = ImVec2(cell_min.x + kRoomCellSize,
|
||||
cell_min.y + kRoomCellSize);
|
||||
|
||||
// Check if room is active
|
||||
bool is_active = false;
|
||||
for (int i = 0; i < active_rooms_.Size; i++) {
|
||||
if (active_rooms_[i] == room_id) {
|
||||
is_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw cell background
|
||||
ImU32 bg_color = is_active ? IM_COL32(100, 150, 255, 255)
|
||||
: IM_COL32(50, 50, 50, 255);
|
||||
draw_list->AddRectFilled(cell_min, cell_max, bg_color);
|
||||
|
||||
// Draw cell border
|
||||
draw_list->AddRect(cell_min, cell_max, IM_COL32(150, 150, 150, 255));
|
||||
|
||||
// Draw room ID
|
||||
std::string room_label = absl::StrFormat("%02X", room_id);
|
||||
ImVec2 text_size = ImGui::CalcTextSize(room_label.c_str());
|
||||
ImVec2 text_pos = ImVec2(cell_min.x + (kRoomCellSize - text_size.x) * 0.5f,
|
||||
cell_min.y + (kRoomCellSize - text_size.y) * 0.5f);
|
||||
draw_list->AddText(text_pos, IM_COL32(255, 255, 255, 255), room_label.c_str());
|
||||
|
||||
// Handle clicks
|
||||
ImGui::SetCursorScreenPos(cell_min);
|
||||
ImGui::InvisibleButton(absl::StrFormat("##room%d", room_id).c_str(),
|
||||
ImVec2(kRoomCellSize, kRoomCellSize));
|
||||
|
||||
if (ImGui::IsItemClicked()) {
|
||||
OnRoomSelected(room_id);
|
||||
}
|
||||
|
||||
// Hover preview (TODO: implement room bitmap preview)
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
if (room_id < static_cast<int>(std::size(zelda3::kRoomNames))) {
|
||||
ImGui::Text("%s", zelda3::kRoomNames[room_id].data());
|
||||
} else {
|
||||
ImGui::Text("Room %03X", room_id);
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Advance cursor past the grid
|
||||
ImGui::Dummy(ImVec2(kRoomsPerRow * kRoomCellSize, kRoomsPerCol * kRoomCellSize));
|
||||
}
|
||||
matrix_card.End();
|
||||
}
|
||||
|
||||
} // namespace yaze::editor
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
|
||||
#define YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "app/editor/editor.h"
|
||||
@@ -70,7 +73,8 @@ class DungeonEditorV2 : public Editor {
|
||||
Rom* rom() const { return rom_; }
|
||||
|
||||
// Room management
|
||||
void add_room(int room_id) { active_rooms_.push_back(room_id); }
|
||||
void add_room(int room_id);
|
||||
void FocusRoom(int room_id);
|
||||
|
||||
// ROM state
|
||||
bool IsRomLoaded() const override { return rom_ && rom_->is_loaded(); }
|
||||
@@ -85,19 +89,31 @@ class DungeonEditorV2 : public Editor {
|
||||
void DrawLayout();
|
||||
void DrawRoomTab(int room_id);
|
||||
void DrawToolset();
|
||||
void DrawRoomMatrixCard();
|
||||
void DrawRoomsListCard();
|
||||
void DrawEntrancesListCard();
|
||||
|
||||
// Room selection callback
|
||||
void OnRoomSelected(int room_id);
|
||||
void OnEntranceSelected(int entrance_id);
|
||||
|
||||
// Data
|
||||
Rom* rom_;
|
||||
std::array<zelda3::Room, 0x128> rooms_;
|
||||
std::array<zelda3::RoomEntrance, 0x8C> entrances_;
|
||||
|
||||
// Active room tabs
|
||||
// Active room tabs and card tracking for jump-to
|
||||
ImVector<int> active_rooms_;
|
||||
std::unordered_map<int, std::shared_ptr<gui::EditorCard>> room_cards_;
|
||||
int current_room_id_ = 0;
|
||||
|
||||
// Card visibility flags
|
||||
bool show_room_selector_ = true;
|
||||
bool show_room_matrix_ = false;
|
||||
bool show_entrances_list_ = false;
|
||||
bool show_object_selector_ = true;
|
||||
bool show_palette_editor_ = true;
|
||||
|
||||
// Palette management
|
||||
gfx::SnesPalette current_palette_;
|
||||
gfx::PaletteGroup current_palette_group_;
|
||||
|
||||
@@ -3267,5 +3267,42 @@ void EditorManager::DrawWelcomeScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Jump-to Functionality for Cross-Editor Navigation
|
||||
// ============================================================================
|
||||
|
||||
void EditorManager::JumpToDungeonRoom(int room_id) {
|
||||
if (!current_editor_set_) return;
|
||||
|
||||
// Switch to dungeon editor
|
||||
SwitchToEditor(EditorType::kDungeon);
|
||||
|
||||
// Open the room in the dungeon editor
|
||||
current_editor_set_->dungeon_editor_.add_room(room_id);
|
||||
}
|
||||
|
||||
void EditorManager::JumpToOverworldMap(int map_id) {
|
||||
if (!current_editor_set_) return;
|
||||
|
||||
// Switch to overworld editor
|
||||
SwitchToEditor(EditorType::kOverworld);
|
||||
|
||||
// Set the current map in the overworld editor
|
||||
current_editor_set_->overworld_editor_.set_current_map(map_id);
|
||||
}
|
||||
|
||||
void EditorManager::SwitchToEditor(EditorType editor_type) {
|
||||
// Find the editor tab and activate it
|
||||
for (size_t i = 0; i < current_editor_set_->active_editors_.size(); ++i) {
|
||||
if (current_editor_set_->active_editors_[i]->type() == editor_type) {
|
||||
current_editor_set_->active_editors_[i]->set_active(true);
|
||||
|
||||
// Set editor as the current/focused one
|
||||
// This will make it visible when tabs are rendered
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace editor
|
||||
} // namespace yaze
|
||||
|
||||
@@ -134,6 +134,11 @@ class EditorManager {
|
||||
}
|
||||
|
||||
void BuildModernMenu();
|
||||
|
||||
// Jump-to functionality for cross-editor navigation
|
||||
void JumpToDungeonRoom(int room_id);
|
||||
void JumpToOverworldMap(int map_id);
|
||||
void SwitchToEditor(EditorType editor_type);
|
||||
|
||||
private:
|
||||
void DrawWelcomeScreen();
|
||||
|
||||
@@ -101,6 +101,14 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
||||
if (!rom_->is_loaded()) return "ROM failed to load";
|
||||
return absl::StrFormat("ROM loaded: %s", rom_->title());
|
||||
}
|
||||
|
||||
// Jump-to functionality
|
||||
void set_current_map(int map_id) {
|
||||
if (map_id >= 0 && map_id < zelda3::kNumOverworldMaps) {
|
||||
current_map_ = map_id;
|
||||
current_world_ = map_id / 0x40; // Calculate which world the map belongs to
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load the Bitmap objects for each OverworldMap.
|
||||
|
||||
@@ -15,10 +15,10 @@ using namespace ImGui;
|
||||
|
||||
// Entity colors - solid with good visibility
|
||||
namespace {
|
||||
ImVec4 GetEntranceColor() { return ImVec4(0.0f, 255.0f, 0.0f, 255.0f); } // Solid green
|
||||
ImVec4 GetExitColor() { return ImVec4(255.0f, 0.0f, 0.0f, 255.0f); } // Solid red
|
||||
ImVec4 GetItemColor() { return ImVec4(255.0f, 255.0f, 0.0f, 255.0f); } // Solid yellow
|
||||
ImVec4 GetSpriteColor() { return ImVec4(255.0f, 128.0f, 0.0f, 255.0f); } // Solid orange
|
||||
ImVec4 GetEntranceColor() { return ImVec4{1.0f, 1.0f, 0.0f, 1.0f}; } // Solid yellow (#FFFF00FF, fully opaque)
|
||||
ImVec4 GetExitColor() { return ImVec4{1.0f, 1.0f, 1.0f, 1.0f}; } // Solid white (#FFFFFFFF, fully opaque)
|
||||
ImVec4 GetItemColor() { return ImVec4{1.0f, 0.0f, 0.0f, 1.0f}; } // Solid red (#FF0000FF, fully opaque)
|
||||
ImVec4 GetSpriteColor() { return ImVec4{1.0f, 0.0f, 1.0f, 1.0f}; } // Solid magenta (#FF00FFFF, fully opaque)
|
||||
} // namespace
|
||||
|
||||
void OverworldEntityRenderer::DrawEntrances(ImVec2 canvas_p0, ImVec2 scrolling,
|
||||
|
||||
@@ -141,7 +141,7 @@ void DrawCanvasRect(ImDrawList* draw_list, ImVec2 canvas_p0, ImVec2 scrolling,
|
||||
ImVec2 size(canvas_p0.x + scrolling.x + scaled_x + scaled_w,
|
||||
canvas_p0.y + scrolling.y + scaled_y + scaled_h);
|
||||
|
||||
uint32_t color_u32 = IM_COL32(color.x, color.y, color.z, color.w);
|
||||
uint32_t color_u32 = IM_COL32(color.x * 255, color.y * 255, color.z * 255, color.w * 255);
|
||||
draw_list->AddRectFilled(origin, size, color_u32);
|
||||
|
||||
// Add a black outline
|
||||
|
||||
@@ -229,11 +229,14 @@ bool Toolset::AddUsageStatsButton(const char* tooltip) {
|
||||
// ============================================================================
|
||||
|
||||
EditorCard::EditorCard(const char* title, const char* icon)
|
||||
: title_(title), icon_(icon ? icon : ""), default_size_(400, 300) {}
|
||||
: title_(title), icon_(icon ? icon : ""), default_size_(400, 300) {
|
||||
window_name_ = icon_.empty() ? title_ : icon_ + " " + title_;
|
||||
}
|
||||
|
||||
EditorCard::EditorCard(const char* title, const char* icon, bool* p_open)
|
||||
: title_(title), icon_(icon ? icon : ""), default_size_(400, 300) {
|
||||
p_open_ = p_open;
|
||||
window_name_ = icon_.empty() ? title_ : icon_ + " " + title_;
|
||||
}
|
||||
|
||||
void EditorCard::SetDefaultSize(float width, float height) {
|
||||
@@ -301,11 +304,20 @@ bool EditorCard::Begin(bool* p_open) {
|
||||
}
|
||||
|
||||
void EditorCard::End() {
|
||||
// Check if window was focused this frame
|
||||
focused_ = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor(2);
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
void EditorCard::Focus() {
|
||||
// Set window focus using ImGui's focus system
|
||||
ImGui::SetWindowFocus(window_name_.c_str());
|
||||
focused_ = true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EditorLayout Implementation
|
||||
// ============================================================================
|
||||
|
||||
@@ -132,15 +132,24 @@ class EditorCard {
|
||||
void SetMinimized(bool minimized) { minimized_ = minimized; }
|
||||
bool IsMinimized() const { return minimized_; }
|
||||
|
||||
// Focus the card window (bring to front and set focused)
|
||||
void Focus();
|
||||
bool IsFocused() const { return focused_; }
|
||||
|
||||
// Get the window name for ImGui operations
|
||||
const char* GetWindowName() const { return window_name_.c_str(); }
|
||||
|
||||
private:
|
||||
std::string title_;
|
||||
std::string icon_;
|
||||
std::string window_name_; // Full window name with icon
|
||||
ImVec2 default_size_;
|
||||
Position position_ = Position::Free;
|
||||
bool minimizable_ = true;
|
||||
bool closable_ = true;
|
||||
bool minimized_ = false;
|
||||
bool first_draw_ = true;
|
||||
bool focused_ = false;
|
||||
bool* p_open_ = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -133,6 +133,12 @@ struct EnhancedTheme {
|
||||
Color editor_grid; // Grid lines in editors
|
||||
Color editor_cursor; // Cursor/selection in editors
|
||||
Color editor_selection; // Selected area in editors
|
||||
|
||||
Color entrance_color;
|
||||
Color hole_color;
|
||||
Color exit_color;
|
||||
Color item_color;
|
||||
Color sprite_color;
|
||||
|
||||
// Style parameters
|
||||
float window_rounding = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user