Skip to content

Instantly share code, notes, and snippets.

@hb3p8
Created November 4, 2020 18:54
Show Gist options
  • Save hb3p8/b660b0ee868c45790a04cac1f46a91ac to your computer and use it in GitHub Desktop.
Save hb3p8/b660b0ee868c45790a04cac1f46a91ac to your computer and use it in GitHub Desktop.
// 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