mirror of
https://github.com/Nexoniarz/Fry3DX.git
synced 2026-11-03 04:24:26 +00:00
242 lines
12 KiB
C++
242 lines
12 KiB
C++
#include "icons.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <initializer_list>
|
|
#include <utility>
|
|
|
|
namespace fry {
|
|
|
|
void drawIcon(ImDrawList* dl, Icon icon, ImVec2 o, float s, ImU32 c) {
|
|
auto P = [&](float x, float y) { return ImVec2(o.x + x * s, o.y + y * s); };
|
|
const float t = std::max(1.5f, s * 0.07f);
|
|
const ImU32 dim = (c & 0x00FFFFFF) | 0x60000000;
|
|
auto line = [&](float x0, float y0, float x1, float y1, float w = 0) { dl->AddLine(P(x0, y0), P(x1, y1), c, w > 0 ? w : t); };
|
|
auto tri = [&](float x0, float y0, float x1, float y1, float x2, float y2) { dl->AddTriangleFilled(P(x0, y0), P(x1, y1), P(x2, y2), c); };
|
|
auto quad = [&](float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, bool fill, ImU32 col) {
|
|
if (fill) dl->AddQuadFilled(P(x0, y0), P(x1, y1), P(x2, y2), P(x3, y3), col);
|
|
else dl->AddQuad(P(x0, y0), P(x1, y1), P(x2, y2), P(x3, y3), col, t);
|
|
};
|
|
auto dot = [&](float x, float y, float r) { dl->AddCircleFilled(P(x, y), r * s, c); };
|
|
switch (icon) {
|
|
case Icon::Select: {
|
|
const ImVec2 pts[] = {P(0.28f, 0.14f), P(0.28f, 0.80f), P(0.44f, 0.65f), P(0.56f, 0.88f), P(0.66f, 0.83f), P(0.55f, 0.60f), P(0.76f, 0.60f)};
|
|
dl->AddConcavePolyFilled(pts, 7, c);
|
|
break;
|
|
}
|
|
case Icon::Move:
|
|
line(0.5f, 0.2f, 0.5f, 0.8f), line(0.2f, 0.5f, 0.8f, 0.5f);
|
|
tri(0.5f, 0.08f, 0.38f, 0.24f, 0.62f, 0.24f), tri(0.5f, 0.92f, 0.38f, 0.76f, 0.62f, 0.76f);
|
|
tri(0.08f, 0.5f, 0.24f, 0.38f, 0.24f, 0.62f), tri(0.92f, 0.5f, 0.76f, 0.38f, 0.76f, 0.62f);
|
|
break;
|
|
case Icon::Rotate:
|
|
dl->PathArcTo(P(0.5f, 0.52f), 0.30f * s, 3.14159f * 0.15f, 3.14159f * 1.75f, 24);
|
|
dl->PathStroke(c, 0, t * 1.2f);
|
|
tri(0.80f, 0.18f, 0.86f, 0.46f, 0.60f, 0.36f);
|
|
break;
|
|
case Icon::Scale:
|
|
dl->AddRect(P(0.16f, 0.16f), P(0.84f, 0.84f), dim, 0, 0, t);
|
|
dl->AddRectFilled(P(0.16f, 0.56f), P(0.44f, 0.84f), c);
|
|
line(0.44f, 0.56f, 0.76f, 0.24f);
|
|
tri(0.84f, 0.16f, 0.62f, 0.22f, 0.78f, 0.38f);
|
|
break;
|
|
case Icon::Draw: {
|
|
const ImVec2 pts[] = {P(0.18f, 0.78f), P(0.30f, 0.26f), P(0.62f, 0.18f), P(0.82f, 0.50f), P(0.60f, 0.82f)};
|
|
dl->AddPolyline(pts, 5, c, ImDrawFlags_Closed, t);
|
|
for (const ImVec2& p : pts) dl->AddCircleFilled(p, 0.07f * s, c);
|
|
break;
|
|
}
|
|
case Icon::Extrude:
|
|
quad(0.14f, 0.70f, 0.56f, 0.70f, 0.86f, 0.52f, 0.44f, 0.52f, true, dim);
|
|
quad(0.14f, 0.42f, 0.56f, 0.42f, 0.86f, 0.24f, 0.44f, 0.24f, false, c);
|
|
line(0.50f, 0.62f, 0.50f, 0.36f), tri(0.50f, 0.10f, 0.40f, 0.30f, 0.60f, 0.30f);
|
|
break;
|
|
case Icon::Inset:
|
|
dl->AddRect(P(0.14f, 0.14f), P(0.86f, 0.86f), c, 0, 0, t);
|
|
dl->AddRectFilled(P(0.34f, 0.34f), P(0.66f, 0.66f), c);
|
|
line(0.14f, 0.14f, 0.34f, 0.34f, t * 0.6f), line(0.86f, 0.14f, 0.66f, 0.34f, t * 0.6f);
|
|
line(0.14f, 0.86f, 0.34f, 0.66f, t * 0.6f), line(0.86f, 0.86f, 0.66f, 0.66f, t * 0.6f);
|
|
break;
|
|
case Icon::Bevel:
|
|
dl->PathLineTo(P(0.16f, 0.86f));
|
|
dl->PathLineTo(P(0.16f, 0.16f));
|
|
dl->PathLineTo(P(0.40f, 0.16f));
|
|
dl->PathArcTo(P(0.40f, 0.60f), 0.44f * s, -3.14159f * 0.5f, 0.0f, 16);
|
|
dl->PathLineTo(P(0.84f, 0.86f));
|
|
dl->PathFillConvex(dim);
|
|
dl->PathLineTo(P(0.40f, 0.16f));
|
|
dl->PathArcTo(P(0.40f, 0.60f), 0.44f * s, -3.14159f * 0.5f, 0.0f, 16);
|
|
dl->PathStroke(c, 0, t * 1.4f);
|
|
break;
|
|
case Icon::LoopCut:
|
|
dl->AddRect(P(0.12f, 0.22f), P(0.88f, 0.78f), dim, 0, 0, t);
|
|
line(0.12f, 0.50f, 0.88f, 0.50f, t * 0.6f);
|
|
line(0.50f, 0.10f, 0.50f, 0.90f, t * 1.4f);
|
|
break;
|
|
case Icon::Objects:
|
|
case Icon::Shape:
|
|
quad(0.5f, 0.12f, 0.86f, 0.30f, 0.5f, 0.48f, 0.14f, 0.30f, icon == Icon::Objects, icon == Icon::Objects ? c : dim);
|
|
quad(0.14f, 0.30f, 0.5f, 0.48f, 0.5f, 0.88f, 0.14f, 0.70f, icon == Icon::Objects, icon == Icon::Objects ? dim : dim);
|
|
quad(0.86f, 0.30f, 0.5f, 0.48f, 0.5f, 0.88f, 0.86f, 0.70f, false, c);
|
|
if (icon == Icon::Shape)
|
|
for (auto [x, y] : {std::pair{0.5f, 0.12f}, {0.86f, 0.30f}, {0.5f, 0.48f}, {0.14f, 0.30f}, {0.14f, 0.70f}, {0.5f, 0.88f}, {0.86f, 0.70f}}) dot(x, y, 0.07f);
|
|
break;
|
|
case Icon::Points:
|
|
case Icon::Edges:
|
|
case Icon::Faces:
|
|
if (icon == Icon::Faces) dl->AddRectFilled(P(0.2f, 0.2f), P(0.8f, 0.8f), c);
|
|
dl->AddRect(P(0.2f, 0.2f), P(0.8f, 0.8f), icon == Icon::Faces ? c : dim, 0, 0, t);
|
|
if (icon == Icon::Edges) line(0.2f, 0.2f, 0.8f, 0.2f, t * 2.2f), line(0.8f, 0.2f, 0.8f, 0.8f, t * 2.2f);
|
|
if (icon == Icon::Points)
|
|
for (auto [x, y] : {std::pair{0.2f, 0.2f}, {0.8f, 0.2f}, {0.8f, 0.8f}, {0.2f, 0.8f}}) dot(x, y, 0.11f);
|
|
break;
|
|
case Icon::Box:
|
|
for (int i = 0; i < 4; ++i) { // dashed
|
|
const float a = 0.16f + float(i) * 0.18f, b = a + 0.1f;
|
|
line(a, 0.18f, b, 0.18f), line(a, 0.82f, b, 0.82f), line(0.16f, a + 0.02f, 0.16f, b + 0.02f), line(0.84f, a + 0.02f, 0.84f, b + 0.02f);
|
|
}
|
|
break;
|
|
case Icon::Brush:
|
|
dl->AddCircle(P(0.5f, 0.5f), 0.32f * s, c, 24, t);
|
|
dot(0.5f, 0.5f, 0.07f);
|
|
break;
|
|
case Icon::Lasso: {
|
|
dl->PathArcTo(P(0.52f, 0.40f), 0.30f * s, 0.0f, 6.2832f, 24);
|
|
dl->PathStroke(c, ImDrawFlags_Closed, t);
|
|
line(0.32f, 0.62f, 0.26f, 0.88f);
|
|
break;
|
|
}
|
|
case Icon::Add:
|
|
line(0.5f, 0.18f, 0.5f, 0.82f, t * 1.6f), line(0.18f, 0.5f, 0.82f, 0.5f, t * 1.6f);
|
|
break;
|
|
case Icon::Knife: {
|
|
const ImVec2 blade[] = {P(0.10f, 0.90f), P(0.56f, 0.30f), P(0.70f, 0.44f)};
|
|
dl->AddTriangleFilled(blade[0], blade[1], blade[2], c);
|
|
line(0.66f, 0.38f, 0.88f, 0.14f, t * 2.4f);
|
|
line(0.14f, 0.62f, 0.34f, 0.62f, t * 0.6f), line(0.06f, 0.74f, 0.22f, 0.74f, t * 0.6f); // (the cut)
|
|
break;
|
|
}
|
|
case Icon::Hole:
|
|
dl->AddRect(P(0.12f, 0.12f), P(0.88f, 0.88f), dim, 0, 0, t);
|
|
dl->AddCircleFilled(P(0.5f, 0.5f), 0.26f * s, (c & 0x00FFFFFF) | 0x40000000, 24);
|
|
dl->AddCircle(P(0.5f, 0.5f), 0.26f * s, c, 24, t * 1.2f);
|
|
dl->PathArcTo(P(0.5f, 0.5f), 0.18f * s, 3.14159f * 0.15f, 3.14159f * 0.85f, 12);
|
|
dl->PathStroke(c, 0, t * 0.7f);
|
|
break;
|
|
case Icon::PaintBrush:
|
|
line(0.84f, 0.14f, 0.46f, 0.52f, t * 1.6f);
|
|
dl->AddQuadFilled(P(0.40f, 0.48f), P(0.52f, 0.60f), P(0.36f, 0.80f), P(0.22f, 0.66f), c);
|
|
dl->AddTriangleFilled(P(0.22f, 0.66f), P(0.36f, 0.80f), P(0.10f, 0.90f), c);
|
|
break;
|
|
case Icon::Eraser:
|
|
quad(0.16f, 0.62f, 0.50f, 0.28f, 0.82f, 0.60f, 0.48f, 0.94f, false, c);
|
|
quad(0.16f, 0.62f, 0.33f, 0.45f, 0.65f, 0.77f, 0.48f, 0.94f, true, c);
|
|
break;
|
|
case Icon::Fill:
|
|
quad(0.16f, 0.46f, 0.46f, 0.16f, 0.76f, 0.46f, 0.46f, 0.76f, false, c);
|
|
quad(0.16f, 0.46f, 0.76f, 0.46f, 0.61f, 0.61f, 0.31f, 0.61f, true, dim);
|
|
dot(0.84f, 0.74f, 0.08f), tri(0.84f, 0.52f, 0.77f, 0.72f, 0.91f, 0.72f);
|
|
break;
|
|
case Icon::Picker:
|
|
line(0.18f, 0.82f, 0.60f, 0.40f, t * 1.6f);
|
|
line(0.50f, 0.36f, 0.64f, 0.50f, t * 1.6f);
|
|
dot(0.72f, 0.28f, 0.13f);
|
|
dot(0.16f, 0.84f, 0.05f);
|
|
break;
|
|
case Icon::Picture:
|
|
dl->AddRect(P(0.10f, 0.18f), P(0.90f, 0.82f), c, 0, 0, t);
|
|
tri(0.16f, 0.76f, 0.40f, 0.40f, 0.62f, 0.76f), tri(0.46f, 0.76f, 0.66f, 0.52f, 0.84f, 0.76f);
|
|
dot(0.70f, 0.34f, 0.07f);
|
|
break;
|
|
case Icon::Render:
|
|
dl->AddRect(P(0.10f, 0.32f), P(0.90f, 0.82f), c, 0.08f * s, 0, t);
|
|
dl->AddRectFilled(P(0.30f, 0.20f), P(0.54f, 0.33f), c);
|
|
dl->AddCircle(P(0.5f, 0.57f), 0.16f * s, c, 20, t);
|
|
dot(0.78f, 0.42f, 0.04f);
|
|
break;
|
|
case Icon::Layout: // (a frame unfolded: a cross of squares)
|
|
dl->AddRect(P(0.38f, 0.10f), P(0.62f, 0.34f), c, 0, 0, t);
|
|
dl->AddRect(P(0.14f, 0.34f), P(0.86f, 0.58f), c, 0, 0, t);
|
|
dl->AddRect(P(0.38f, 0.58f), P(0.62f, 0.90f), c, 0, 0, t);
|
|
line(0.38f, 0.34f, 0.38f, 0.58f), line(0.62f, 0.34f, 0.62f, 0.58f);
|
|
break;
|
|
case Icon::Print: // (a nozzle over what it's printed)
|
|
quad(0.34f, 0.10f, 0.66f, 0.10f, 0.66f, 0.30f, 0.34f, 0.30f, true, c);
|
|
tri(0.40f, 0.30f, 0.60f, 0.30f, 0.50f, 0.44f);
|
|
for (int i = 0; i < 3; ++i) dl->AddRectFilled(P(0.22f + 0.04f * float(i), 0.56f + 0.11f * float(i)), P(0.78f - 0.04f * float(i), 0.64f + 0.11f * float(i)), i ? dim : c);
|
|
line(0.10f, 0.90f, 0.90f, 0.90f);
|
|
break;
|
|
case Icon::Ruler: {
|
|
quad(0.08f, 0.66f, 0.66f, 0.08f, 0.92f, 0.34f, 0.34f, 0.92f, false, c);
|
|
for (int i = 1; i < 6; ++i) {
|
|
const float k = float(i) / 6.0f, x = 0.08f + 0.58f * k, y = 0.66f - 0.58f * k, l = i % 2 ? 0.09f : 0.15f;
|
|
line(x, y, x + l, y + l, t * 0.8f);
|
|
}
|
|
break;
|
|
}
|
|
// Sculpting: a line of surface, and what the brush does to it.
|
|
case Icon::Sculpt: { // a bump raised, an arrow up out of it
|
|
const ImVec2 pts[] = {P(0.08f, 0.80f), P(0.30f, 0.78f), P(0.42f, 0.58f), P(0.58f, 0.58f), P(0.70f, 0.78f), P(0.92f, 0.80f)};
|
|
dl->AddPolyline(pts, 6, c, 0, t * 1.2f);
|
|
line(0.5f, 0.48f, 0.5f, 0.24f), tri(0.5f, 0.08f, 0.38f, 0.26f, 0.62f, 0.26f);
|
|
break;
|
|
}
|
|
case Icon::Inflate:
|
|
dl->AddCircle(P(0.5f, 0.5f), 0.2f * s, c, 24, t);
|
|
for (int i = 0; i < 4; ++i) {
|
|
const float a = 0.785f + 1.5708f * float(i), x = std::cos(a), y = std::sin(a);
|
|
line(0.5f + x * 0.28f, 0.5f + y * 0.28f, 0.5f + x * 0.42f, 0.5f + y * 0.42f);
|
|
}
|
|
break;
|
|
case Icon::Smooth: { // bumps above, evened out below
|
|
ImVec2 pts[9];
|
|
for (int i = 0; i < 9; ++i) pts[i] = P(0.1f + 0.1f * float(i), 0.3f + (i % 2 ? -0.1f : 0.08f));
|
|
dl->AddPolyline(pts, 9, dim, 0, t);
|
|
dl->PathArcTo(P(0.5f, 1.25f), 0.62f * s, 3.14159f * 1.2f, 3.14159f * 1.8f, 20);
|
|
dl->PathStroke(c, 0, t * 1.2f);
|
|
break;
|
|
}
|
|
case Icon::Flatten: // a bump pressed flat by a bar
|
|
dl->AddRectFilled(P(0.2f, 0.18f), P(0.8f, 0.32f), c, 0.04f * s);
|
|
line(0.5f, 0.36f, 0.5f, 0.5f), tri(0.5f, 0.62f, 0.4f, 0.48f, 0.6f, 0.48f);
|
|
line(0.08f, 0.78f, 0.92f, 0.78f, t * 1.2f);
|
|
break;
|
|
case Icon::Pinch: // two sides pulled in to a crease
|
|
line(0.08f, 0.5f, 0.34f, 0.5f), tri(0.46f, 0.5f, 0.32f, 0.4f, 0.32f, 0.6f);
|
|
line(0.92f, 0.5f, 0.66f, 0.5f), tri(0.54f, 0.5f, 0.68f, 0.4f, 0.68f, 0.6f);
|
|
line(0.5f, 0.2f, 0.5f, 0.8f, t * 0.7f);
|
|
break;
|
|
case Icon::Grab: { // a patch of surface pulled up and over
|
|
const ImVec2 pts[] = {P(0.08f, 0.82f), P(0.32f, 0.80f), P(0.46f, 0.50f), P(0.62f, 0.34f), P(0.72f, 0.80f), P(0.92f, 0.82f)};
|
|
dl->AddPolyline(pts, 6, c, 0, t * 1.2f);
|
|
dot(0.62f, 0.34f, 0.08f);
|
|
line(0.62f, 0.34f, 0.84f, 0.16f, t * 0.8f), tri(0.92f, 0.08f, 0.78f, 0.12f, 0.88f, 0.22f);
|
|
break;
|
|
}
|
|
case Icon::Eye: case Icon::EyeShut: // an eye: open, or shut with its lashes
|
|
if (icon == Icon::Eye) {
|
|
dl->AddBezierQuadratic(P(0.04f, 0.5f), P(0.5f, 0.02f), P(0.96f, 0.5f), c, t);
|
|
dl->AddBezierQuadratic(P(0.04f, 0.5f), P(0.5f, 0.98f), P(0.96f, 0.5f), c, t);
|
|
dot(0.5f, 0.5f, 0.15f);
|
|
} else {
|
|
dl->AddBezierQuadratic(P(0.04f, 0.42f), P(0.5f, 0.86f), P(0.96f, 0.42f), c, t);
|
|
line(0.26f, 0.60f, 0.18f, 0.76f), line(0.5f, 0.66f, 0.5f, 0.84f), line(0.74f, 0.60f, 0.82f, 0.76f);
|
|
}
|
|
break;
|
|
case Icon::Lock: case Icon::Unlock: { // a padlock: the shackle down in it, or up and open
|
|
dl->AddRectFilled(P(0.24f, 0.46f), P(0.76f, 0.88f), c, s * 0.08f);
|
|
const float lift = icon == Icon::Unlock ? 0.12f : 0.0f;
|
|
dl->PathArcTo(P(0.5f, 0.38f - lift), 0.17f * s, 3.14159f, 3.14159f * 2.0f, 12);
|
|
dl->PathStroke(c, 0, t);
|
|
line(0.33f, 0.38f - lift, 0.33f, 0.47f - (lift > 0 ? lift : 0)), line(0.67f, 0.38f - lift, 0.67f, 0.47f);
|
|
break;
|
|
}
|
|
case Icon::LayFlat:
|
|
quad(0.22f, 0.40f, 0.62f, 0.22f, 0.86f, 0.50f, 0.46f, 0.68f, false, c);
|
|
line(0.10f, 0.88f, 0.90f, 0.88f);
|
|
line(0.54f, 0.06f, 0.54f, 0.30f), tri(0.54f, 0.36f, 0.46f, 0.24f, 0.62f, 0.24f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
} // namespace fry
|