warfactoryracine/test_imgui_ui.cpp
StillHammer f393b28d73 Migrate core engine interfaces to GroveEngine repository
Removed core engine infrastructure from warfactoryracine:
- Core interfaces: IEngine, IModule, IModuleSystem, IIO, ITaskScheduler, ICoordinationModule
- Configuration system: IDataTree, IDataNode, DataTreeFactory
- UI system: IUI, IUI_Enums, ImGuiUI (header + implementation)
- Resource management: Resource, ResourceRegistry, SerializationRegistry
- Serialization: ASerializable, ISerializable
- World generation: IWorldGenerationStep (replaced by IWorldGenerationPhase)

These components now live in the GroveEngine repository and are included
via CMake add_subdirectory(../GroveEngine) for reusability across projects.

warfactoryracine remains focused on game-specific logic and content.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 00:22:36 +08:00

306 lines
12 KiB
C++

#include <grove/IUI_Enums.h>
#include <grove/ImGuiUI.h>
#include <iostream>
#include <cstdlib>
using namespace grove;
void showUsage(const char* program_name) {
std::cout << "Usage: " << program_name << " [options]\n"
<< "Options:\n"
<< " --headless Run in headless mode (auto-exit after 3s test)\n"
<< " --max-frames N Exit after N frames (overrides interactive mode)\n"
<< " --interactive Run interactively (no auto-exit) [DEFAULT]\n"
<< " --help Show this help message\n"
<< "\nDefault behavior: Interactive mode - close window or press Ctrl+C to exit\n";
}
int main(int argc, char* argv[]) {
// Parse command line arguments
bool headless_mode = false;
bool interactive_mode = true; // DEFAULT: Interactive mode for normal users
int max_frames = -1; // DEFAULT: No time limit
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "--headless") {
headless_mode = true;
interactive_mode = false; // Override default
max_frames = 180; // 3 seconds for quick tests
} else if (arg == "--interactive") {
interactive_mode = true;
headless_mode = false;
max_frames = -1; // No limit
} else if (arg == "--max-frames" && i + 1 < argc) {
max_frames = std::atoi(argv[++i]);
interactive_mode = false; // Override default when explicit limit set
} else if (arg == "--help") {
showUsage(argv[0]);
return 0;
} else {
std::cerr << "Unknown option: " << arg << "\n";
showUsage(argv[0]);
return 1;
}
}
// Show mode info
if (headless_mode) {
std::cout << "[MODE] Headless test mode - will exit after " << max_frames << " frames (3s)\n";
} else if (interactive_mode && max_frames <= 0) {
std::cout << "[MODE] Interactive mode (DEFAULT) - close window or press Ctrl+C to exit\n";
std::cout << "[TIP] Use --headless for quick automated tests\n";
} else {
std::cout << "[MODE] Timed mode - will exit after " << max_frames << " frames\n";
std::cout << "[TIP] Use --interactive for manual testing, --headless for quick tests\n";
}
// Create ImGuiUI instance
ImGuiUI ui;
// Initialize with basic config
ui.initialize({
{"title", "ImGuiUI Test - Hybrid Sizing System"},
{"window_size", {{"width", 1400}, {"height", 900}}}
});
ui.info("Testing ImGuiUI implementation with hybrid sizing system");
// Test 1: Responsive sidebar - 20% but min 250px
ui.createDock("sidebar", DockType::TABBED, DockPosition::LEFT, {
{"size", {{"width", "20%"}, {"height", "90%"}}}, // Target 20% width x 90% height (below toolbar)
{"min_size", {{"width", 250}, {"height", 500}}}, // Minimum 250px x 500px
{"max_size", {{"width", 400}, {"height", "95%"}}}, // Maximum 400px x 95% height
{"resizable", true},
{"collapsible", true}
});
ui.success("Created responsive sidebar: Target 20%, min 250px, max 400px");
// Test 2: Bottom console - 25% height with hybrid constraints
ui.createDock("console", DockType::DOCK, DockPosition::BOTTOM, {
{"size", {{"height", "25%"}}}, // Target 25% = 225px
{"min_size", {{"height", 120}}}, // Minimum 4 lines
{"max_size", {{"height", "35%"}}}, // Max 35% = 315px
{"resizable", true}
});
ui.success("Created bottom console: Target 25%, min 120px, max 35%");
// Test 3: Economy window in sidebar (FULL HEIGHT)
ui.showData(DataType::ECONOMY, {
{"content", {
{"prices", {{"steel_plate", 5.2}, {"iron_ore", 1.1}, {"copper_ore", 0.8}}},
{"trends", {{"steel_plate", "+2.1%"}, {"iron_ore", "-0.5%"}, {"copper_ore", "+1.2%"}}},
{"market_status", "stable"}
}},
{"window", {
{"id", "economy_main"},
{"title", "💰 Economy Dashboard"},
{"parent", "sidebar"},
{"dock", "tab"},
{"size", {{"width", "90%"}, {"height", "100%"}}}, // 90% sidebar width, FULL height
{"min_size", {{"width", 200}, {"height", 400}}}, // Minimum for full sidebar
{"max_size", {{"width", "95%"}, {"height", "100%"}}}// Max 95% sidebar, full height
}}
});
ui.info("Created economy window: 90% of sidebar width x FULL sidebar height");
// Test 3.5: Right sidebar test
ui.createDock("info_panel", DockType::TABBED, DockPosition::RIGHT, {
{"size", {{"width", "25%"}, {"height", "90%"}}}, // Target 25% width x 90% height (below toolbar)
{"min_size", {{"width", 200}, {"height", 500}}}, // Minimum 200px x 500px
{"max_size", {{"width", 500}, {"height", "95%"}}}, // Maximum 500px x 95% height
{"resizable", true},
{"collapsible", true}
});
ui.success("Created right sidebar: Target 25%, min 200px, max 500px");
// Test 3.6: Info panel in right sidebar
ui.showData(DataType::SETTINGS, {
{"content", {
{"performance", {{"fps", 60}, {"memory", "156MB"}}},
{"debug", {{"entities", 2847}, {"chunks_loaded", 12}}}
}},
{"window", {
{"id", "info_panel_main"},
{"title", "📊 Info Panel"},
{"parent", "info_panel"},
{"dock", "tab"},
{"size", {{"width", "95%"}, {"height", "100%"}}}, // 95% right sidebar, full height
{"min_size", {{"width", 180}, {"height", 300}}},
{"max_size", {{"width", "100%"}, {"height", "100%"}}}
}}
});
ui.info("Created info panel: 95% of right sidebar width x FULL height");
// Test 3.7: Top toolbar test
ui.createDock("toolbar", DockType::DOCK, DockPosition::TOP, {
{"size", {{"width", "100%"}, {"height", "8%"}}}, // FULL width x 8% height
{"min_size", {{"width", 800}, {"height", 50}}}, // Minimum 800px x 50px
{"max_size", {{"width", "100%"}, {"height", 120}}}, // FULL width x max 120px
{"resizable", true}
});
ui.success("Created top toolbar: Target 8%, min 50px, max 120px");
// Test 3.8: Toolbar content
ui.showData(DataType::CUSTOM, {
{"content", {
{"buttons", {"New", "Save", "Load", "Export"}},
{"current_tool", "Select"}
}},
{"window", {
{"id", "toolbar_main"},
{"title", "🛠️ Toolbar"},
{"parent", "toolbar"},
{"dock", "tab"},
{"size", {{"width", "100%"}, {"height", "90%"}}}, // Full width, 90% toolbar height
{"min_size", {{"width", 400}, {"height", 40}}},
{"max_size", {{"width", "100%"}, {"height", "95%"}}}
}}
});
ui.info("Created toolbar: 100% width x 90% of toolbar height");
// Test 4: Map window
ui.showData(DataType::MAP, {
{"content", {
{"current_chunk", {{"x", 0}, {"y", 0}}},
{"tiles", {{"iron", 25}, {"copper", 15}, {"coal", 10}}}
}},
{"window", {
{"id", "map_main"},
{"title", "🗺️ Global Map"},
{"size", {{"width", "50%"}, {"height", "60%"}}}, // 50% x 60% of screen
{"min_size", {{"width", 400}, {"height", 300}}}, // Minimum for visibility
{"max_size", {{"width", 800}, {"height", 600}}} // Don't dominate
}}
});
ui.info("Created map window: 50% x 60% of screen with 400x300-800x600 constraints");
// Test 5: Settings dialog - floating with hybrid sizing
ui.showData(DataType::SETTINGS, {
{"content", {
{"graphics", {{"resolution", "1400x900"}, {"fullscreen", false}, {"vsync", true}}},
{"audio", {{"master_volume", 0.8}, {"effects_volume", 0.7}}},
{"controls", {{"mouse_sensitivity", 1.2}}}
}},
{"window", {
{"id", "settings_dialog"},
{"title", "⚙️ Settings"},
{"floating", true},
{"size", {{"width", "30%"}, {"height", "40%"}}}, // 30% x 40% of screen
{"min_size", {{"width", 400}, {"height", 300}}}, // Usable dialog size
{"max_size", {{"width", 600}, {"height", 500}}} // Don't dominate
}}
});
ui.info("Created settings dialog: Floating 30% x 40% with 400x300-600x500 constraints");
// Set up callbacks for testing
ui.onRequest(RequestType::GET_PRICES, [&](const json& req) {
ui.info("📈 Price update requested - would fetch from backend");
// Simulate price update
ui.showData(DataType::ECONOMY, {
{"content", {
{"prices", {{"steel_plate", 5.7}, {"iron_ore", 1.0}, {"copper_ore", 0.9}}},
{"trends", {{"steel_plate", "+9.6%"}, {"iron_ore", "-9.1%"}, {"copper_ore", "+12.5%"}}},
{"market_status", "volatile"}
}},
{"window", {
{"id", "economy_main"}
}}
});
});
ui.onRequest(RequestType::GET_CHUNK, [&](const json& req) {
ui.info("🗺️ Map chunk requested: " + req.dump());
// Simulate chunk update
ui.showData(DataType::MAP, {
{"content", {
{"current_chunk", {{"x", 1}, {"y", 0}}},
{"tiles", {{"iron", 30}, {"copper", 8}, {"stone", 12}}}
}},
{"window", {
{"id", "map_main"}
}}
});
});
ui.onRequestCustom("console_command", [&](const json& req) {
std::string command = req.value("command", "");
ui.info("💻 Console command: " + command);
if (command == "test_resize") {
ui.info("🔄 Testing window resize behavior...");
// All percentage-based sizes would recalculate automatically
} else if (command == "show_performance") {
ui.showData(DataType::PERFORMANCE, {
{"content", {
{"fps", 60},
{"frame_time", "16.7ms"},
{"memory_usage", "156MB"},
{"entities", 2847}
}},
{"window", {
{"id", "performance_monitor"},
{"title", "📊 Performance Monitor"},
{"size", {{"width", 300}, {"height", "25%"}}}, // 300px x 25% height
{"min_size", {{"width", 250}, {"height", 200}}},
{"floating", true}
}}
});
}
});
ui.success("All callbacks configured - UI ready for testing!");
ui.info("Commands: 'test_resize', 'show_performance'");
ui.info("Try resizing the window to see responsive percentage behavior");
// Main loop with configurable timeout
int frame = 0;
bool should_exit = false;
while (ui.update() && !should_exit) {
frame++;
// Test automatic percentage recalculation
if (frame == 60) { // 1s at 60fps
ui.debug("🔄 Simulating window resize - percentages recalculate automatically");
}
if (frame % 60 == 0) { // Every second
ui.info("Frame " + std::to_string(frame) + " - Docking system operational");
}
// Headless mode: quick test and exit
if (headless_mode && frame == 120) { // 2s at 60fps
ui.success("✅ Headless docking test completed successfully!");
should_exit = true;
}
// Standard/Interactive mode: check frame limit
if (max_frames > 0 && frame >= max_frames) {
ui.info("🕐 Auto-exit after " + std::to_string(max_frames) + " frames");
should_exit = true;
}
// Interactive mode message
if (interactive_mode && frame == 180) { // Show tip after 3 seconds
ui.info("💡 Interactive mode: Close window or press Ctrl+C to exit");
}
}
ui.info("Exited at frame " + std::to_string(frame));
ui.info("Shutting down ImGuiUI test");
ui.shutdown();
return 0;
}