12#include "ncengine/type/EngineTypes.h"
28#define IMGUI_SCOPE_UNIQUE_NAME_HELPER(name, lineNumber) name ## lineNumber
29#define IMGUI_SCOPE_UNIQUE_NAME(name, lineNumber) IMGUI_SCOPE_UNIQUE_NAME_HELPER(name, lineNumber)
33#define IMGUI_SCOPE(Property, ...) auto IMGUI_SCOPE_UNIQUE_NAME(imguiProp, __LINE__) = Property(__VA_ARGS__)
37constexpr auto g_defaultItemWidth = 50.0f;
38constexpr auto g_maxPos = 5000.0f;
39constexpr auto g_minPos = -g_maxPos;
40constexpr auto g_maxAngle = std::numbers::pi_v<float> * 2.0f;
41constexpr auto g_minAngle = -g_maxAngle;
42constexpr auto g_minScale = 0.1f;
43constexpr auto g_maxScale = 1000.0f;
47void Window(
const char* label, F&& drawContents);
51void Window(
const char* label, ImGuiWindowFlags flags, F&& drawContents);
55void ChildWindow(
const char* label, F&& drawContents);
59void ChildWindow(
const char* label, ImGuiChildFlags flags, F&& drawContents);
62auto IsWindowBackgroundClicked() -> bool;
65auto InputInt(
int& value,
const char* label,
int step = 1) -> bool;
68auto InputU8(uint8_t& value,
const char* label) -> bool;
71auto InputU16(uint16_t& value,
const char* label) -> bool;
74auto InputU32(uint32_t& value,
const char* label) -> bool;
77auto InputU64(uint64_t& value,
const char* label) -> bool;
80auto DragFloat(
float& value,
const char* label,
float speed = 1.0f,
float min = 0.0f,
float max = 1000.0f) -> bool;
83auto Checkbox(
bool& value,
const char* name) -> bool;
86auto InputVector3(
Vector3& value,
const char* label,
float speed = 1.0f,
float min = 0.0f,
float max = 100.0f) -> bool;
95auto InputScale(
Vector3& value,
const char* label,
float min = g_minScale,
float max = g_maxScale) -> bool;
98auto InputAxis(
Vector3& value,
const char* label,
float min = -1.0f,
float max = 1.0f) -> bool;
113auto Combobox(std::string& value,
const char* label, std::span<const std::string_view> items);
116auto FilteredCombobox(std::string& value,
const char* label, std::span<const std::string_view> items,
auto&& disableIf);
119auto InputText(std::string& value,
const char* label) -> bool;
122auto SelectableWidget(
bool selected,
const ImVec2& size,
auto&& widget) -> bool;
132template<
class Getter,
class Setter>
137 const char* name =
"";
153auto PropertyWidget(
const auto& property,
auto& instance,
auto&& widget,
auto&&... args) -> bool;
160template<
class T, std::invocable<T*> F>
175 explicit ImGuiId(
const char*
id) { ImGui::PushID(
id); }
176 explicit ImGuiId(
int id) { ImGui::PushID(
id); }
177 ~ImGuiId()
noexcept { ImGui::PopID(); }
183 explicit Indent() { ImGui::Indent(); }
184 ~Indent()
noexcept { ImGui::Unindent(); }
190 explicit StyleColor(ImGuiCol index, ImU32 col) { ImGui::PushStyleColor(index, col); }
191 explicit StyleColor(ImGuiCol index,
const ImVec4& col) { ImGui::PushStyleColor(index, col); }
192 explicit StyleColor(ImGuiCol index,
const Vector4& col) { ImGui::PushStyleColor(index, col); }
199 explicit StyleVar(ImGuiStyleVar index,
const ImVec2& value) { ImGui::PushStyleVar(index, value); }
200 ~StyleVar()
noexcept { ImGui::PopStyleVar(); }
206 explicit StyleFont(ImFont* font) { ImGui::PushFont(font); }
213 explicit ItemWidth(
float itemWidth) { ImGui::PushItemWidth(itemWidth); }
214 ~ItemWidth()
noexcept { ImGui::PopItemWidth(); }
220 explicit DisableIf(
bool condition) { ImGui::BeginDisabled(condition); }
221 ~DisableIf()
noexcept { ImGui::EndDisabled(); }
228 return ImGui::GetIO().WantCaptureKeyboard;
235 return ImGui::GetIO().WantCaptureMouse;
239void Window(
const char* label, ImGuiWindowFlags flags, F&& drawContents)
241 if (ImGui::Begin(label,
nullptr, flags))
250void Window(
const char* label, F&& drawContents)
252 Window(label, ImGuiWindowFlags_None, std::forward<F>(drawContents));
256void ChildWindow(
const char* label, ImGuiChildFlags flags, F&& drawContents)
258 if (ImGui::BeginChild(label, {0, 0}, flags))
269 if (ImGui::BeginChild(label, {0, 0},
true))
279 return ImGui::IsWindowHovered() && ImGui::IsMouseClicked(0) && !ImGui::IsAnyItemHovered();
291 const auto availableWidth = ImGui::GetContentRegionAvail().x;
292 itemWidth += + ImGui::GetStyle().FramePadding.x * 2.0f;
293 ImGui::SameLine(ImGui::GetCursorPosX() + availableWidth - itemWidth);
303inline auto InputInt(
int& value,
const char* label,
int step) ->
bool
305 return ImGui::InputInt(label, &value, step);
308inline auto InputU8(uint8_t& value,
const char* label) ->
bool
310 constexpr uint8_t step = 1;
311 return ImGui::InputScalar(label, ImGuiDataType_U8, &value, &step);
314inline auto InputU16(uint16_t& value,
const char* label) ->
bool
316 constexpr uint16_t step = 1;
317 return ImGui::InputScalar(label, ImGuiDataType_U16, &value, &step);
320inline auto InputU32(
unsigned& value,
const char* label) ->
bool
322 constexpr uint32_t step = 1;
323 return ImGui::InputScalar(label, ImGuiDataType_U32, &value, &step);
326inline auto InputU64(uint64_t& value,
const char* label) ->
bool
328 constexpr uint64_t step = 1;
329 return ImGui::InputScalar(label, ImGuiDataType_U64, &value, &step);
332inline auto DragFloat(
float& value,
const char* label,
float speed,
float min,
float max) ->
bool
334 return ImGui::DragFloat(label, &value, speed, min, max,
"%.3f", ImGuiSliderFlags_AlwaysClamp);
337inline auto Checkbox(
bool& value,
const char* name) ->
bool
339 return ImGui::Checkbox(name, &value);
344 return ImGui::DragFloat3(label, &value.x, speed, min, max,
"%.3f", ImGuiSliderFlags_AlwaysClamp);
349 return ImGui::DragFloat3(label, &value.x, 1.0f, g_minPos, g_maxPos,
"%.3f", ImGuiSliderFlags_AlwaysClamp);
354 return ImGui::DragFloat3(label, &value.x, 0.1f, g_minAngle, g_maxAngle,
"%.3f", ImGuiSliderFlags_AlwaysClamp);
359 return ImGui::DragFloat3(label, &value.x, 0.5f, min, max,
"%.3f", ImGuiSliderFlags_AlwaysClamp);
364 const auto previous = value;
365 if (ImGui::DragFloat3(label, &value.x, 0.1f, min, max,
"%.3f", ImGuiSliderFlags_AlwaysClamp))
369 if (value.x != previous.x && std::fabs(value.x) == 1.0f)
370 value =
Vector3{value.x, 0.0f, 0.0f};
371 else if (value.y != previous.y && std::fabs(value.y) == 1.0f)
372 value =
Vector3{0.0f, value.y, 0.0f};
373 else if (value.z != previous.z && std::fabs(value.z) == 1.0f)
374 value =
Vector3{0.0f, 0.0f, value.z};
375 else if (value == Vector3::Zero())
388 auto modified =
false;
391 normal = ClosestOrthogonal(normal, basis);
397 basis = ClosestOrthogonal(basis, normal);
404inline auto InputColor(
Vector3& value,
const char* label) ->
bool
406 return ImGui::ColorEdit3(label, &value.x, ImGuiColorEditFlags_NoInputs);
411 return ImGui::ColorEdit3(label, &value.x, ImGuiColorEditFlags_NoInputs);
416 return ImGui::ColorEdit4(label, &value.x, ImGuiColorEditFlags_NoInputs);
422 const auto startColor = ImGui::ColorConvertFloat4ToU32(ImVec4{value.start});
423 const auto endColor = ImGui::ColorConvertFloat4ToU32(ImVec4{value.end});
424 const auto canvasPos = ImGui::GetCursorScreenPos();
425 const auto canvasSize = ImVec2{ImGui::CalcItemWidth(), ImGui::GetTextLineHeight()};
426 auto* drawList = ImGui::GetWindowDrawList();
427 drawList->AddRectFilledMultiColor(canvasPos, canvasPos + canvasSize, startColor, endColor, endColor, startColor);
428 ImGui::InvisibleButton(
"gradientbar", canvasSize);
430 if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0))
432 const auto mouseX = ImGui::GetIO().MousePos.x;
433 if (mouseX < canvasPos.x + canvasSize.x * 0.5f)
434 ImGui::OpenPopup(
"StartPicker");
436 ImGui::OpenPopup(
"EndPicker");
439 auto changed =
false;
440 if (ImGui::BeginPopup(
"StartPicker"))
442 changed |= ImGui::ColorPicker4(
"Start Color", &value.start.x);
446 if (ImGui::BeginPopup(
"EndPicker"))
448 changed |= ImGui::ColorPicker4(
"End Color", &value.end.x);
453 ImGui::TextUnformatted(label);
454 ImGui::Dummy(ImVec2{0.0f, 5.0f});
458inline auto Combobox(std::string& value,
const char* label, std::span<const std::string_view> items)
460 if (ImGui::BeginCombo(label, value.c_str()))
462 const auto selected = std::ranges::find_if(items, [](
const auto& text)
464 return ImGui::Selectable(text.data());
469 if (selected != std::cend(items))
471 value = selected->data();
479inline auto FilteredCombobox(std::string& value,
const char* label, std::span<const std::string_view> items,
auto&& disableIf)
481 if (ImGui::BeginCombo(label, value.c_str()))
483 const auto selected = std::ranges::find_if(items, [&disableIf](
const auto& text)
486 return ImGui::Selectable(text.data());
491 if (selected != std::cend(items))
493 value = selected->data();
508inline auto InputTextCallback(ImGuiInputTextCallbackData* data) ->
int
510 if(data->EventFlag == ImGuiInputTextFlags_CallbackResize)
513 auto* str = userData->string;
514 str->resize(data->BufTextLen);
515 data->Buf = (
char*)str->c_str();
522inline auto InputText(std::string& text,
const char* label) ->
bool
524 auto flags = ImGuiInputTextFlags_CallbackResize | ImGuiInputTextFlags_EnterReturnsTrue;
526 return ImGui::InputText(label, text.data(), text.capacity() + 1, flags, internal::InputTextCallback, &userData);
531 static constexpr auto flags = ImGuiSelectableFlags_AllowDoubleClick |
532 ImGuiSelectableFlags_AllowItemOverlap;
533 auto clicked =
false;
534 if (ImGui::Selectable(
"##select", selected, flags, size))
539 if (ImGui::IsItemClicked(0))
542 ImGui::SetKeyboardFocusHere(-1);
548auto PropertyWidget(
const auto& property,
auto& instance,
auto&& widget,
auto&&... args) ->
bool
550 auto value = std::invoke(property.get, instance);
551 if (widget(value, property.name, std::forward<
decltype(args)>(args)...))
553 std::invoke(property.set, instance, value);
563 if(ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
567 ImGui::EndDragDropSource();
571template<
class T, std::invocable<T*> F>
574 if(ImGui::BeginDragDropTarget())
578 func(
static_cast<std::add_pointer_t<T>
>(payload->Data));
581 ImGui::EndDragDropTarget();
587 if (ImGui::IsItemHovered())
589 ImGui::SetTooltip(
"%s", text);
void SameLineRightAligned(float itemWidth)
UI layout helper for right aligning an item on the same line as the previous item.
Definition: ImGuiUtility.h:289
auto IsCapturingMouse() -> bool
Check if the UI is currently using mouse events.
Definition: ImGuiUtility.h:233
auto InputU32(uint32_t &value, const char *label) -> bool
Input field UI widget for uint32_t.
auto InputColor4(Vector4 &value, const char *label) -> bool
RGBA color picker UI widget.
Definition: ImGuiUtility.h:414
void SameLineSpaced()
UI layout helper for spacing.
Definition: ImGuiUtility.h:282
auto PropertyWidget(const auto &property, auto &instance, auto &&widget, auto &&... args) -> bool
Invoke a widget function with a Property and object instance.
Definition: ImGuiUtility.h:548
auto InputReferenceFrame(Vector3 &basis, Vector3 &normal, const char *basisLabel, const char *normalLabel) -> bool
Vector3 UI widget constrained for two orthonormal axis inputs.
Definition: ImGuiUtility.h:386
auto FilteredCombobox(std::string &value, const char *label, std::span< const std::string_view > items, auto &&disableIf)
Combobox UI widget that allows disabling selection of entries.
Definition: ImGuiUtility.h:479
void DragAndDropTarget(F &&func)
Introduce a drag and drop target that can accept a payload of type T*.
Definition: ImGuiUtility.h:572
auto InputPosition(Vector3 &value, const char *label) -> bool
Vector3 UI widget constrained for position inputs.
Definition: ImGuiUtility.h:347
auto Combobox(std::string &value, const char *label, std::span< const std::string_view > items)
Combobox UI widget.
Definition: ImGuiUtility.h:458
void ChildWindow(const char *label, F &&drawContents)
Create a child window.
Definition: ImGuiUtility.h:267
void Window(const char *label, F &&drawContents)
Create a top-level window.
Definition: ImGuiUtility.h:250
auto InputText(std::string &value, const char *label) -> bool
Text input UI widget.
Definition: ImGuiUtility.h:522
auto InputScale(Vector3 &value, const char *label, float min=g_minScale, float max=g_maxScale) -> bool
Vector3 UI widget constrained for scale inputs.
Definition: ImGuiUtility.h:357
auto InputU16(uint16_t &value, const char *label) -> bool
Input field UI widget for uint16_t.
Definition: ImGuiUtility.h:314
auto InputU64(uint64_t &value, const char *label) -> bool
Input field UI widget for uint64_t.
Definition: ImGuiUtility.h:326
void SeparatorSpaced()
UI layout helper for separator.
Definition: ImGuiUtility.h:296
void DragAndDropSource(T *item)
Introduce a drag and drop source with item as its payload.
Definition: ImGuiUtility.h:561
auto IsWindowBackgroundClicked() -> bool
Check if the current window background is clicked on.
Definition: ImGuiUtility.h:277
auto DragFloat(float &value, const char *label, float speed=1.0f, float min=0.0f, float max=1000.0f) -> bool
Drag slider UI widget for float.
Definition: ImGuiUtility.h:332
void SetTooltip(const char *text)
Set tooltip text if the last item is hovered.
Definition: ImGuiUtility.h:585
auto InputGradient(Gradient &value, const char *lable) -> bool
RGBA color pickers over a two color gradient.
Definition: ImGuiUtility.h:419
auto SelectableWidget(bool selected, const ImVec2 &size, auto &&widget) -> bool
Wrap a widget with a selectable - allows for things like list box of input widgets.
Definition: ImGuiUtility.h:529
auto InputInt(int &value, const char *label, int step=1) -> bool
Input field UI widget for int.
Definition: ImGuiUtility.h:303
#define IMGUI_SCOPE(Property,...)
Create a variable to hold a scoped property.
Definition: ImGuiUtility.h:33
auto IsCapturingKeyboard() -> bool
Check if the UI is currently using keyboard events.
Definition: ImGuiUtility.h:226
auto InputU8(uint8_t &value, const char *label) -> bool
Input field UI widget for uint8_t.
Definition: ImGuiUtility.h:308
auto InputAngles(Vector3 &value, const char *label) -> bool
Vector3 UI widget constrained for angular (radians) inputs.
Definition: ImGuiUtility.h:352
auto InputAxis(Vector3 &value, const char *label, float min=-1.0f, float max=1.0f) -> bool
Vector3 UI widget constrained for normalized axis inputs.
Definition: ImGuiUtility.h:362
auto InputColor3(Vector3 &value, const char *label) -> bool
RGB color picker UI widget.
Definition: ImGuiUtility.h:409
auto Checkbox(bool &value, const char *name) -> bool
Checkbox UI widget for bool.
Definition: ImGuiUtility.h:337
auto InputVector3(Vector3 &value, const char *label, float speed=1.0f, float min=0.0f, float max=100.0f) -> bool
Vector3 UI widget with three float drag sliders.
Definition: ImGuiUtility.h:342
auto Normalize(const Quaternion &quat) -> Quaternion
Return a normalized quaternion.
Gradient between two Colors.
Definition: Color.h:45
A three component vector.
Definition: Vector.h:29
A four component vector.
Definition: Vector.h:48
RAII wrapper for conditionally disabling widgets within a scope.
Definition: ImGuiUtility.h:219
RAII wrapper for scoped uids.
Definition: ImGuiUtility.h:174
RAII wrapper for scoped indentation.
Definition: ImGuiUtility.h:182
RAII wrapper for scoped item width.
Definition: ImGuiUtility.h:212
Simple getter/setter-based property wrapper.
Definition: ImGuiUtility.h:134
RAII wrapper for scoped style color.
Definition: ImGuiUtility.h:189
RAII wrapper for ui font.
Definition: ImGuiUtility.h:205
RAII wrapper for scoped style var.
Definition: ImGuiUtility.h:198
Definition: ImGuiUtility.h:504