Files
yaze/src/app/gui/automation/widget_auto_register.h
scawful 58f3213c62 refactor(gui): reorganize GUI includes and introduce new components
- Updated include paths for various GUI-related headers to improve organization and clarity.
- Introduced new components for better modularity, including PaletteEditorWidget and EditorCardManager.
- Refactored existing code to utilize the new components, ensuring consistency across the GUI subsystem.

Benefits:
- Enhances maintainability and readability of the GUI code.
- Facilitates future enhancements and optimizations within the GUI subsystem.
2025-10-13 10:21:03 -04:00

265 lines
9.1 KiB
C++

#ifndef YAZE_APP_GUI_AUTOMATION_WIDGET_AUTO_REGISTER_H_
#define YAZE_APP_GUI_AUTOMATION_WIDGET_AUTO_REGISTER_H_
#include <string>
#include "imgui/imgui.h"
#include "app/gui/automation/widget_id_registry.h"
#include "absl/strings/str_cat.h"
/**
* @file widget_auto_register.h
* @brief Automatic widget registration helpers for ImGui Test Engine integration
*
* This file provides inline wrappers and RAII helpers that automatically
* register ImGui widgets with the WidgetIdRegistry for test automation.
*
* Usage:
* {
* gui::AutoWidgetScope scope("Dungeon/Canvas");
* if (gui::AutoButton("Save##DungeonSave")) {
* // Button clicked
* }
* gui::AutoInputText("RoomName", buffer, sizeof(buffer));
* }
*
* All widgets created within this scope will be automatically registered
* with their full hierarchical paths for test harness discovery.
*/
namespace yaze {
namespace gui {
/**
* @class AutoWidgetScope
* @brief RAII scope that enables automatic widget registration
*
* Creates a widget ID scope and enables auto-registration for all widgets
* created within this scope. Combines WidgetIdScope with automatic metadata
* capture.
*/
class AutoWidgetScope {
public:
explicit AutoWidgetScope(const std::string& name);
~AutoWidgetScope();
// Get current scope path
std::string GetPath() const { return scope_.GetFullPath(); }
private:
WidgetIdScope scope_;
std::string name_;
};
/**
* @brief Automatically register the last ImGui item
*
* Call this after any ImGui widget creation to automatically register it.
* Captures widget type, bounds, visibility, and enabled state.
*
* @param widget_type Type of widget ("button", "input", "checkbox", etc.)
* @param explicit_label Optional explicit label (uses ImGui::GetItemLabel() if empty)
* @param description Optional description for the test harness
*/
void AutoRegisterLastItem(const std::string& widget_type,
const std::string& explicit_label = "",
const std::string& description = "");
// ============================================================================
// Automatic Registration Wrappers for Common ImGui Widgets
// ============================================================================
// These wrappers call the standard ImGui functions and automatically register
// the widget with the WidgetIdRegistry for test automation.
//
// They preserve the exact same API and return values as ImGui, so they can be
// drop-in replacements in existing code.
inline bool AutoButton(const char* label, const ImVec2& size = ImVec2(0, 0)) {
bool clicked = ImGui::Button(label, size);
AutoRegisterLastItem("button", label);
return clicked;
}
inline bool AutoSmallButton(const char* label) {
bool clicked = ImGui::SmallButton(label);
AutoRegisterLastItem("button", label, "Small button");
return clicked;
}
inline bool AutoCheckbox(const char* label, bool* v) {
bool changed = ImGui::Checkbox(label, v);
AutoRegisterLastItem("checkbox", label);
return changed;
}
inline bool AutoRadioButton(const char* label, bool active) {
bool clicked = ImGui::RadioButton(label, active);
AutoRegisterLastItem("radio", label);
return clicked;
}
inline bool AutoRadioButton(const char* label, int* v, int v_button) {
bool clicked = ImGui::RadioButton(label, v, v_button);
AutoRegisterLastItem("radio", label);
return clicked;
}
inline bool AutoInputText(const char* label, char* buf, size_t buf_size,
ImGuiInputTextFlags flags = 0,
ImGuiInputTextCallback callback = nullptr,
void* user_data = nullptr) {
bool changed = ImGui::InputText(label, buf, buf_size, flags, callback, user_data);
AutoRegisterLastItem("input", label);
return changed;
}
inline bool AutoInputTextMultiline(const char* label, char* buf, size_t buf_size,
const ImVec2& size = ImVec2(0, 0),
ImGuiInputTextFlags flags = 0,
ImGuiInputTextCallback callback = nullptr,
void* user_data = nullptr) {
bool changed = ImGui::InputTextMultiline(label, buf, buf_size, size, flags, callback, user_data);
AutoRegisterLastItem("textarea", label);
return changed;
}
inline bool AutoInputInt(const char* label, int* v, int step = 1, int step_fast = 100,
ImGuiInputTextFlags flags = 0) {
bool changed = ImGui::InputInt(label, v, step, step_fast, flags);
AutoRegisterLastItem("input_int", label);
return changed;
}
inline bool AutoInputFloat(const char* label, float* v, float step = 0.0f,
float step_fast = 0.0f, const char* format = "%.3f",
ImGuiInputTextFlags flags = 0) {
bool changed = ImGui::InputFloat(label, v, step, step_fast, format, flags);
AutoRegisterLastItem("input_float", label);
return changed;
}
inline bool AutoSliderInt(const char* label, int* v, int v_min, int v_max,
const char* format = "%d", ImGuiSliderFlags flags = 0) {
bool changed = ImGui::SliderInt(label, v, v_min, v_max, format, flags);
AutoRegisterLastItem("slider", label);
return changed;
}
inline bool AutoSliderFloat(const char* label, float* v, float v_min, float v_max,
const char* format = "%.3f", ImGuiSliderFlags flags = 0) {
bool changed = ImGui::SliderFloat(label, v, v_min, v_max, format, flags);
AutoRegisterLastItem("slider", label);
return changed;
}
inline bool AutoCombo(const char* label, int* current_item, const char* const items[],
int items_count, int popup_max_height_in_items = -1) {
bool changed = ImGui::Combo(label, current_item, items, items_count, popup_max_height_in_items);
AutoRegisterLastItem("combo", label);
return changed;
}
inline bool AutoSelectable(const char* label, bool selected = false,
ImGuiSelectableFlags flags = 0,
const ImVec2& size = ImVec2(0, 0)) {
bool clicked = ImGui::Selectable(label, selected, flags, size);
AutoRegisterLastItem("selectable", label);
return clicked;
}
inline bool AutoSelectable(const char* label, bool* p_selected,
ImGuiSelectableFlags flags = 0,
const ImVec2& size = ImVec2(0, 0)) {
bool clicked = ImGui::Selectable(label, p_selected, flags, size);
AutoRegisterLastItem("selectable", label);
return clicked;
}
inline bool AutoMenuItem(const char* label, const char* shortcut = nullptr,
bool selected = false, bool enabled = true) {
bool activated = ImGui::MenuItem(label, shortcut, selected, enabled);
AutoRegisterLastItem("menuitem", label);
return activated;
}
inline bool AutoMenuItem(const char* label, const char* shortcut, bool* p_selected,
bool enabled = true) {
bool activated = ImGui::MenuItem(label, shortcut, p_selected, enabled);
AutoRegisterLastItem("menuitem", label);
return activated;
}
inline bool AutoBeginMenu(const char* label, bool enabled = true) {
bool opened = ImGui::BeginMenu(label, enabled);
if (opened) {
AutoRegisterLastItem("menu", label, "Submenu");
}
return opened;
}
inline bool AutoBeginTabItem(const char* label, bool* p_open = nullptr,
ImGuiTabItemFlags flags = 0) {
bool selected = ImGui::BeginTabItem(label, p_open, flags);
if (selected) {
AutoRegisterLastItem("tab", label);
}
return selected;
}
inline bool AutoTreeNode(const char* label) {
bool opened = ImGui::TreeNode(label);
if (opened) {
AutoRegisterLastItem("treenode", label);
}
return opened;
}
inline bool AutoTreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0) {
bool opened = ImGui::TreeNodeEx(label, flags);
if (opened) {
AutoRegisterLastItem("treenode", label);
}
return opened;
}
inline bool AutoCollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0) {
bool opened = ImGui::CollapsingHeader(label, flags);
if (opened) {
AutoRegisterLastItem("collapsing", label);
}
return opened;
}
// ============================================================================
// Canvas-specific registration helpers
// ============================================================================
/**
* @brief Register a canvas widget after BeginChild or similar
*
* Canvases typically use BeginChild which doesn't have a return value,
* so we provide a separate registration helper.
*
* @param canvas_name Name of the canvas (should match BeginChild name)
* @param description Optional description of the canvas purpose
*/
inline void RegisterCanvas(const char* canvas_name, const std::string& description = "") {
AutoRegisterLastItem("canvas", canvas_name, description);
}
/**
* @brief Register a table after BeginTable
*
* @param table_name Name of the table (should match BeginTable name)
* @param description Optional description
*/
inline void RegisterTable(const char* table_name, const std::string& description = "") {
AutoRegisterLastItem("table", table_name, description);
}
} // namespace gui
} // namespace yaze
#endif // YAZE_APP_GUI_AUTOMATION_WIDGET_AUTO_REGISTER_H_