Skip to content

Instantly share code, notes, and snippets.

@JSandusky
Last active November 19, 2019 19:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JSandusky/54b85068aa30390c91a0b377703f042e to your computer and use it in GitHub Desktop.
Save JSandusky/54b85068aa30390c91a0b377703f042e to your computer and use it in GitHub Desktop.
Urho3D DearImGui
#include "../Precompiled.h"
#include "../AngelScript/Addons.h"
#include "../AngelScript/Script.h"
#include "../Math/Color.h"
#include "../Math/Vector2.h"
#include "../Math/Vector3.h"
#include "../Math/Vector4.h"
#include <AngelScript\angelscript.h>
#include <ImGui\imgui.h>
namespace Urho3D
{
void RegisterImGuiBindings(asIScriptEngine* engine)
{
engine->SetDefaultNamespace("ImGui");
engine->RegisterGlobalFunction("bool Begin(const String&in, bool, int=0)", asFUNCTIONPR([](const String& name, bool opened, int flags) { return ImGui::Begin(name.CString(), &opened, flags); }, (const String&, bool, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void End()", asFUNCTIONPR(ImGui::End, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginChild(const String&in)", asFUNCTIONPR([](const String& name) {
return ImGui::Begin(name.CString()); }, (const String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndChild()", asFUNCTIONPR(ImGui::EndChild, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetContentRegionMax()", asFUNCTIONPR([]() {
auto v = ImGui::GetContentRegionMax(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetContentRegionAvail()", asFUNCTIONPR([]() {
auto v = ImGui::GetContentRegionAvail(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetContentRegionAvailWidth()", asFUNCTIONPR(ImGui::GetContentRegionAvailWidth, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetWindowContentRegionMin()", asFUNCTIONPR([]() {
auto v = ImGui::GetWindowContentRegionMin(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetWindowContentRegionMax()", asFUNCTIONPR([]() {
auto v = ImGui::GetWindowContentRegionMax(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetWindowRegionWidth()", asFUNCTIONPR(ImGui::GetWindowContentRegionWidth, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetWindowPos()", asFUNCTIONPR([]() {
auto v = ImGui::GetWindowPos(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetWindowSize()", asFUNCTIONPR([]() {
auto v = ImGui::GetWindowSize(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetWindowWedth()", asFUNCTIONPR(ImGui::GetWindowWidth, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetWindowHeight()", asFUNCTIONPR(ImGui::GetWindowHeight, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsWindowCollapsed()", asFUNCTIONPR(ImGui::IsWindowCollapsed, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsWindowAppearing()", asFUNCTIONPR(ImGui::IsWindowAppearing, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowFontScale(float)", asFUNCTIONPR(ImGui::SetWindowFontScale, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetNextWindowPos(Vector2)", asFUNCTIONPR([](Vector2 v) {
ImGui::SetNextWindowPos(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetNextWindowSize(Vector2)", asFUNCTIONPR([](Vector2 v) {
ImGui::SetNextWindowSize(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetNextWindowContentSize(Vector2)", asFUNCTIONPR([](Vector2 v) {
ImGui::SetNextWindowContentSize(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetNextWindowCollapsed(bool)", asFUNCTIONPR([](bool v) {
ImGui::SetNextWindowCollapsed(v); }, (bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetNextWindowFocus()", asFUNCTIONPR([]() {
ImGui::SetNextWindowFocus(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowPos(Vector2)", asFUNCTIONPR([](Vector2 v) {
ImGui::SetWindowPos(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowSize(Vector2)", asFUNCTIONPR([](Vector2 v) {
ImGui::SetWindowSize(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowCollapsed(bool)", asFUNCTIONPR([](bool v) {
ImGui::SetWindowCollapsed(v); }, (bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowFocus()", asFUNCTIONPR([]() { ImGui::SetWindowFocus(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowPos(const String&in, Vector2)", asFUNCTIONPR([](const String& name, Vector2 v) {
ImGui::SetWindowPos(name.CString(), ImVec2(v.x_, v.y_)); }, (const String&, Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowSize(const String&in, Vector2)", asFUNCTIONPR([](const String& name, Vector2 v) {
ImGui::SetWindowSize(name.CString(), ImVec2(v.x_, v.y_)); }, (const String&, Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowCollapsed(const String&in, bool)", asFUNCTIONPR([](const String& name, bool v) {
ImGui::SetWindowCollapsed(name.CString(), v); }, (const String&, bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetWindowFocus(const String&in)", asFUNCTIONPR([](const String& v) {
ImGui::SetWindowFocus(v.CString()); }, (const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetScrollX()", asFUNCTIONPR(ImGui::GetScrollX, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetScrollY()", asFUNCTIONPR(ImGui::GetScrollY, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetScrollMaxX()", asFUNCTIONPR(ImGui::GetScrollMaxX, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetScrollMaxY()", asFUNCTIONPR(ImGui::GetScrollMaxY, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetScrollX(float)", asFUNCTIONPR(ImGui::SetScrollX, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetScrollY(float)", asFUNCTIONPR(ImGui::SetScrollY, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetScrollHere(float = 0.5f)", asFUNCTIONPR(ImGui::SetScrollHere, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetScrollFromPosY(float, float = 0.5f)", asFUNCTIONPR(ImGui::SetScrollFromPosY, (float,float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Separator()", asFUNCTIONPR(ImGui::Separator, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SameLine(float = 0.0f, float = -1.0f)", asFUNCTIONPR(ImGui::SameLine, (float,float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void NewLine()", asFUNCTIONPR(ImGui::NewLine, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Spacing()", asFUNCTIONPR(ImGui::Spacing, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Dummy(Vector2)", asFUNCTIONPR([](Vector2 v) { ImGui::Dummy(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Indent(float = 0.0f)", asFUNCTIONPR(ImGui::Indent, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Unindent(float = 0.0f)", asFUNCTIONPR(ImGui::Unindent, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void BeginGroup()", asFUNCTIONPR(ImGui::BeginGroup, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndGroup()", asFUNCTIONPR(ImGui::EndGroup, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetCursorPos()", asFUNCTIONPR([]() { auto v = ImGui::GetCursorPos(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetCursorPosX()", asFUNCTIONPR(ImGui::GetCursorPosX, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetCursorPosY()", asFUNCTIONPR(ImGui::GetCursorPosY, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetCursorPos(Vector2)", asFUNCTIONPR([](Vector2 v) { ImGui::SetCursorPos(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetCursorPosX(float)", asFUNCTIONPR(ImGui::SetCursorPosX, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetCursorPosY(float)", asFUNCTIONPR(ImGui::SetCursorPosY, (float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetCursorStartPos()", asFUNCTIONPR([]() { auto v = ImGui::GetCursorStartPos(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetCursorScreenPos()", asFUNCTIONPR([]() { auto v = ImGui::GetCursorScreenPos(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetCursorScreenPos(Vector2)", asFUNCTIONPR([](Vector2 v) { ImGui::SetCursorScreenPos(ImVec2(v.x_, v.y_)); }, (Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void AlignTextToFramePadding()", asFUNCTIONPR(ImGui::AlignTextToFramePadding, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetTextLineHeight()", asFUNCTIONPR(ImGui::GetTextLineHeight, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetTextLineHeightWithSpacing()", asFUNCTIONPR(ImGui::GetTextLineHeightWithSpacing, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetFrameHeight()", asFUNCTIONPR(ImGui::GetFrameHeight, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetFrameHeightWithSpacing()", asFUNCTIONPR(ImGui::GetFrameHeightWithSpacing, (), float), asCALL_CDECL);
// Columns
engine->RegisterGlobalFunction("void Columns(int = 1, const String&in = String(), bool = true)", asFUNCTIONPR([](int a, const String& b, bool c) {
ImGui::Columns(a, b.Empty() ? b.CString() : 0x0, c); }, (int, const String&, bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void NextColumn()", asFUNCTIONPR([]() { ImGui::NextColumn(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("int GetColumnIndex()", asFUNCTIONPR([]() { return ImGui::GetColumnIndex(); }, (), int), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetColumnWidth(int = -1)", asFUNCTIONPR([](int a) { return ImGui::GetColumnWidth(a); }, (int), float), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetColumnWidth(int, float)", asFUNCTIONPR([](int a, float b) { ImGui::SetColumnWidth(a, b); }, (int,float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetColumnOffset(int = -1)", asFUNCTIONPR([](int a) { return ImGui::GetColumnOffset(a); }, (int), float), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetColumnOffset(int, float)", asFUNCTIONPR([](int a, float b) { ImGui::SetColumnOffset(a, b); }, (int,float), void), asCALL_CDECL);
engine->RegisterGlobalFunction("int GetColumnsCount()", asFUNCTIONPR([]() { return ImGui::GetColumnsCount(); }, (), int), asCALL_CDECL);
// ID scopes
engine->RegisterGlobalFunction("void PushID(const String&in)", asFUNCTIONPR([](const String& n) { ImGui::PushID(n.CString()); }, (const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void PushID(int int_id)", asFUNCTIONPR([](int id) { ImGui::PushID(id); }, (int), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void PopID()", asFUNCTIONPR(ImGui::PopID, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("uint GetID(const String&in)", asFUNCTIONPR([](const String& n) { return ImGui::GetID(n.CString()); }, (const String&), unsigned), asCALL_CDECL);
// Widgets: Text
engine->RegisterGlobalFunction("void Text(const String&in)", asFUNCTIONPR([](const String& n) {
ImGui::TextUnformatted(n.CString());
}, (const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void TextColored(Color col, const String&in)", asFUNCTIONPR([](Color c, const String& n) {
auto v = c.ToVector4();
ImGui::TextColored(ImVec4(v.x_, v.y_, v.z_, v.w_), n.CString());
}, (Color, const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void TextWrapped(const String&in)", asFUNCTIONPR([](const String& n) {
ImGui::TextWrapped(n.CString()); }, (const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void LabelText(const String&in, const String&in)", asFUNCTIONPR([](const String& l, const String& n) {
ImGui::LabelText(l.CString(), n.CString()); }, (const String&, const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Bullet()", asFUNCTIONPR(ImGui::Bullet, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void BulletText(const String&in)", asFUNCTIONPR([](const String& n) {
ImGui::BulletText(n.CString()); }, (const String&), void), asCALL_CDECL);
// Widgets: Main
engine->RegisterGlobalFunction("bool Button(const String&in, Vector2 = Vector2(0,0))", asFUNCTIONPR([](const String& n, Vector2 v) {
return ImGui::Button(n.CString(), ImVec2(v.x_, v.y_));
}, (const String&, Vector2), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SmallButton(const String&in)", asFUNCTIONPR([](const String& n) {
return ImGui::SmallButton(n.CString()); }, (const String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InvisibleButton(const String&in, Vector2)", asFUNCTIONPR([](const String& id, Vector2 v) {
return ImGui::InvisibleButton(id.CString(), ImVec2(v.x_, v.y_)); }, (const String&, Vector2), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void Image(uint, Vector2)", asFUNCTIONPR([](unsigned u, Vector2 v) {
ImGui::Image((ImTextureID)u, ImVec2(v.x_, v.y_));
}, (unsigned, Vector2), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool Checkbox(const String&in, bool&inout)", asFUNCTIONPR([](const String& n, bool& v) {
return ImGui::Checkbox(n.CString(), &v); }, (const String&, bool&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool CheckboxFlags(const String&in, uint&inout, uint)", asFUNCTIONPR([](const String& n, unsigned& f, unsigned v) {
return ImGui::CheckboxFlags(n.CString(), &f, v); }, (const String&, unsigned&, unsigned), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool RadioButton(const String&in, bool)", asFUNCTIONPR([](const String& n, bool v) {
return ImGui::RadioButton(n.CString(), v); }, (const String&, bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool RadioButton(const String&in, int&inout, int)", asFUNCTIONPR([](const String& n, int& v, int vv) {
return ImGui::RadioButton(n.CString(), &v, vv); }, (const String&, int&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void ProgressBar(float)", asFUNCTIONPR([](float v) {
ImGui::ProgressBar(v); }, (float), void), asCALL_CDECL);
// Widgets: Combo Box
engine->RegisterGlobalFunction("bool BeginCombo(const String&in, const String&in, int = 0)", asFUNCTIONPR([](const String& id, const String& prevItem, int flags) { return ImGui::BeginCombo(id.CString(), prevItem.CString(), flags); }, (const String&, const String&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndCombo()", asFUNCTIONPR(ImGui::EndCombo, (), void), asCALL_CDECL);
static char imgui_comboItem[4096];
engine->RegisterGlobalFunction("bool Combo(const String&in, int&inout, const Array<String>@+)", asFUNCTIONPR([](const String& lbl, int& index, const CScriptArray* items) {
memset(imgui_comboItem, 0, sizeof(char) * 4096);
unsigned offset = 0;
for (unsigned i = 0; i < items->GetSize(); ++i)
{
String* str = ((String*)items->At(i));
strcpy(imgui_comboItem + offset, str->CString());
offset += str->Length() + 1;
}
return ImGui::Combo(lbl.CString(), &index, imgui_comboItem, -1);
}, (const String&, int&, const CScriptArray*), bool), asCALL_CDECL);
// Widgets: Drags
engine->RegisterGlobalFunction("bool DragFloat(const String&in, float&inout, float = 1.0f, float = 0.0f, float = 0.0f)", asFUNCTIONPR([](const String& n, float& v, float speed, float mn, float mx) {
return ImGui::DragFloat(n.CString(), &v, speed, mn, mx); }, (const String&, float&, float, float, float), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragFloat2(const String&in, Vector2&inout)", asFUNCTIONPR([](const String& n, Vector2& v) {
return ImGui::DragFloat2(n.CString(), &v.x_); }, (const String&, Vector2&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragFloat3(const String&in, Vector3&inout)", asFUNCTIONPR([](const String& n, Vector3& v) {
return ImGui::DragFloat3(n.CString(), &v.x_); }, (const String&, Vector3&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragFloat4(const String&in, Vector4&inout)", asFUNCTIONPR([](const String& n, Vector4& v) {
return ImGui::DragFloat4(n.CString(), &v.x_); }, (const String&, Vector4&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragInt(const String&in, int&inout, int = 0, int = 0)", asFUNCTIONPR([](const String& n, int& v, int mn, int mx) {
return ImGui::DragInt(n.CString(), &v, 1.0f, mn, mx); }, (const String&, int&, int, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragInt2(const String&in, IntVector2&inout, int = 0, int = 0)", asFUNCTIONPR([](const String& n, IntVector2& v, int mn, int mx) {
return ImGui::DragInt2(n.CString(), &v.x_, 1.0f, mn, mx); }, (const String&, IntVector2&, int,int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragInt3(const String&in, IntVector3&inout, int = 0, int = 0)", asFUNCTIONPR([](const String& n, IntVector3& v, int mn, int mx) {
return ImGui::DragInt3(n.CString(), &v.x_, 1.0f, mn, mx); }, (const String&, IntVector3&, int,int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragFloatRange2(const String&in, float&inout, float&inout, float = 0.0f, float = 1.0f)", asFUNCTIONPR([](const String& n, float& v0, float&v1, float mn, float mx) {
return ImGui::DragFloatRange2(n.CString(), &v0, &v1, 1.0f, mn, mx); }, (const String&, float&, float&, float, float), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool DragIntRange2(const String&in, int&inout, int&inout, int, int)", asFUNCTIONPR([](const String& n, int& v0, int&v1, int mn, int mx) {
return ImGui::DragIntRange2(n.CString(), &v0, &v1, 1.0f, mn, mx); }, (const String&, int&, int&, int, int), bool), asCALL_CDECL);
// Widgets: Input with Keyboard
static char imgui_text_buffer[4096]; // shared with multiple widgets
engine->RegisterGlobalFunction("bool InputText(const String&in, String&inout)", asFUNCTIONPR([](const String& id, String& val) {
memset(imgui_text_buffer, 0, sizeof(char) * 4096);
strcpy(imgui_text_buffer, val.CString());
if (ImGui::InputText(id.CString(), imgui_text_buffer, 4096))
{
val = imgui_text_buffer;
return true;
}
return false;
}, (const String&, String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputTextMultiline(const String&in, String&inout)", asFUNCTIONPR([](const String& id, String& val) {
memset(imgui_text_buffer, 0, sizeof(char) * 4096);
strcpy(imgui_text_buffer, val.CString());
if (ImGui::InputTextMultiline(id.CString(), imgui_text_buffer, 4096))
{
val = imgui_text_buffer;
return true;
}
return false;
}, (const String&, String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputFloat(const String&, float&inout)", asFUNCTIONPR([](const String& id, float& val) {
return ImGui::InputFloat(id.CString(), &val); }, (const String&, float&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputFloat2(const String&, Vector2&inout)", asFUNCTIONPR([](const String& id, Vector2& val) {
return ImGui::InputFloat2(id.CString(), &val.x_); }, (const String&, Vector2&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputFloat3(const String&, Vector3&inout)", asFUNCTIONPR([](const String& id, Vector3& val) {
return ImGui::InputFloat3(id.CString(), &val.x_); }, (const String&, Vector3&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputFloat4(const String&, Vector4&inout)", asFUNCTIONPR([](const String& id, Vector4& val) {
return ImGui::InputFloat4(id.CString(), &val.x_); }, (const String&, Vector4&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputInt(const String&, int&inout)", asFUNCTIONPR([](const String& id, int& val) {
return ImGui::InputInt(id.CString(), &val); }, (const String&, int&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputInt2(const String&, IntVector2&inout)", asFUNCTIONPR([](const String& id, IntVector2& val) {
return ImGui::InputInt2(id.CString(), &val.x_); }, (const String&, IntVector2&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool InputInt3(const String&, IntVector3&inout)", asFUNCTIONPR([](const String& id, IntVector3& val) {
return ImGui::InputInt3(id.CString(), &val.x_); }, (const String&, IntVector3&), bool), asCALL_CDECL);
// Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds)
engine->RegisterGlobalFunction("bool SliderFloat(const String&in, float&inout, float = 0.0f, float = 0.0f)", asFUNCTIONPR([](const String& n, float& v, float mn, float mx) {
return ImGui::SliderFloat(n.CString(), &v, mn, mx); }, (const String&, float&, float,float), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SliderFloat2(const String&in, Vector2&inout, float, float)", asFUNCTIONPR([](const String& n, Vector2& v, float mn, float mx) {
return ImGui::SliderFloat2(n.CString(), &v.x_, mn, mx); }, (const String&, Vector2&, float,float),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SliderFloat3(const String&in, Vector3&inout, float, float)", asFUNCTIONPR([](const String& n, Vector3& v, float mn, float mx) {
return ImGui::SliderFloat3(n.CString(), &v.x_, mn, mx); }, (const String&, Vector3&, float,float),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SliderFloat4(const String&in, Vector4&inout, float, float)", asFUNCTIONPR([](const String& n, Vector4& v, float mn, float mx) {
return ImGui::SliderFloat4(n.CString(), &v.x_, mn, mx); }, (const String&, Vector4&,float,float),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SliderInt(const String&in, int&inout, int = 0, int = 0)", asFUNCTIONPR([](const String& n, int& v, int mn, int mx) {
return ImGui::SliderInt(n.CString(), &v, mn, mx); }, (const String&, int&,int,int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SliderInt2(const String&in, IntVector2&inout, int = 0, int = 0)", asFUNCTIONPR([](const String& n, IntVector2& v, int mn, int mx) {
return ImGui::SliderInt2(n.CString(), &v.x_, mn, mx); }, (const String&, IntVector2&, int,int),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool SliderInt3(const String&in, IntVector3&inout, int = 0, int = 0)", asFUNCTIONPR([](const String& n, IntVector3& v, int mn, int mx) {
return ImGui::SliderInt3(n.CString(), &v.x_, mn, mx); }, (const String&, IntVector3&, int,int),bool), asCALL_CDECL);
// Widgets: Color Editor/Picker
engine->RegisterGlobalFunction("bool ColorEdit3(const String&in, Color&inout)", asFUNCTIONPR([](const String& id, Color& val) {
auto v = val.ToVector3();
if (ImGui::ColorEdit3(id.CString(), &v.x_))
{
val = Color(v.x_, v.y_, v.z_);
return true;
}
return false;
}, (const String&, Color&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool ColorEdit4(const String&in, Color&inout)", asFUNCTIONPR([](const String& id, Color& val) {
auto v = val.ToVector4();
if (ImGui::ColorEdit4(id.CString(), &v.x_))
{
val = Color(v.x_, v.y_, v.z_, v.w_);
return true;
}
return false;
}, (const String&, Color&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool ColorPicker3(const String&in, Color&inout)", asFUNCTIONPR([](const String& id, Color& val) {
auto v = val.ToVector3();
if (ImGui::ColorPicker3(id.CString(), &v.x_))
{
val = Color(v.x_, v.y_, v.z_);
return true;
}
return false;
}, (const String&, Color&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool ColorPicker4(const String&in, Color&inout)", asFUNCTIONPR([](const String& id, Color& val) {
auto v = val.ToVector4();
if (ImGui::ColorPicker4(id.CString(), &v.x_))
{
val = Color(v.x_, v.y_, v.z_, v.w_);
return true;
}
return false;
}, (const String&, Color&),bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool ColorButton(const String&in, Color)", asFUNCTIONPR([](const String& id, Color val) {
auto v = val.ToVector4();
ImVec4 vv(v.x_, v.y_, v.z_, v.w_);
return ImGui::ColorButton(id.CString(), vv);
}, (const String&, Color), bool), asCALL_CDECL);
// Widgets: Trees
engine->RegisterGlobalFunction("bool TreeNode(const String&in)", asFUNCTIONPR([](const String& id) { return ImGui::TreeNode(id.CString()); }, (const String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void TreePush(const String&in)", asFUNCTIONPR([](const String& id) { ImGui::TreePush(id.CString()); }, (const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void TreePop()", asFUNCTIONPR(ImGui::TreePop, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void TreeAdvanceToLabelPos()", asFUNCTIONPR(ImGui::TreeAdvanceToLabelPos, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetTreeNodeToLabelSpacing()", asFUNCTIONPR(ImGui::GetTreeNodeToLabelSpacing, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetNextTreeNodeOpen(bool)", asFUNCTIONPR([](bool val) { ImGui::SetNextTreeNodeOpen(val); }, (bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool CollapsingHeader(const String&in)", asFUNCTIONPR([](const String& n) { return ImGui::CollapsingHeader(n.CString()); }, (const String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool CollapsingHeader(const String&in, bool&inout)", asFUNCTIONPR([](const String& n, bool& v) { return ImGui::CollapsingHeader(n.CString(), &v); }, (const String&, bool&), bool), asCALL_CDECL);
// Widgets: Selectable / Lists
engine->RegisterGlobalFunction("bool Selectable(const String&in, bool = false)", asFUNCTIONPR([](const String& n, bool v) { return ImGui::Selectable(n.CString(), v); }, (const String&, bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool ListBoxHeader(const String&in)", asFUNCTIONPR([](const String& n) { return ImGui::ListBoxHeader(n.CString()); }, (const String&), bool), asCALL_CDECL);
// Values
engine->RegisterGlobalFunction("void Value(const String&in, bool)", asFUNCTIONPR([](const String& n, bool v) { ImGui::Value(n.CString(), v); }, (const String&, bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Value(const String&in, int)", asFUNCTIONPR([](const String& n, int v) { ImGui::Value(n.CString(), v); }, (const String&, int), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Value(const String&in, uint)", asFUNCTIONPR([](const String& n, unsigned v) { ImGui::Value(n.CString(), v);}, (const String&, unsigned), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void Value(const String&in, float)", asFUNCTIONPR([](const String& n, float v) { ImGui::Value(n.CString(), v); }, (const String&, float), void), asCALL_CDECL);
// Tooltips
engine->RegisterGlobalFunction("void BeginTooltip()", asFUNCTIONPR(ImGui::BeginTooltip , (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndTooltip()", asFUNCTIONPR(ImGui::EndTooltip , (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetTooltip(const String&in)", asFUNCTIONPR([](const String& t) { ImGui::SetTooltip(t.CString()); }, (const String&), void), asCALL_CDECL);
// Menus
engine->RegisterGlobalFunction("bool BeginMainMenuBar()", asFUNCTIONPR([]() { return ImGui::BeginMainMenuBar(); }, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndMainMenuBar()", asFUNCTIONPR([]() { ImGui::EndMainMenuBar(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginMenuBar()", asFUNCTIONPR([]() { return ImGui::BeginMenuBar(); }, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndMenuBar()", asFUNCTIONPR([]() { ImGui::EndMenuBar(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginMenu(const String&in, bool = true)", asFUNCTIONPR([](const String& a, bool b) {
return ImGui::BeginMenu(a.Empty() ? a.CString() : 0x0, b); }, (const String&, bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndMenu()", asFUNCTIONPR([]() { ImGui::EndMenu(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool MenuItem(const String&in, const String&in = String(), bool = false, bool = true)", asFUNCTIONPR([](const String& a, const String& b, bool c, bool d) {
return ImGui::MenuItem(a.Empty() ? a.CString() : 0x0, b.Empty() ? b.CString() : 0x0, c, d); }, (const String&, const String&, bool, bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool MenuItem(const String&in, const String&in, bool &inout, bool = true)", asFUNCTIONPR([](const String& a, const String& b, bool& c, bool d) {
return ImGui::MenuItem(a.Empty() ? a.CString() : 0x0, b.Empty() ? b.CString() : 0x0, &c, d); }, (const String&, const String&, bool&, bool), bool), asCALL_CDECL);
// Popups
engine->RegisterGlobalFunction("void OpenPopup(const String&in)", asFUNCTIONPR([](const String& a) { ImGui::OpenPopup(a.Empty() ? a.CString() : 0x0); }, (const String&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginPopup(const String&in, int = 0)", asFUNCTIONPR([](const String& a, int b) {
return ImGui::BeginPopup(a.Empty() ? a.CString() : 0x0, (ImGuiWindowFlags)b); }, (const String&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginPopupContextItem(const String&in = String(), int = 1)", asFUNCTIONPR([](const String& a, int b) {
return ImGui::BeginPopupContextItem(a.Empty() ? a.CString() : 0x0, b); }, (const String&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginPopupContextWindow(const String&in = String(), int = 1, bool = true)", asFUNCTIONPR([](const String& a, int b, bool c) {
return ImGui::BeginPopupContextWindow(a.Empty() ? a.CString() : 0x0, b, c); }, (const String&, int, bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginPopupContextVoid(const String&in = String(), int = 1)", asFUNCTIONPR([](const String& a, int b) {
return ImGui::BeginPopupContextVoid(a.Empty() ? a.CString() : 0x0, b); }, (const String&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginPopupModal(const String&in, bool &inout = null, int = 0)", asFUNCTIONPR([](const String& a, bool& b, int c) {
return ImGui::BeginPopupModal(a.Empty() ? a.CString() : 0x0, &b, (ImGuiWindowFlags)c); }, (const String&, bool&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndPopup()", asFUNCTIONPR([]() { ImGui::EndPopup(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool OpenPopupOnItemClick(const String&in = String(), int = 1)", asFUNCTIONPR([](const String& a, int b) {
return ImGui::OpenPopupOnItemClick(a.Empty() ? a.CString() : 0x0, b); }, (const String&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsPopupOpen(const String&in)", asFUNCTIONPR([](const String& a) {
return ImGui::IsPopupOpen(a.Empty() ? a.CString() : 0x0); }, (const String&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void CloseCurrentPopup()", asFUNCTIONPR([]() { ImGui::CloseCurrentPopup(); }, (), void), asCALL_CDECL);
// Clip-rects
engine->RegisterGlobalFunction("void PushClipRect(const Vector2&, const Vector2&, bool)", asFUNCTIONPR([](const Vector2& a, const Vector2& b, bool c) {
ImGui::PushClipRect(ImVec2(a.x_, a.y_), ImVec2(b.x_, b.y_), c); }, (const Vector2&, const Vector2&, bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void PopClipRect()", asFUNCTIONPR([]() { ImGui::PopClipRect(); }, (), void), asCALL_CDECL);
// Focus
engine->RegisterGlobalFunction("void SetItemDefaultFocus()", asFUNCTIONPR([]() { ImGui::SetItemDefaultFocus(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetKeyboardFocusHere(int = 0)", asFUNCTIONPR([](int a) { ImGui::SetKeyboardFocusHere(a); }, (int), void), asCALL_CDECL);
// Utilities
engine->RegisterGlobalFunction("bool IsItemHovered(int = 0)", asFUNCTIONPR([](int a) { return ImGui::IsItemHovered((ImGuiHoveredFlags)a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsItemActive()", asFUNCTIONPR([]() { return ImGui::IsItemActive(); }, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsItemClicked(int = 0)", asFUNCTIONPR([](int a) { return ImGui::IsItemClicked(a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsItemVisible()", asFUNCTIONPR([]() { return ImGui::IsItemVisible(); }, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsAnyItemHovered()", asFUNCTIONPR([]() { return ImGui::IsAnyItemHovered(); }, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsAnyItemActive()", asFUNCTIONPR([]() { return ImGui::IsAnyItemActive(); }, (), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetItemRectMin()", asFUNCTIONPR([]() { auto v = ImGui::GetItemRectMin(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetItemRectMax()", asFUNCTIONPR([]() { auto v = ImGui::GetItemRectMax(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetItemRectSize()", asFUNCTIONPR([]() { auto v = ImGui::GetItemRectSize(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetItemAllowOverlap()", asFUNCTIONPR([]() { ImGui::SetItemAllowOverlap(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsWindowFocused(int = 0)", asFUNCTIONPR([](int a) { return ImGui::IsWindowFocused((ImGuiFocusedFlags)a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsWindowHovered(int = 0)", asFUNCTIONPR([](int a) { return ImGui::IsWindowHovered((ImGuiHoveredFlags)a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsRectVisible(const Vector2&)", asFUNCTIONPR([](const Vector2& a) { return ImGui::IsRectVisible(ImVec2(a.x_, a.y_)); }, (const Vector2&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsRectVisible(const Vector2&, const Vector2&)", asFUNCTIONPR([](const Vector2& a, const Vector2& b) { return ImGui::IsRectVisible(ImVec2(a.x_, a.y_), ImVec2(b.x_, b.y_)); }, (const Vector2&, const Vector2&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("float GetTime()", asFUNCTIONPR([]() { return ImGui::GetTime(); }, (), float), asCALL_CDECL);
engine->RegisterGlobalFunction("int GetFrameCount()", asFUNCTIONPR([]() { return ImGui::GetFrameCount(); }, (), int), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 CalcTextSize(const String&in, const String&in = String(), bool = false, float = -1.0f)", asFUNCTIONPR([](const String& a, const String& b, bool c, float d) {
auto v = ImGui::CalcTextSize(a.Empty() ? a.CString() : 0x0, b.Empty() ? b.CString() : 0x0, c, d); return Vector2(v.x, v.y); }, (const String&, const String&, bool, float), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("void CalcListClipping(int, float, int&inout, int&inout)", asFUNCTIONPR([](int a, float b, int& c, int& d) {
ImGui::CalcListClipping(a, b, &c, &d); }, (int,float,int&,int&), void), asCALL_CDECL);
engine->RegisterGlobalFunction("bool BeginChildFrame(uint, const Vector2&, int = 0)", asFUNCTIONPR([](unsigned a, const Vector2& b, int c) {
return ImGui::BeginChildFrame(a, ImVec2(b.x_,b.y_), (ImGuiWindowFlags)c); }, (unsigned, const Vector2&, int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("void EndChildFrame()", asFUNCTIONPR([]() { ImGui::EndChildFrame(); }, (), void), asCALL_CDECL);
engine->RegisterGlobalFunction("int GetKeyIndex(int)", asFUNCTIONPR([](int a) { return ImGui::GetKeyIndex((ImGuiKey)a); }, (int), int), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsKeyDown(int)", asFUNCTIONPR([](int a) { return ImGui::IsKeyDown(a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsKeyPressed(int, bool = true)", asFUNCTIONPR([](int a, bool b) { return ImGui::IsKeyPressed(a, b); }, (int,bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsKeyReleased(int)", asFUNCTIONPR([](int a) { return ImGui::IsKeyReleased(a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("int GetKeyPressedAmount(int, float, float)", asFUNCTIONPR([](int a, float b, float c) { return ImGui::GetKeyPressedAmount(a, b, c); }, (int,float,float), int), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMouseDown(int)", asFUNCTIONPR([](int a) { return ImGui::IsMouseDown(a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMouseClicked(int, bool = false)", asFUNCTIONPR([](int a, bool b) { return ImGui::IsMouseClicked(a, b); }, (int,bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMouseDoubleClicked(int)", asFUNCTIONPR([](int a) { return ImGui::IsMouseDoubleClicked(a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMouseReleased(int)", asFUNCTIONPR([](int a) { return ImGui::IsMouseReleased(a); }, (int), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMouseDragging(int = 0, float = -1.0f)", asFUNCTIONPR([](int a, float b) { return ImGui::IsMouseDragging(a, b); }, (int, float), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMouseHoveringRect(const Vector2&in, const Vector2&in, bool = true)", asFUNCTIONPR([](const Vector2& a, const Vector2& b, bool c) { return ImGui::IsMouseHoveringRect(ImVec2(a.x_, a.y_), ImVec2(b.x_, b.y_), c); }, (const Vector2&, const Vector2&, bool), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("bool IsMousePosValid(const Vector2&in)", asFUNCTIONPR([](const Vector2& a) { auto v = ImVec2(a.x_, a.y_); return ImGui::IsMousePosValid(&v); }, (const Vector2&), bool), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetMousePos()", asFUNCTIONPR([]() { auto v = ImGui::GetMousePos(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetMousePosOnOpeningCurrentPopup()", asFUNCTIONPR([]() { auto v = ImGui::GetMousePosOnOpeningCurrentPopup(); return Vector2(v.x, v.y); }, (), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("Vector2 GetMouseDragDelta(int = 0, float = -1.0f)", asFUNCTIONPR([](int a, float b) { auto v = ImGui::GetMouseDragDelta(a, b); return Vector2(v.x, v.y); }, (int,float), Vector2), asCALL_CDECL);
engine->RegisterGlobalFunction("void ResetMouseDragDelta(int = 0)", asFUNCTIONPR([](int a) { ImGui::ResetMouseDragDelta(a); }, (int), void), asCALL_CDECL);
engine->RegisterGlobalFunction("int GetMouseCursor()", asFUNCTIONPR([]() { return ImGui::GetMouseCursor(); }, (), int), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetMouseCursor(int)", asFUNCTIONPR([](ImGuiMouseCursor a) { ImGui::SetMouseCursor(a); }, (int), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void CaptureKeyboardFromApp(bool = true)", asFUNCTIONPR([](bool a) { ImGui::CaptureKeyboardFromApp(a); }, (bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("void CaptureMouseFromApp(bool = true)", asFUNCTIONPR([](bool a) { ImGui::CaptureMouseFromApp(a); }, (bool), void), asCALL_CDECL);
engine->RegisterGlobalFunction("String GetClipboardText()", asFUNCTIONPR([]() { return String(ImGui::GetClipboardText()); }, (), String), asCALL_CDECL);
engine->RegisterGlobalFunction("void SetClipboardText(const String&in)", asFUNCTIONPR([](const String& a) { ImGui::SetClipboardText(a.Empty() ? a.CString() : 0x0); }, (const String&), void), asCALL_CDECL);
engine->SetDefaultNamespace("");
}
}
//?? worth caring about freeing the font-texture?
//?? #1565 changes in the future
//?? Future changes to survive DearImGui context/window changes
//?? Gamepad navigation
//?? Font glyphs
#include "../Precompiled.h"
#include "../Core/Context.h"
#include "../Graphics/Graphics.h"
#include "../Graphics/GraphicsEvents.h"
#include "../Resource/Image.h"
#include "../UI/ImGuiElement.h"
#include "../Input/Input.h"
#include "../Resource/ResourceCache.h"
#include "../Graphics/Texture2D.h"
#include "../UI/UI.h"
#include "../IO/Log.h"
#include <ImGui/imgui.h>
namespace Urho3D
{
extern const char* UI_CATEGORY;
const char* IMGUI_FONT_TEXTURE = "IMGUI_FONT_TEXTURE";
const intptr_t IMGUI_FONT_KEY = -1;
void AddTriangleToUIBatch(UIBatch& batch)
{
}
ImGuiElement::ImGuiElement(Context* context) :
UIElement(context),
imguiContext_(nullptr),
renderFunction_(nullptr)
{
enabled_ = true;
SetFocusMode(FM_FOCUSABLE);
imguiContext_ = ImGui::CreateContext();
ImGui::SetCurrentContext(imguiContext_);
ImGuiIO& io = ImGui::GetIO();
CreateFontTexture();
// Scancodes and key-codes mixed because SDL keys have massive values in many cases
io.KeyMap[ImGuiKey_Tab] = KEY_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = SCANCODE_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = SCANCODE_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = SCANCODE_UP;
io.KeyMap[ImGuiKey_DownArrow] = SCANCODE_DOWN;
io.KeyMap[ImGuiKey_PageUp] = SCANCODE_PAGEUP;
io.KeyMap[ImGuiKey_PageDown] = SCANCODE_PAGEDOWN;
io.KeyMap[ImGuiKey_Home] = SCANCODE_HOME;
io.KeyMap[ImGuiKey_End] = SCANCODE_END;
io.KeyMap[ImGuiKey_Insert] = SCANCODE_INSERT;
io.KeyMap[ImGuiKey_Delete] = KEY_DELETE;
io.KeyMap[ImGuiKey_Backspace] = KEY_BACKSPACE;
io.KeyMap[ImGuiKey_Enter] = KEY_RETURN;
io.KeyMap[ImGuiKey_Escape] = KEY_ESCAPE;
io.KeyMap[ImGuiKey_A] = KEY_A;
io.KeyMap[ImGuiKey_C] = KEY_C;
io.KeyMap[ImGuiKey_V] = KEY_V;
io.KeyMap[ImGuiKey_X] = KEY_X;
io.KeyMap[ImGuiKey_Y] = KEY_Y;
io.KeyMap[ImGuiKey_Z] = KEY_Z;
// Render function is deliberately not set
// Buffering the UIBatches and vertex-data was ridiculously slow
ImGui::StyleColorsDark();
SubscribeToEvent(E_DEVICERESET, URHO3D_HANDLER(ImGuiElement, HandleDeviceReset));
}
ImGuiElement::~ImGuiElement()
{
if (imguiContext_)
{
//!!! NOTICE: this block will be invalid when [GH issue #1565](https://github.com/ocornut/imgui/issues/1565) makes its' way into the DearImGui trunk
// have to shut it down to clear it's context local copy of font data
ImGui::SetCurrentContext(imguiContext_);
ImGui::Shutdown();
// this only frees, does not shut it down
ImGui::DestroyContext(imguiContext_);
imguiContext_ = nullptr;
}
}
void ImGuiElement::RegisterObject(Context* context)
{
context->RegisterFactory<ImGuiElement>(UI_CATEGORY);
URHO3D_ACCESSOR_ATTRIBUTE("Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Visible", IsVisible, SetVisible, bool, true, AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Alpha Multiplier", GetAlphaMultiplier, SetAlphaMultiplier, float, 1.0f, AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Antialias", AntialiasEnabled, SetAntialize, bool, true, AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Touch Padding", GetTouchPadding, SetTouchPadding, Vector2, Vector2(0, 0), AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Font Size", GetFontSize, SetFontSize, int, 20, AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Show Metrics", IsMetricsWindowVisible, SetMetricsWindowVisible, bool, false, AM_DEFAULT);
URHO3D_ACCESSOR_ATTRIBUTE("Show Demo", IsDemoWindowVisible, SetDemoWindowVisible, bool, false, AM_DEFAULT);
}
void ImGuiElement::Update(float timeStep)
{
// If not visible then there's nothing todo
if (!IsVisibleEffective() || GetAlphaMultiplier() == 0.0f)
{
// make sure we don't have the focus to be interrupting anything
if (HasFocus())
SetFocus(false);
return;
}
ImGui::SetCurrentContext(imguiContext_);
Graphics* graphics = GetSubsystem<Graphics>();
// Always keep ourselves fullscreen, not 100% necessary but it guarantees popups behave.
SetPosition(0, 0);
SetWidth(graphics->GetWidth());
SetHeight(graphics->GetHeight());
const Input* input = GetSubsystem<Input>();
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = timeStep;
// Viewport
io.DisplaySize = ImVec2(GetWidth(), GetHeight());
// Grab whoever is under the mouse so that regular UI elements will be respected
IntVector2 mousePos = input->GetMousePosition();
UIElement* mouseHitter = GetSubsystem<UI>()->GetElementAt(mousePos);
// Process input, if allowed
// do nothing if the mouse is in a capturing state
// respect the Z-index precedent under the mouse
if (IsEnabled() && (input->GetMouseMode() == MM_FREE || input->GetMouseMode() == MM_ABSOLUTE) && (mouseHitter == nullptr || mouseHitter == this))
{
// Mouse
if (input->GetNumTouches())
mousePos = input->GetTouch(0)->position_;
io.MousePos = ImVec2(mousePos.x_, mousePos.y_);
io.MouseDown[0] = input->GetMouseButtonDown(MOUSEB_LEFT) || input->GetNumTouches();
io.MouseDown[1] = input->GetMouseButtonDown(MOUSEB_RIGHT);
io.MouseDown[2] = input->GetMouseButtonDown(MOUSEB_MIDDLE);
// Is suppressing mouse wheel the correct thing to do? Mouse dampening?
// Wheel amounts vary considerably between mice, as much as an order of magnitude
int wheel = input->GetMouseMoveWheel();
io.MouseWheel = wheel > 0 ? 1 : (wheel < 0 ? -1 : 0);
// Modifier keys
io.KeyAlt = input->GetScancodeDown(SCANCODE_ALT);
io.KeyCtrl = input->GetScancodeDown(SCANCODE_CTRL);
io.KeyShift = input->GetScancodeDown(SCANCODE_SHIFT);
// We get text through the OnTextInput, SDL's keycodes are a complete mess so only dealing with these important keys
io.KeysDown[KEY_TAB] = input->GetKeyDown(KEY_TAB);
io.KeysDown[SCANCODE_LEFT] = input->GetScancodeDown(SCANCODE_LEFT);
io.KeysDown[SCANCODE_RIGHT] = input->GetScancodeDown(SCANCODE_RIGHT);
io.KeysDown[SCANCODE_UP] = input->GetScancodeDown(SCANCODE_UP);
io.KeysDown[SCANCODE_DOWN] = input->GetScancodeDown(SCANCODE_DOWN);
io.KeysDown[SCANCODE_PAGEUP] = input->GetScancodeDown(SCANCODE_PAGEUP);
io.KeysDown[SCANCODE_PAGEDOWN] = input->GetScancodeDown(SCANCODE_PAGEDOWN);
io.KeysDown[SCANCODE_HOME] = input->GetScancodeDown(SCANCODE_HOME);
io.KeysDown[SCANCODE_END] = input->GetScancodeDown(SCANCODE_END);
io.KeysDown[SCANCODE_INSERT] = input->GetScancodeDown(SCANCODE_INSERT);
io.KeysDown[KEY_DELETE] = input->GetKeyDown(KEY_DELETE);
io.KeysDown[KEY_BACKSPACE] = input->GetKeyDown(KEY_BACKSPACE);
io.KeysDown[KEY_RETURN] = input->GetKeyDown(KEY_RETURN);
io.KeysDown[KEY_ESCAPE] = input->GetKeyDown(KEY_ESCAPE);
io.KeysDown[KEY_A] = input->GetKeyDown(KEY_A);
io.KeysDown[KEY_C] = input->GetKeyDown(KEY_C);
io.KeysDown[KEY_V] = input->GetKeyDown(KEY_V);
io.KeysDown[KEY_X] = input->GetKeyDown(KEY_X);
io.KeysDown[KEY_Y] = input->GetKeyDown(KEY_Y);
io.KeysDown[KEY_Z] = input->GetKeyDown(KEY_Z);
if (!lastText_.Empty())
io.AddInputCharactersUTF8(lastText_.CString());
}
else
{
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
io.MouseWheel = false;
io.MouseDown[0] = io.MouseDown[1] = io.MouseDown[2] = false;
for (int i = 0; i < 512; ++i)
io.KeysDown[i] = false;
}
lastText_ = String::EMPTY;
ImGui::NewFrame();
// if we have a render function then use that, otherwise default to whatever is in our virtual method
if (renderFunction_)
renderFunction_;
else
{
VariantMap& eventMap = GetEventDataMap();
using namespace IMGUIDraw;
eventMap[IMGUIDraw::P_ELEMENT] = this;
eventMap[IMGUIDraw::P_TIMESTEP] = timeStep;
SendEvent(E_IMGUI_DRAW, eventMap);
RenderImGui();
}
// Show optional windows as appropriate
if (showMetrics_)
ImGui::ShowMetricsWindow();
if (showDemo_)
ImGui::ShowDemoWindow();
ImGui::Render();
if (io.WantTextInput || io.WantCaptureKeyboard || io.WantCaptureMouse)
{
if (!HasFocus())
SetFocus(true);
if (io.WantTextInput && GetSubsystem<UI>()->GetUseScreenKeyboard())
GetSubsystem<UI>()->SetUseScreenKeyboard(true);
}
else // unfocus otherwise
{
if (HasFocus() && GetSubsystem<UI>()->GetUseScreenKeyboard())
GetSubsystem<UI>()->SetUseScreenKeyboard(false);
SetFocus(false);
}
}
void ImGuiElement::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
{
if (!IsVisibleEffective())
return;
// Can batches be a bit more aggressive? Add to the batch in the back unless textureid changes?
// ImGui is pretty aggressive about minimizing batches though
// ImGui doesn't flush draw data after the end of the frame, so this is safe to do (for now)
ImGui::SetCurrentContext(imguiContext_);
ImDrawData* drawData = ImGui::GetDrawData();
if (drawData == nullptr)
return;
for (int cmdListIdx = 0; cmdListIdx < drawData->CmdListsCount; ++cmdListIdx)
{
ImDrawList* drawList = drawData->CmdLists[cmdListIdx];
ImDrawIdx idx_buffer_offset = 0;
for (int cmdIdx = 0; cmdIdx < drawList->CmdBuffer.Size; ++cmdIdx)
{
const ImDrawCmd* drawCmd = &drawList->CmdBuffer[cmdIdx];
if (drawCmd->UserCallback)
{
//TODO: is there a meaningful use to this?
// most likely entirely end-user-project specific
}
else
{
ImVec4 clipRect = drawCmd->ClipRect;
Texture* texture = nullptr;
if (drawCmd->TextureId)
{
intptr_t textureID = (intptr_t)drawCmd->TextureId;
HashMap<intptr_t, SharedPtr<Texture2D> >::ConstIterator foundTexture = textureTable_.Find(textureID);
if (foundTexture != textureTable_.End())
texture = foundTexture->second_.Get();
}
else
texture = fontTexture_;
UIBatch batch(this, BLEND_ALPHA, IntRect(clipRect.x, clipRect.y, clipRect.z, clipRect.w), texture, &vertexData);
batch.useGradient_ = true;
unsigned begin = batch.vertexData_->Size();
batch.vertexData_->Resize(begin + drawCmd->ElemCount * UI_VERTEX_SIZE);
float* dest = &(batch.vertexData_->At(begin));
batch.vertexEnd_ = batch.vertexData_->Size();
// Unfortunately, the index buffer is used a lot
// Consider adding Vtx/Idx buffer support to UI batch?
for (unsigned i = 0; i < drawCmd->ElemCount; ++i)
{
unsigned index = drawList->IdxBuffer[idx_buffer_offset+i];
auto vert = drawList->VtxBuffer[index];
// ?? Consider reordering ImDrawVertex data, would be able to memcpy then
dest[0] = vert.pos.x;
dest[1] = vert.pos.y;
dest[2] = 0.0f;
((unsigned&)dest[3]) = vert.col;
dest[4] = vert.uv.x;
dest[5] = vert.uv.y;
// xyz, rgba8, uv
dest += UI_VERTEX_SIZE;
}
batches.Push(batch);
}
idx_buffer_offset += drawCmd->ElemCount;
}
}
}
void ImGuiElement::OnTextInput(const String& text)
{
lastText_ = text;
}
IntVector2 ImGuiElement::ScreenToElement(const IntVector2& screenPosition)
{
// This is a hack, the ImGuiElement assumes it has the entire screen
// Doing this allows it to play nicely with the rest of Urho3D UI based on Z-index
if (!HasFocus() || !IsEnabled() || !IsVisibleEffective())
return IntVector2(-20, -20);
return UIElement::ScreenToElement(screenPosition);
}
void ImGuiElement::SetRenderFunction(ImGuiRenderFunction* func)
{
renderFunction_ = func;
}
void ImGuiElement::AddTexture(intptr_t textureID, SharedPtr<Texture2D> texture)
{
textureTable_[textureID] = texture;
}
void ImGuiElement::RemoveTexture(intptr_t textureID)
{
textureTable_.Erase(textureID);
}
void ImGuiElement::CreateFontTexture(bool force)
{
ResourceCache* resCache = GetSubsystem<ResourceCache>();
ImGuiIO& io = ImGui::GetIO();
if (!force)
{
if (Texture2D* fontTexture = resCache->GetResource<Texture2D>(IMGUI_FONT_TEXTURE, false))
{
fontTexture_ = fontTexture;
io.Fonts->TexID = (void*)IMGUI_FONT_KEY;
textureTable_[IMGUI_FONT_KEY] = fontTexture_;
return;
}
}
// ?? what to do about fonts is a serious question?
ImFontConfig config;
config.OversampleH = 1; // horizontal oversampling blurs things quite badly
config.OversampleV = 1;
config.GlyphExtraSpacing.x = 1.0f;
config.SizePixels = fontSize_;
io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF("Data/Fonts/Anonymous Pro.ttf", fontSize_, &config);
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
SharedPtr<Image> img(new Image(context_));
img->SetSize(width, height, 4);
img->SetData(pixels);
SharedPtr<Texture2D> texture(new Texture2D(context_));
texture->SetName(IMGUI_FONT_TEXTURE);
texture->SetData(img, true);
texture->AddMetadata("FONT_SIZE", fontSize_);
resCache->AddManualResource(texture);
fontTexture_ = texture;
io.Fonts->TexID = (void*)IMGUI_FONT_KEY;
textureTable_[IMGUI_FONT_KEY] = fontTexture_;
}
void ImGuiElement::HandleDeviceReset(StringHash eventType, VariantMap& eventData)
{
if (fontTexture_ && fontTexture_->IsDataLost())
{
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
SharedPtr<Image> img(new Image(context_));
img->SetSize(width, height, 4);
img->SetData(pixels);
fontTexture_->SetData(img, true);
}
}
float ImGuiElement::GetAlphaMultiplier() const
{
ImGui::SetCurrentContext(imguiContext_);
return ImGui::GetStyle().Alpha;
}
void ImGuiElement::SetAlphaMultiplier(float value)
{
ImGui::SetCurrentContext(imguiContext_);
ImGui::GetStyle().Alpha = Clamp(value, 0.0f, 1.0f);
}
bool ImGuiElement::AntialiasEnabled() const
{
ImGui::SetCurrentContext(imguiContext_);
// always working with them together
return ImGui::GetStyle().AntiAliasedLines;
}
void ImGuiElement::SetAntialize(bool state)
{
ImGui::SetCurrentContext(imguiContext_);
ImGuiStyle& style = ImGui::GetStyle();
style.AntiAliasedFill = style.AntiAliasedLines = state;
}
Vector2 ImGuiElement::GetTouchPadding() const
{
ImGui::SetCurrentContext(imguiContext_);
ImGuiStyle& style = ImGui::GetStyle();
return Vector2(style.TouchExtraPadding.x, style.TouchExtraPadding.y);
}
void ImGuiElement::SetTouchPadding(const Vector2& extraPadding)
{
ImGui::SetCurrentContext(imguiContext_);
ImGui::GetStyle().TouchExtraPadding = ImVec2(extraPadding.x_, extraPadding.y_);
}
void ImGuiElement::SetFontSize(int newSize)
{
if (newSize == fontSize_)
return;
// never allow less than 8
// High DPIs tend to be ~150 ... extreme cases are ~200, 256 max leaves enough room for a 1-inch character
// beyond that it's really time to use font-scaling
fontSize_ = Clamp(newSize, 8, 256);
// Rebuild the font texture, if multiple instances of ImGuiElement are used this will mangle the others,
// due to shared font-texture being used with different font-data.
// If necessary append the element ID to the manual resource.
CreateFontTexture(true);
}
}
#pragma once
#include "../UI/UIElement.h"
struct ImGuiContext;
namespace Urho3D
{
URHO3D_EVENT(E_IMGUI_DRAW, IMGUIDraw)
{
URHO3D_PARAM(P_ELEMENT, Element); // UIElement pointer
URHO3D_PARAM(P_TIMESTEP, TimeStep); // float
}
class ImGuiElement;
typedef void(*ImGuiRenderFunction)(ImGuiElement* self);
/// Implements a fullscreen Dear ImGui context.
class URHO3D_API ImGuiElement : public UIElement
{
URHO3D_OBJECT(ImGuiElement, UIElement);
public:
/// Construct.
explicit ImGuiElement(Context* context);
/// Destruct.
~ImGuiElement();
/// Register object factory and properties.
static void RegisterObject(Context* context);
/// Updates and 'soft renders' the ImGui context.
virtual void Update(float timeStep) override;
/// Constructs UIBatches for rendering from the ImGuiContext's draw data.
virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor) override;
/// Records the text for use in the next update.
virtual void OnTextInput(const String& text) override;
/// Overriden for use in GetElementAt, as the ImGuiElement is fullscreen focus needs to be checked.
virtual IntVector2 ScreenToElement(const IntVector2& screenPosition);
/// Sets an external rendering function to be called for running ImGui commands. Function will be called from Update.
void SetRenderFunction(ImGuiRenderFunction* func);
/// Add a texture for referencing within ImGui.
void AddTexture(intptr_t textureID, SharedPtr<Texture2D> texture);
/// Remove a texture from the table.
void RemoveTexture(intptr_t textureID);
/// Returns the factor by which all alpha transparency is multiplied.
float GetAlphaMultiplier() const;
/// Returns true if antialiasing of lines and fill is active.
bool AntialiasEnabled() const;
/// Returns the extra padding around controls for easier touch interaction.
Vector2 GetTouchPadding() const;
/// Returns true if the ImGui debugging window is visible.
inline bool IsMetricsWindowVisible() const { return showMetrics_; }
/// Returns true if the ImGui standard demo is visible.
inline bool IsDemoWindowVisible() const { return showDemo_; }
/// Sets the global alpha multiplier.
void SetAlphaMultiplier(float value);
/// Activates or deactivates antialiasing of fill and lines.
void SetAntialize(bool state);
/// Sets the extra padding around controls for touch interaction.
void SetTouchPadding(const Vector2& extraPadding);
/// Sets the visibility of the ImGui debug window for tracking draws.
void SetMetricsWindowVisible(bool state) { showMetrics_ = state; }
/// Sets the visibility of the demo window, this is useful for tracking down widgets/layout.
void SetDemoWindowVisible(bool state) { showDemo_ = state; }
inline int GetFontSize() const { return fontSize_; }
void SetFontSize(int size);
protected:
/// Alternatively to set the ImGuiRenderFunction pointer this method can be overriden for generating the UI.
virtual void RenderImGui() { }
/// Creates or acquires the font texture.
void CreateFontTexture(bool force = false);
private:
/// Rebuilds the font texture when necessary.
void HandleDeviceReset(StringHash eventType, VariantMap& eventData);
/// Last text received from OnTextInput.
String lastText_;
/// ImGuiContext for this particular instance.
ImGuiContext* imguiContext_;
/// Optional GUI rendering function to use.
ImGuiRenderFunction* renderFunction_;
/// Table of IDs to textures for drawing textures/render-target in Dear ImGui.
HashMap<intptr_t, SharedPtr<Texture2D> > textureTable_;
/// Stored font texture.
SharedPtr<Texture2D> fontTexture_;
/// Pixel height for font size.
int fontSize_ = 20;
/// Whether to show the debug window or not.
bool showMetrics_ = false;
/// Whether to show the standard ImGui demo or not.
bool showDemo_ = false;
};
}
set(TARGET_NAME imgui)
define_source_files ()
setup_library ()
install_header_files (DIRECTORY ./ DESTINATION ${DEST_INCLUDE_DIR}/ThirdParty/ImGui FILES_MATCHING PATTERN *.h BUILD_TREE_ONLY) # Note: the trailing slash is significant
static void RegisterImgui(asIScriptEngine* engine)
{
RegisterUIElement<ImGuiElement>(engine, "ImGuiElement", false);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment