This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// CC0 | |
#define IMGUI_DEFINE_MATH_OPERATORS | |
#include <imgui_internal.h> | |
#define isdigit(c) (c >= '0' && c <= '9') | |
namespace ImGui | |
{ | |
float strToFloat (const char *s) // atof from minilibc | |
{ | |
float a = 0.0; | |
bool neg = false; | |
int e = 0; | |
int c; | |
if (*s == '-') | |
{ | |
neg = true; | |
++s; | |
} | |
while ((c = *s++) != '\0' && c != ' ' && isdigit(c)) { | |
a = a*10.0f + (c - '0'); | |
} | |
if (c == '.') { | |
while ((c = *s++) != '\0' && c != ' ' && isdigit(c)) { | |
a = a*10.0f + (c - '0'); | |
e = e-1; | |
} | |
} | |
while (e < 0) { | |
a *= 0.1f; | |
e++; | |
} | |
return neg ? -a : a; | |
} | |
int tokenlLength (const char* str) | |
{ | |
const char* c = str; | |
for (; c - str < 16; ++c) | |
{ | |
if (*c == ' ' || *c == '\0' ) | |
{ | |
return int(c - str); | |
} | |
} | |
return 16; | |
} | |
void DrawCmdList (ImDrawList* theDrawList, const ImVec2 thePivot, const char* theCmdList, const ImU32 theColor) | |
{ | |
enum class State | |
{ | |
None, | |
RectFilled, // r left top right bottom | |
Line, // l thickness p0.x p0.y p1.x p1.y | |
}; | |
State state = State::None; | |
float cmdArgs[8] = {}; | |
int cmdArgNum = 0; | |
const char* c = theCmdList; | |
while (*c) | |
{ | |
switch (*c) | |
{ | |
case ';': // execute command | |
{ | |
switch (state) | |
{ | |
case State::RectFilled: | |
{ | |
theDrawList->AddRectFilled (thePivot + ImVec2 (cmdArgs[0], cmdArgs[1]), | |
thePivot + ImVec2 (cmdArgs[2], cmdArgs[3]), theColor); | |
break; | |
} | |
case State::Line: | |
{ | |
theDrawList->AddLine (thePivot + ImVec2 (cmdArgs[1], cmdArgs[2]), | |
thePivot + ImVec2 (cmdArgs[3], cmdArgs[4]), theColor, cmdArgs[0]); | |
break; | |
} | |
default: | |
break; | |
} | |
state = State::None; | |
break; | |
} | |
case 'r': | |
{ | |
state = State::RectFilled; | |
cmdArgNum = 0; | |
break; | |
} | |
case 'l': | |
{ | |
state = State::Line; | |
cmdArgNum = 0; | |
break; | |
} | |
default: | |
{ | |
cmdArgs[cmdArgNum++ % 8] = strToFloat (c); | |
break; | |
} | |
} | |
c += tokenlLength (c) + 1; // next cmd | |
} | |
} | |
// Demo widget using DrawCmdList | |
bool CircleVectorButton (const char* theID, const float theRadius, const char* theCmdList) | |
{ | |
ImGuiWindow* window = ImGui::GetCurrentWindow(); | |
if (window->SkipItems) | |
return false; | |
const ImGuiID id = window->GetID (theID); | |
const ImVec2 size (theRadius * 2, theRadius * 2); | |
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); | |
const ImRect image_bb(window->DC.CursorPos, window->DC.CursorPos + size); | |
ImGui::ItemSize(bb); | |
if (!ImGui::ItemAdd(bb, id)) | |
return false; | |
bool hovered, held; | |
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held); | |
// Render | |
const ImU32 col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); | |
window->DrawList->AddCircleFilled (bb.Min + ImVec2 (theRadius, theRadius), theRadius, col, 24); | |
DrawCmdList (window->DrawList, bb.GetCenter(), theCmdList, ImGui::GetColorU32 (ImGuiCol_Text)); | |
return pressed; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment