#include <thread>
#include <chrono>
#include <cmath>

#define IM_ASSERT(_EXPR) assert(_EXPR)
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR))))

FLinearColor 浅蓝 = FLinearColor(36 / 255.f, 249 / 255.f, 217 / 255.f, 255 / 255.f);
FLinearColor 蓝色 = FLinearColor(170 / 255.f, 203 / 255.f, 244 / 255.f, 0.75f);
FLinearColor 白色 = FLinearColor(255 / 255.f, 255 / 255.f, 255 / 255.f, 1.0f);
FLinearColor 浅粉 = FLinearColor(255 / 255.f, 200 / 255.f, 250 / 255.f, 0.95f);
FLinearColor 黑色 = FLinearColor(0 / 255.f, 0 / 255.f, 0 / 255.f, 1.0f);
FLinearColor 灰色 = FLinearColor(0 / 255.f, 0 / 255.f, 0 / 255.f, 0.18f);
FLinearColor 血色 = FLinearColor(0 / 255.f, 249 / 255.f, 0 / 255.f, 0.35f);
FLinearColor 红色 = FLinearColor(255 / 255.f, 000 / 255.f, 000 / 255.f, 0.95f);
FLinearColor 绿色 = FLinearColor(50 / 255.f, 222 / 215.f, 50 / 255.f, 0.55f);
FLinearColor 黄色 = FLinearColor(255 / 255.f, 255 / 255.f, 0 / 255.f, 0.95f);
FLinearColor 橘黄 = FLinearColor(255 / 255.f, 150 / 255.f, 30 / 255.f, 0.95f);
FLinearColor 粉红 = FLinearColor(220 / 255.f, 108 / 255.f, 1202 / 255.f, 0.95f);
FLinearColor 紫色 = FLinearColor(169 / 255.f, 120 / 255.f, 223 / 255.f, 0.95f);
FLinearColor 暗红 = FLinearColor(149 / 255.f, 10 / 255.f, 10 / 255.f, 0.95f);
FLinearColor 青绿 = FLinearColor(145 / 255.f, 232 / 255.f, 135 / 255.f, 255 / 255.f);

static UFont* robotoFont = 0;

UTexture2D* BG;
ASTExtraPlayerCharacter* g_LocalPlayer = 0;
ASTExtraPlayerController* g_PlayerController = 0;
void (*K2_DrawLineUI)(void* Canvas, FVector2D ScreenPositionA, FVector2D ScreenPositionB, float Thickness, FLinearColor RenderColor);
void (*K2_DrawTextUI)(void* Canvas, void* RenderFont, const FString & Text, FVector2D ScreenPosition, FLinearColor RenderColor, float Kerning, FLinearColor ShadowColor, FVector2D ShadowOffset, bool bCentreX, bool bCentreY, bool bOutlined, FLinearColor OutlineColor);
typedef unsigned char BYTE;
typedef uint32_t UINT32;
bool KeyCtrl;
bool KeyShift;
bool KeyAlt;
bool KeySuper;
static std::map<int32_t, std::queue<int32_t>> g_KeyEventQueues;

void DrawOutlinedText(UCanvas* Canvas, FString Text, FVector2D Pos, FLinearColor Color, FLinearColor OutlineColor, bool isCenter = false)
{
    Canvas->K2_DrawText(robotoFont, Text, Pos, Color, 1.f, {}, {}, isCenter, isCenter, true, OutlineColor);
}

void DrawLine(UCanvas* Canvas, FVector2D posFrom, FVector2D posTo, float Thickness, FLinearColor Color) {
    Canvas->K2_DrawLine({ posFrom.X, posFrom.Y }, { posTo.X, posTo.Y }, Thickness, Color);
}

void DrawBox(UCanvas* Canvas, FVector2D Pos, FVector2D size, FLinearColor Color) {
    Canvas->K2_DrawTexture(BG, Pos, size, {}, {}, Color, EBlendMode::BLEND_Translucent, 0, {});
}

void DrawText(UCanvas* Canvas, FString Text, FVector2D Pos, FLinearColor Color, FLinearColor OutlineColor, int FontSize, bool isCenter) {
    robotoFont->LegacyFontSize = FontSize;
    Canvas->K2_DrawText(robotoFont, Text, Pos, Color, 1.f, {}, {}, isCenter, false, true, OutlineColor);
    robotoFont->LegacyFontSize = 13;
}

void DrawFilledRect(UCanvas* Canvas, FVector2D initial_pos, float w, float h, FLinearColor Color)
{
    DrawBox(Canvas,initial_pos, {w,h}, Color);
}

void DrawRectangle(UCanvas* Canvas, FVector2D Pos, float Width, float Height, float Thickness, FLinearColor Color) {
    Canvas->K2_DrawLine(FVector2D(Pos.X, Pos.Y), FVector2D(Pos.X + Width, Pos.Y), Thickness, Color);
    Canvas->K2_DrawLine(FVector2D(Pos.X, Pos.Y), FVector2D(Pos.X, Pos.Y + Height), Thickness, Color);
    Canvas->K2_DrawLine(FVector2D(Pos.X + Width, Pos.Y), FVector2D(Pos.X + Width, Pos.Y + Height), Thickness, Color);
    Canvas->K2_DrawLine(FVector2D(Pos.X, Pos.Y + Height), FVector2D(Pos.X + Width, Pos.Y + Height), Thickness, Color);
}

void DrawArc(UCanvas* Canvas, float centerX, float centerY, float radius, float startAngle, float endAngle, FLinearColor Color, float Thickness) {
    int segments = 64;
    std::vector<FVector2D> points;
    for (int i = 0; i <= segments; ++i) {
        float angle = startAngle + (endAngle - startAngle) * i / segments;
        float x = centerX + radius * cos(angle);
        float y = centerY + radius * sin(angle);
        points.push_back(FVector2D(x, y));
    }
    for (size_t i = 1; i < points.size(); ++i) {
        Canvas->K2_DrawLine(points[i - 1], points[i], Thickness, Color);
    }
}

void DrawTexture(UCanvas* Canvas, UTexture2D* TextureToRender, FVector2D SceenPos, FVector2D SceenSize, FLinearColor Color, float Rotation)
{
    Canvas->K2_DrawTexture(TextureToRender, SceenPos, SceenSize, { 0,0 }, FVector2D{ 1,1 }, Color, EBlendMode::BLEND_Translucent, Rotation, {});
}

void DrawFilledCircle(UCanvas* Canvas, FVector2D pos, float r, FLinearColor color)
{
    for (float y = -r; y <= r; y += 1.0f)
    {
        float x_half_width = sqrtf(r * r - y * y);
        Canvas->K2_DrawLine(
            FVector2D{ pos.X - x_half_width, pos.Y + y },
            FVector2D{ pos.X + x_half_width, pos.Y + y },
            1.0f,
            color
        );
    }
}

void DrawFilledRectByLine(UCanvas* Canvas, FVector2D initial_pos, float w, float h, FLinearColor Color)
{
    for (float i = 0.f; i < h; i += 1.f)
        Canvas->K2_DrawLine(FVector2D(initial_pos.X, initial_pos.Y + i), 
                            FVector2D(initial_pos.X + w, initial_pos.Y + i), 
                            1.0f, Color);
}

void 绘制圆角矩形(UCanvas* Canvas, FVector2D pos, float w, float h, float r, FLinearColor color)
{
    ::DrawFilledCircle(Canvas, FVector2D{ pos.X + r, pos.Y + r }, r, color);
    ::DrawFilledCircle(Canvas, FVector2D{ pos.X + w - r, pos.Y + r }, r, color);
    ::DrawFilledCircle(Canvas, FVector2D{ pos.X + w - r, pos.Y + h - r }, r, color);
    ::DrawFilledCircle(Canvas, FVector2D{ pos.X + r, pos.Y + h - r }, r, color);
    ::DrawFilledRectByLine(Canvas, FVector2D{ pos.X, pos.Y + r }, w, h - r * 2, color);
    ::DrawFilledRectByLine(Canvas, FVector2D{ pos.X + r, pos.Y }, w - r * 2, r, color);
    ::DrawFilledRectByLine(Canvas, FVector2D{ pos.X + r, pos.Y + h - r }, w - r * 2, r + 1, color);
}

void DrawTextNoOutline(UCanvas* Canvas, FString Text, FVector2D Pos, FLinearColor Color, int FontSize, bool isCenter = false)
{
    robotoFont->LegacyFontSize = FontSize;
    Canvas->K2_DrawText(robotoFont,Text,Pos,Color,1.f,FLinearColor(),{},isCenter,isCenter,false,FLinearColor(0, 0, 0, 0));
    robotoFont->LegacyFontSize = 13;
}

void DrawHexagonStar(float x, float y, float radius, float DeltaTime, FLinearColor color) {
    const int numPoints = 6;
    FVector2D center(x, y);
    FVector2D points[numPoints];
    for (int i = 0; i < numPoints; i++) {
        float angle = DeltaTime + 2 * M_PI * i / numPoints;
        points[i] = FVector2D(center.X + radius * cos(angle), center.Y + radius * sin(angle));
    }
}

void 绘制旋转六芒星(float x, float y, float DeltaTime) {
    static float rotationAngle = 0;
    rotationAngle += DeltaTime * 0.5f;
    float radius = 35;
    FLinearColor color(蓝色);
    DrawHexagonStar(x, y, radius, rotationAngle, color);
}

void DrawCircle(UCanvas* Canvas, float x, float y, float radius, int numsides, FLinearColor OutlineColor) {
    float Step = M_PI * 2.0 / numsides;
    int Count = 0;
    FVector2D V[128];
    for (float a = 0; a < M_PI * 2.0; a += Step)
    {
        float X1 = radius * cos(a) + x;
        float Y1 = radius * sin(a) + y;
        float X2 = radius * cos(a + Step) + x;
        float Y2 = radius * sin(a + Step) + y;
        V[Count].X = X1;
        V[Count].Y = Y1;
        V[Count + 1].X = X2;
        V[Count + 1].Y = Y2;
        Canvas->K2_DrawLine(FVector2D(V[Count].X, V[Count].Y), FVector2D(X2, Y2), 1.f, OutlineColor);
    }
}

void DrawCircleM(UCanvas *Canvas, int x, int y, int radius, FLinearColor OutlineColor){
    float Step = 2.0f * M_PI / (float)radius;
    int Count = 0;
    FVector2D V[128];
    for (float a = 0; a < M_PI * 2.0; a += Step)
    {
        float X1 = radius * cos(a) + x;
        float Y1 = radius * sin(a) + y;
        float X2 = radius * cos(a + Step) + x;
        float Y2 = radius * sin(a + Step) + y;
        V[Count].X = X1;
        V[Count].Y = Y1;
        V[Count + 1].X = X2;
        V[Count + 1].Y = Y2;
        K2_DrawLineUI(Canvas,FVector2D({V[Count].X, V[Count].Y}), FVector2D({ X2, Y2 }), 1.0f, OutlineColor);
    }
}

FVector RotateCorner(FVector origin, FVector corner, float theta)
{
    float x = corner.X - origin.X;
    float y = corner.Y - origin.Y;
    return { origin.X + (x * cos(theta) - y * sin(theta)), origin.Y + (x * sin(theta) + y * cos(theta)), corner.Z };
}

void FillTriangle(UCanvas* Canvas, FVector2D v1, FVector2D v2, FVector2D v3, FLinearColor color) {
    if (v1.Y > v2.Y) std::swap(v1, v2);
    if (v1.Y > v3.Y) std::swap(v1, v3);
    if (v2.Y > v3.Y) std::swap(v2, v3);

    float dy1 = v2.Y - v1.Y;
    float dy2 = v3.Y - v1.Y;
    float dy3 = v3.Y - v2.Y;

    if (dy1 > 0) {
        for (float y = v1.Y; y <= v2.Y; y += 1.0f) {
            float t1 = (y - v1.Y) / dy1;
            float t2 = (y - v1.Y) / dy2;
            float x1 = v1.X + (v2.X - v1.X) * t1;
            float x2 = v1.X + (v3.X - v1.X) * t2;
            if (x1 > x2) std::swap(x1, x2);
            Canvas->K2_DrawLine(FVector2D(x1, y), FVector2D(x2, y), 1.0f, color);
        }
    }
    if (dy3 > 0) {
        for (float y = v2.Y; y <= v3.Y; y += 1.0f) {
            float t1 = (y - v2.Y) / dy3;
            float t2 = (y - v1.Y) / dy2;
            float x1 = v2.X + (v3.X - v2.X) * t1;
            float x2 = v1.X + (v3.X - v1.X) * t2;
            if (x1 > x2) std::swap(x1, x2);
            Canvas->K2_DrawLine(FVector2D(x1, y), FVector2D(x2, y), 1.0f, color);
        }
    }
}

void DrawBox3D(UCanvas* Canvas, AActor* actor, FLinearColor Color, FVector origin, FVector extent) {
    auto MathLibrary = (UKismetMathLibrary*)UKismetMathLibrary::StaticClass();
    auto GameplayStatics = (UGameplayStatics*)UGameplayStatics::StaticClass();
    FRotator rotation = actor->K2_GetActorRotation();
    float yaw = MathLibrary->DegreesToRadians((int)(rotation.Yaw + 450.0f) % 360);
    FVector2D ts1, ts2, ts3, ts4, bs1, bs2, bs3, bs4;
    FVector t1, t2, t3, t4, b1, b2, b3, b4;
    t1 = t2 = t3 = t4 = b1 = b2 = b3 = b4 = origin;
    t1.X -= extent.X;
    t1.Y -= extent.Y;
    t1.Z -= extent.Z;
    t2.X += extent.X;
    t2.Y -= extent.Y;
    t2.Z -= extent.Z;
    t3.X += extent.X;
    t3.Y += extent.Y;
    t3.Z -= extent.Z;
    t4.X -= extent.X;
    t4.Y += extent.Y;
    t4.Z -= extent.Z;

    t1 = RotateCorner(origin, t1, yaw);
    t2 = RotateCorner(origin, t2, yaw);
    t3 = RotateCorner(origin, t3, yaw);
    t4 = RotateCorner(origin, t4, yaw);

    b1.X -= extent.X;
    b1.Y -= extent.Y;
    b1.Z += extent.Z;
    b2.X += extent.X;
    b2.Y -= extent.Y;
    b2.Z += extent.Z;
    b3.X += extent.X;
    b3.Y += extent.Y;
    b3.Z += extent.Z;
    b4.X -= extent.X;
    b4.Y += extent.Y;
    b4.Z += extent.Z;

    b1 = RotateCorner(origin, b1, yaw);
    b2 = RotateCorner(origin, b2, yaw);
    b3 = RotateCorner(origin, b3, yaw);
    b4 = RotateCorner(origin, b4, yaw);
    if (GameplayStatics->ProjectWorldToScreen(g_PlayerController, b1, false, &bs1) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, b2, false, &bs2) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, b3, false, &bs3) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, b4, false, &bs4) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, t1, false, &ts1) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, t2, false, &ts2) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, t3, false, &ts3) && GameplayStatics->ProjectWorldToScreen(g_PlayerController, t4, false, &ts4)) {
        Canvas->K2_DrawLine(ts1, ts2, 2.f, Color);
        Canvas->K2_DrawLine(ts2, ts3, 2.f, Color);
        Canvas->K2_DrawLine(ts3, ts4, 2.f, Color);
        Canvas->K2_DrawLine(ts4, ts1, 2.f, Color);
        Canvas->K2_DrawLine(bs1, bs2, 2.f, Color);
        Canvas->K2_DrawLine(bs2, bs3, 2.f, Color);
        Canvas->K2_DrawLine(bs3, bs4, 2.f, Color);
        Canvas->K2_DrawLine(bs4, bs1, 2.f, Color);
        Canvas->K2_DrawLine(ts1, bs1, 2.f, Color);
        Canvas->K2_DrawLine(ts2, bs2, 2.f, Color);
        Canvas->K2_DrawLine(ts3, bs3, 2.f, Color);
        Canvas->K2_DrawLine(ts4, bs4, 2.f, Color);
    }
}

void DrawRadarGrid(UCanvas* Canvas, float RadarX, float RadarY, float RadarWidth, FLinearColor Color, float LineThickness) {
    float RadarEndX = RadarX + RadarWidth;
    float RadarEndY = RadarY + RadarWidth;

    Canvas->K2_DrawLine(
        FVector2D(RadarX, RadarY),
        FVector2D(RadarEndX, RadarEndY),
        LineThickness,
        Color
    );

    Canvas->K2_DrawLine(
        FVector2D(RadarX, RadarEndY),
        FVector2D(RadarEndX, RadarY),
        LineThickness,
        Color
    );

    float CenterX = RadarX + RadarWidth / 2.0f;
    float CenterY = RadarY + RadarWidth / 2.0f;

    Canvas->K2_DrawLine(
        FVector2D(RadarX, CenterY),
        FVector2D(RadarEndX, CenterY),
        LineThickness,
        Color
    );

    Canvas->K2_DrawLine(
        FVector2D(CenterX, RadarY),
        FVector2D(CenterX, RadarEndY),
        LineThickness,
        Color
    );
    DrawRectangle(
    Canvas,
    FVector2D{ RadarX,RadarY },
    RadarWidth,
    RadarWidth,
    LineThickness,
    Color);
}

void DrawRainbowCircle(UCanvas* Canvas, float x, float y, float radius, int numsides,
    float thickness = 1.0f, float Rotation = 0.0f)
{
    static float AccumulatedTime = 0.0f;
    if (Rotation == 0.0f) {
        AccumulatedTime += 0.0334f;
        Rotation = AccumulatedTime;
    }

    const float FullCircle = 2.0f * PI;
    const float Step = FullCircle / numsides;

    FLinearColor RainbowColors[7] = {
    {1.0f, 0.0f, 0.0f, 0.5f},
    {1.0f, 0.0f, 0.0f, 0.5f},
    {1.0f, 0.0f, 0.0f, 0.5f},
    {1.0f, 0.0f, 0.0f, 0.5f},
    {1.0f, 0.0f, 0.0f, 0.5f},
    {1.0f, 0.0f, 0.0f, 0.5f},
    {1.0f, 0.0f, 0.0f, 0.5f}
};

    float colorOffset = fmod(Rotation * 2.4f, 7.0f);

    for (int i = 0; i < numsides; ++i) {
        const float angle = i * Step;

        float colorPos = (angle / FullCircle) * 7.0f + colorOffset;
        colorPos = fmod(colorPos, 7.0f);

        int idx1 = static_cast<int>(colorPos);
        int idx2 = (idx1 + 1) % 7;
        float blend = colorPos - idx1;

        FLinearColor color;
        color.R = RainbowColors[idx1].R * (1 - blend) + RainbowColors[idx2].R * blend;
        color.G = RainbowColors[idx1].G * (1 - blend) + RainbowColors[idx2].G * blend;
        color.B = RainbowColors[idx1].B * (1 - blend) + RainbowColors[idx2].B * blend;
        color.A = 1.0f;

        FVector2D start(radius * cos(angle) + x, radius * sin(angle) + y);
        FVector2D end(radius * cos(angle + Step) + x, radius * sin(angle + Step) + y);

        Canvas->K2_DrawLine(start, end, thickness, color);
    }
}

void DrawFilledRectWithCircles(UCanvas* canvas, FVector2D center_pos, float w, float h, FLinearColor Color)
{
    FVector2D initial_pos(center_pos.X - w / 2.f, center_pos.Y - h / 2.f);

    for (float i = 0.f; i < h+1; i += 1.f)
        K2_DrawLineUI(canvas, FVector2D(initial_pos.X, initial_pos.Y + i), FVector2D(initial_pos.X + w, initial_pos.Y + i), 1.f, Color);

    DrawFilledCircle(canvas,FVector2D(center_pos.X - w / 2.f , center_pos.Y),h / 2.f, Color);
    FVector2D(center_pos.X + w / 2.f + 50.f, center_pos.Y);

    DrawFilledCircle(canvas,FVector2D(center_pos.X + w / 2.f , center_pos.Y),h / 2.f, Color);
    FVector2D(center_pos.X + w / 2.f + 50.f, center_pos.Y);
}

namespace 寒冰UI
{
    namespace Colors
    {
        FLinearColor Text{ 0.0f, 0.0f, 0.0f, 1.0f };
        FLinearColor Text_Shadow{ 0.0f, 0.0f, 0.0f, 0.2f };
        FLinearColor Text_Outline{ 1.0f, 1.0f, 1.0f, 0.0f };

        FLinearColor Button_Idle{ 0.95f, 0.95f, 0.95f, 1.0f };
        FLinearColor Button_Hovered{ 0.85f, 0.85f, 0.85f, 1.0f };
        FLinearColor Button_Active{ 0.75f, 0.75f, 0.75f, 1.0f };

        FLinearColor ButtonTab_Idle{ 0.9f, 0.9f, 0.9f, 1.0f };
        FLinearColor ButtonTab_Hovered{ 0.8f, 0.8f, 0.8f, 1.0f };
        FLinearColor ButtonTab_Active{ 0.7f, 0.7f, 0.7f, 1.0f };

        FLinearColor Checkbox_Idle{ 0.95f, 0.95f, 0.95f, 1.0f };
        FLinearColor Checkbox_Hovered{ 0.85f, 0.85f, 0.85f, 1.0f };
        FLinearColor Checkbox_Enabled{ 0.2f, 0.6f, 1.0f, 1.0f };

        FLinearColor Combobox_Idle{ 0.95f, 0.95f, 0.95f, 1.0f };
        FLinearColor Combobox_Hovered{ 0.85f, 0.85f, 0.85f, 1.0f };
        FLinearColor Combobox_Elements{ 0.9f, 0.9f, 0.9f, 1.0f };

        FLinearColor Slider_Track{ 0.85f, 0.85f, 0.85f, 1.0f };
        FLinearColor Slider_Progress{ 0.2f, 0.6f, 1.0f, 1.0f };
        FLinearColor Slider_Thumb{ 1.0f, 1.0f, 1.0f, 1.0f };
        FLinearColor Slider_Border{ 0.0f, 0.0f, 0.0f, 0.2f };

        FLinearColor InputBox{ 0.98f, 0.98f, 0.98f, 1.0f };
        FLinearColor ColorPicker_Background{ 0.95f, 0.95f, 0.95f, 0.9f };
    }

    namespace PostRenderer
    {
        struct DrawList
        {
            int type = -1;
            FVector2D pos;
            FVector2D size;
            FLinearColor color;
            char* name;
            bool outline;
            FVector2D from;
            FVector2D to;
            int thickness;
        };
        DrawList drawlist[128];

        void drawFilledRect(FVector2D pos, float w, float h, FLinearColor color)
        {
            for (int i = 0; i < 128; i++)
            {
                if (drawlist[i].type == -1)
                {
                    drawlist[i].type = 1;
                    drawlist[i].pos = pos;
                    drawlist[i].size = FVector2D{ w, h };
                    drawlist[i].color = color;
                    return;
                }
            }
        }
        void TextLeft(char* name, FVector2D pos, FLinearColor color, bool outline)
        {
            for (int i = 0; i < 128; i++)
            {
                if (drawlist[i].type == -1)
                {
                    drawlist[i].type = 2;
                    drawlist[i].name = name;
                    drawlist[i].pos = pos;
                    drawlist[i].outline = outline;
                    drawlist[i].color = color;
                    return;
                }
            }
        }
        void TextCenter(char* name, FVector2D pos, FLinearColor color, bool outline)
        {
            for (int i = 0; i < 128; i++)
            {
                if (drawlist[i].type == -1)
                {
                    drawlist[i].type = 3;
                    drawlist[i].name = name;
                    drawlist[i].pos = pos;
                    drawlist[i].outline = outline;
                    drawlist[i].color = color;
                    return;
                }
            }
        }
        void Draw_Line(FVector2D from, FVector2D to, int thickness, FLinearColor color)
        {
            for (int i = 0; i < 128; i++)
            {
                if (drawlist[i].type == -1)
                {
                    drawlist[i].type = 4;
                    drawlist[i].from = from;
                    drawlist[i].to = to;
                    drawlist[i].thickness = thickness;
                    drawlist[i].color = color;
                    return;
                }
            }
        }
    }

    UCanvas* Canvas;
    UFont* Font;

    bool hover_element = false;
    FVector2D menu_pos = FVector2D{ 0, 0 };
    float offset_x = 0.0f;
    float offset_y = 0.0f;

    FVector2D first_element_pos = FVector2D{ 0, 0 };
    FVector2D last_element_pos = FVector2D{ 0, 0 };
    FVector2D last_element_size = FVector2D{ 0, 0 };

    int current_element = -1;
    FVector2D current_element_pos = FVector2D{ 0, 0 };
    FVector2D current_element_size = FVector2D{ 0, 0 };
    int elements_count = 0;

    bool sameLine = false;
    bool pushY = false;
    float pushYvalue = 0.0f;
    bool mouseDownAlready[256];

    FVector2D MousePos = { 0,0 };
    bool MouseDown = false;
    bool KeysDown[512];

    static int pressed_element = -1;
    static bool pressed_in_element = false;

    FVector2D dragPos;
    FVector2D movePos;
    FVector2D origPos;

    bool IsMouseClicked(int button, int element_id, bool repeat)
    {
        if (MouseDown)
        {
            if (!mouseDownAlready[element_id])
            {
                mouseDownAlready[element_id] = true;
                return true;
            }
            if (repeat)
                return true;
        }
        else
        {
            mouseDownAlready[element_id] = false;
        }
        return false;
    }

    void SetupCanvas(UCanvas* _Canvas, UFont* _font)
    {
        Canvas = _Canvas;
        Font = _font;
    }

    FVector2D CursorPos()
    {
        return MousePos;
    }

    bool MouseInZone(FVector2D pos, FVector2D size)
    {
        FVector2D cursor_pos = CursorPos();
        if (cursor_pos.X > pos.X && cursor_pos.Y > pos.Y)
            if (cursor_pos.X < pos.X + size.X && cursor_pos.Y < pos.Y + size.Y)
                return true;
        return false;
    }

    void Draw_Cursor(bool toogle)
    {
        if (toogle)
        {
            FVector2D cursorPos = CursorPos();
            Canvas->K2_DrawLine(FVector2D{ cursorPos.X, cursorPos.Y }, FVector2D{ cursorPos.X + 35, cursorPos.Y + 10 }, 1, FLinearColor{ 0.30f, 0.30f, 0.80f, 1.0f });

            int x = 35;
            int y = 10;
            while (y != 30)
            {
                x -= 1; if (x < 15) x = 15;
                y += 1; if (y > 30) y = 30;

                Canvas->K2_DrawLine(FVector2D{ cursorPos.X, cursorPos.Y }, FVector2D{ cursorPos.X + x, cursorPos.Y + y }, 1, FLinearColor{ 0.30f, 0.30f, 0.80f, 1.0f });
            }

            Canvas->K2_DrawLine(FVector2D{ cursorPos.X, cursorPos.Y }, FVector2D{ cursorPos.X + 15, cursorPos.Y + 30 }, 1, FLinearColor{ 0.30f, 0.30f, 0.80f, 1.0f });
            Canvas->K2_DrawLine(FVector2D{ cursorPos.X + 35, cursorPos.Y + 10 }, FVector2D{ cursorPos.X + 15, cursorPos.Y + 30 }, 1, FLinearColor{ 0.30f, 0.30f, 0.80f, 1.0f });
        }
    }

    void NewFrame(int screen_width, int screen_height)
    {
        for (auto& key_queue : g_KeyEventQueues)
        {
            if (key_queue.second.empty())
                continue;
            KeysDown[key_queue.first] = (key_queue.second.front() == AKEY_EVENT_ACTION_DOWN);
            key_queue.second.pop();
        }
    }

    bool IsKeyDown(int user_key_index)
    {
        if (user_key_index < 0)
            return false;
        return KeysDown[user_key_index];
    }

    void SameLine()
    {
        sameLine = true;
    }

    void PushNextElementY(float y, bool from_last_element = true)
    {
        pushY = true;
        if (from_last_element)
            pushYvalue = last_element_pos.Y + last_element_size.Y + y;
        else
            pushYvalue = y;
    }

    void ClearFirstPos()
    {
        first_element_pos = FVector2D{ 0, 0 };
    }

    void TextLeft(const char* name, FVector2D pos, FLinearColor color, bool outline)
    {
        int length = strlen(name) + 1;
        Canvas->K2_DrawText(Font, FString(name), pos, color, false, Colors::Text_Shadow, FVector2D{ pos.X + 1, pos.Y + 1 }, false, true, false, Colors::Text_Outline);
    }

    void TextCenter(const char* name, FVector2D pos, FLinearColor color, bool outline)
    {
        int length = strlen(name) + 1;
        Canvas->K2_DrawText(Font, FString(name), pos, color, false, Colors::Text_Shadow, FVector2D{ pos.X + 1, pos.Y + 1 }, true, true, false, Colors::Text_Outline);
    }

    void K2_DrawLine(FVector2D start, FVector2D end, float Thickness, FLinearColor col) {
        DrawLine(寒冰UI::Canvas, FVector2D{ start.X, start.Y }, FVector2D{ end.X, end.Y }, Thickness, col);
    }

    void DrawCheckMark(FVector2D Pos, float Size, FLinearColor Color)
    {
        if (!Canvas)
            return;
        Canvas->K2_DrawLine({ Pos.X + (Size * (2.0f / 10.0f)),Pos.Y + (Size * (6.0f / 10.0f)) }, { Pos.X + (Size * (4.0f / 10.0f)), Pos.Y + (Size * (8.0f / 10.0f)) }, 2.0f, Color);
        Canvas->K2_DrawLine({ Pos.X + (Size * (4.0f / 10.0f)), Pos.Y + (Size * (8.0f / 10.0f)) }, { Pos.X + (Size * (8.0f / 10.0f)), Pos.Y + (Size * (2.0f / 10.0f)) }, 2.0f, Color);
    }

    void GetColor(FLinearColor* color, float* r, float* g, float* b, float* a)
    {
        *r = color->R;
        *g = color->G;
        *b = color->B;
        *a = color->A;
    }

    UINT32 GetColorUINT(int r, int g, int b, int a)
    {
        UINT32 result = (BYTE(a) << 24) + (BYTE(r) << 16) + (BYTE(g) << 8) + BYTE(b);
        return result;
    }

    void Draw_Line(FVector2D from, FVector2D to, int thickness, FLinearColor color)
    {
        Canvas->K2_DrawLine(FVector2D{ from.X, from.Y }, FVector2D{ to.X, to.Y }, thickness, color);
    }

    void drawFilledRect(FVector2D initial_pos, float w, float h, FLinearColor color)
    {
        for (float i = 0.0f; i < h; i += 1.0f)
            Canvas->K2_DrawLine(FVector2D{ initial_pos.X, initial_pos.Y + i }, FVector2D{ initial_pos.X + w, initial_pos.Y + i }, 1.0f, color);
    }

    void DrawCircle(FVector2D pos, int radius, int numSides, FLinearColor Color)
    {
        float Pl = 3.1415927f;
        float Step = Pl * 2.0 / numSides;
        int Count = 0;
        FVector2D V[128];
        for (float a = 0; a < Pl * 2.0; a += Step) {
            float X1 = radius * cos(a) + pos.X;
            float Y1 = radius * sin(a) + pos.Y;
            float X2 = radius * cos(a + Step) + pos.X;
            float Y2 = radius * sin(a + Step) + pos.Y;
            V[Count].X = X1;
            V[Count].Y = Y1;
            V[Count + 1].X = X2;
            V[Count + 1].Y = Y2;

            Draw_Line(FVector2D{ V[Count].X, V[Count].Y }, FVector2D{ X2, Y2 }, 1.0f, Color);
        }
    }

    void NextColumn(float x)
    {
        offset_x = x;
        PushNextElementY(first_element_pos.Y, false);
    }
bool Window(char* name, FVector2D* pos, FVector2D size, bool& isOpen, float& tempValue)
{
    elements_count = 0;

    const float titleBarHeight = 35.0f;
    const float minHeight = 35.0f;
    const float R = 8.0f;

    float actualTitleHeight = isOpen ? titleBarHeight : minHeight;
    float totalHeight = isOpen ? (size.Y + titleBarHeight) : minHeight;

    FLinearColor bgColor = FLinearColor(1.0f, 1.0f, 1.0f, 1.0f);

    float arrowSize = titleBarHeight * 0.5f;
    float arrowLeft = pos->X + R + 5.0f;
    float arrowTop = pos->Y + actualTitleHeight / 2.0f - arrowSize / 2.0f;
    float arrowCenterX = arrowLeft + arrowSize / 2.0f;
    float arrowCenterY = arrowTop + arrowSize / 2.0f;
    const float touchRadius = 12.0f;

    FVector2D cursor = CursorPos();
    float distToArrow = sqrtf(powf(cursor.X - arrowCenterX, 2) + powf(cursor.Y - arrowCenterY, 2));
    bool isMouseOverArrow = distToArrow <= touchRadius;

    bool isMouseInTitleBar = MouseInZone(FVector2D{ pos->X, pos->Y }, FVector2D(size.X, titleBarHeight));
    bool isMouseInDragZone = isOpen ? isMouseInTitleBar : MouseInZone(FVector2D{ pos->X, pos->Y }, FVector2D(size.X, minHeight));

    if (current_element != -1 && !MouseDown)
        current_element = -1;

    if (hover_element && MouseDown)
    {
    }
    else if ((isMouseInDragZone || dragPos.X != 0) && !hover_element)
    {
        if (IsMouseClicked(0, elements_count, true))
        {
            FVector2D cursorPos = CursorPos();
            cursorPos.X -= size.X;
            cursorPos.Y -= size.Y;

            if (dragPos.X == 0)
            {
                dragPos.X = (cursorPos.X - pos->X);
                dragPos.Y = (cursorPos.Y - pos->Y);
                origPos = { cursorPos.X - dragPos.X, cursorPos.Y - dragPos.Y };

                tempValue = isMouseOverArrow ? 1.0f : 0.0f;
            }
            pos->X = cursorPos.X - dragPos.X;
            pos->Y = cursorPos.Y - dragPos.Y;
        }
        else
        {
            dragPos = FVector2D{ 0, 0 };
            if (tempValue && abs(origPos.X - pos->X) <= 10 && abs(origPos.Y - pos->Y) <= 10)
            {
                tempValue = 0;
                isOpen = !isOpen;
            }
            else
            {
                tempValue = 0;
            }
        }
    }
    else
    {
        hover_element = false;
    }

    offset_x = 0.0f; offset_y = 0.0f;
    menu_pos = FVector2D{ pos->X, pos->Y };
    first_element_pos = FVector2D{ 0, 0 };
    current_element_pos = FVector2D{ 0, 0 };
    current_element_size = FVector2D{ 0, 0 };

    ::绘制圆角矩形(寒冰UI::Canvas, FVector2D{ pos->X, pos->Y }, size.X, totalHeight, R, bgColor);

    if (isOpen)
    {
        Draw_Line(FVector2D{ pos->X + R, pos->Y + titleBarHeight },
                  FVector2D{ pos->X + size.X - R, pos->Y + titleBarHeight },
                  1.0f, FLinearColor(0,0,0,0.2f));
    }

    if (isMouseOverArrow)
    {
        FLinearColor hoverColor = FLinearColor(0.5f, 0.5f, 0.5f, 0.3f);
        ::DrawFilledCircle(寒冰UI::Canvas, FVector2D{ arrowCenterX, arrowCenterY }, touchRadius, hoverColor);
    }

    FVector2D v1, v2, v3;
    if (isOpen)
    {
        v1 = FVector2D(arrowCenterX, arrowTop + arrowSize);
        v2 = FVector2D(arrowLeft, arrowTop);
        v3 = FVector2D(arrowLeft + arrowSize, arrowTop);
    }
    else
    {
        v1 = FVector2D(arrowLeft + arrowSize, arrowCenterY);
        v2 = FVector2D(arrowLeft, arrowTop);
        v3 = FVector2D(arrowLeft, arrowTop + arrowSize);
    }
    FLinearColor arrowColor = FLinearColor(0,0,0,1);
    ::FillTriangle(寒冰UI::Canvas, v1, v2, v3, arrowColor);

    int TitleFontSize = 18;
    Font->LegacyFontSize = TitleFontSize;
    float textX = arrowLeft + arrowSize + 10.0f;
    float textY = pos->Y + actualTitleHeight / 2.0f;
    TextLeft(name, FVector2D{ textX, textY }, FLinearColor(0,0,0,1), false);
    Font->LegacyFontSize = 13;

    if (isOpen)
    {
        offset_y += titleBarHeight;
    }

    return isOpen;
}

    bool ButtonTab(const char* name, FVector2D size, bool active)
    {
        elements_count++;

        FVector2D padding = FVector2D{ 5, 10 };
        FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X + padding.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }
        bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, size);

        FLinearColor bgColor;
        if (active)
            bgColor = Colors::ButtonTab_Active;
        else if (isHovered)
            bgColor = Colors::ButtonTab_Hovered;
        else
            bgColor = Colors::ButtonTab_Idle;

        const float R = 8.0f;
        ::绘制圆角矩形(寒冰UI::Canvas, pos, size.X, size.Y, R, bgColor);

        if (!sameLine)
            offset_y += size.Y + padding.Y;

        FVector2D textPos = FVector2D{ pos.X + size.X / 2, pos.Y + size.Y / 2 };
        TextCenter(name, textPos, Colors::Text, false);

        bool clicked = false;
        if (isHovered && MouseDown && !mouseDownAlready[elements_count])
        {
            mouseDownAlready[elements_count] = true;
            pressed_element = elements_count;
            pressed_in_element = true;
        }
        if (pressed_element == elements_count && !MouseDown)
        {
            if (isHovered)
            {
                clicked = true;
            }
            pressed_element = -1;
            pressed_in_element = false;
            mouseDownAlready[elements_count] = false;
        }
        if (pressed_element == elements_count && !isHovered && MouseDown)
        {
            pressed_element = -1;
            pressed_in_element = false;
            mouseDownAlready[elements_count] = false;
        }

        if (!MouseDown)
            mouseDownAlready[elements_count] = false;

        sameLine = false;
        last_element_pos = pos;
        last_element_size = size;
        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;

        if (clicked)
            return true;
        return false;
    }

    bool Button(const char* name, FVector2D size)
    {
        elements_count++;

        FVector2D padding = FVector2D{ 10, 10 };
        FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X + padding.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }
        bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, size);

        FLinearColor bgColor = isHovered ? Colors::Button_Hovered : Colors::Button_Idle;

        const float R = 8.0f;
        ::绘制圆角矩形(寒冰UI::Canvas, pos, size.X, size.Y, R, bgColor);

        if (isHovered) hover_element = true;

        if (!sameLine)
            offset_y += size.Y + padding.Y;

        FVector2D textPos = FVector2D{ pos.X + size.X / 2, pos.Y + size.Y / 2 };
        TextCenter(name, textPos, Colors::Text, false);

        bool clicked = false;
        if (isHovered && MouseDown && !mouseDownAlready[elements_count])
        {
            mouseDownAlready[elements_count] = true;
            pressed_element = elements_count;
            pressed_in_element = true;
        }
        if (pressed_element == elements_count && !MouseDown)
        {
            if (isHovered)
            {
                clicked = true;
            }
            pressed_element = -1;
            pressed_in_element = false;
            mouseDownAlready[elements_count] = false;
        }
        if (pressed_element == elements_count && !isHovered && MouseDown)
        {
            pressed_element = -1;
            pressed_in_element = false;
            mouseDownAlready[elements_count] = false;
        }

        if (!MouseDown)
            mouseDownAlready[elements_count] = false;

        sameLine = false;
        last_element_pos = pos;
        last_element_size = size;
        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;

        if (clicked)
            return true;
        return false;
    }

bool 按钮(char* name, bool* value)
{
    elements_count++;

    float size = 30;
    FVector2D padding = FVector2D{ 10, 10 };
    FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
    if (sameLine)
    {
        pos.X = last_element_pos.X + last_element_size.X + padding.X;
        pos.Y = last_element_pos.Y;
    }
    if (pushY)
    {
        pos.Y = pushYvalue;
        pushY = false;
        pushYvalue = 0.0f;
        offset_y = pos.Y - menu_pos.Y;
    }

    float centerX = pos.X + size / 2;
    float centerY = pos.Y + size / 2;
    float radius = size / 2;

    bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, FVector2D{ size, size });

    if (isHovered)
        hover_element = true;

    if (*value)
    {
        ::DrawFilledCircle(Canvas, FVector2D{ centerX, centerY }, radius, Colors::Checkbox_Enabled);
        float checkSize = radius * 0.7f;
        FVector2D p1(centerX - checkSize/2, centerY);
        FVector2D p2(centerX, centerY + checkSize/2);
        FVector2D p3(centerX + checkSize/2, centerY - checkSize/3);
        Canvas->K2_DrawLine(p1, p2, 3.0f, FLinearColor(1,1,1,1));
        Canvas->K2_DrawLine(p2, p3, 3.0f, FLinearColor(1,1,1,1));
    }
    else
    {
        ::DrawCircle(Canvas, centerX, centerY, radius, 32, FLinearColor(0.7f,0.7f,0.7f,1));
    }

    if (!sameLine)
        offset_y += size + padding.Y;

    FVector2D textPos = FVector2D{ pos.X + size + 5, pos.Y + size / 2 };
    TextLeft(name, textPos, Colors::Text, false);

    sameLine = false;
    last_element_pos = pos;
    last_element_size = FVector2D{ size + (name ? strlen(name)*8 : 0), size };
    if (first_element_pos.X == 0.0f)
        first_element_pos = pos;

    bool clicked = false;
    if (isHovered && MouseDown && !mouseDownAlready[elements_count])
    {
        mouseDownAlready[elements_count] = true;
        pressed_element = elements_count;
        pressed_in_element = true;
    }
    if (pressed_element == elements_count && !MouseDown)
    {
        if (isHovered)
        {
            clicked = true;
        }
        pressed_element = -1;
        pressed_in_element = false;
        mouseDownAlready[elements_count] = false;
    }
    if (pressed_element == elements_count && !isHovered && MouseDown)
    {
        pressed_element = -1;
        pressed_in_element = false;
        mouseDownAlready[elements_count] = false;
    }

    if (!MouseDown)
        mouseDownAlready[elements_count] = false;

    if (clicked)
    {
        *value = !*value;
        return true;
    }
    return false;
}

    void Text(const char* text, bool center = false, bool outline = false)
    {
        elements_count++;

        float size = 12.5;
        FVector2D padding = FVector2D{ 10, 10 };
        FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X + padding.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }

        if (!sameLine)
            offset_y += size + padding.Y;

        FVector2D textPos = FVector2D{ pos.X + 5.0f, pos.Y + size / 2 };
        if (center)
            TextCenter(text, textPos, Colors::Text, outline);
        else
            TextLeft(text, textPos, Colors::Text, outline);

        sameLine = false;
        last_element_pos = pos;
        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;
    }

    void BoxText(const char* text, bool center = false, bool outline = false)
    {
        elements_count++;

        float size = 12.5;
        FVector2D slider_size = FVector2D{ 530, 40 };
        FVector2D padding = FVector2D{ 10, 10 };
        FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X + padding.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }

        if (!sameLine)
            offset_y += size + padding.Y;

        DrawRectangle(Canvas, FVector2D{ pos.X, pos.Y + padding.Y/2 }, slider_size.X, slider_size.Y ,3.f, 黑色);

        FVector2D textPos = FVector2D{ pos.X + slider_size.X/2, pos.Y + size*2 };
        TextCenter(text, textPos, FLinearColor{ 0.f, 0.f, 0.f, 1.0f }, false);

        sameLine = false;
        last_element_pos = pos;
        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;
    }

    bool ToggleSwitch(char* name, bool* value)
    {
        elements_count++;

        float size = 30;
        float JG = 350;
        FVector2D padding = FVector2D{ 10, 20 };
        FVector2D pos = FVector2D{ menu_pos.X + 10.f + offset_x, menu_pos.Y + offset_y + 5.f };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }
        bool isHovered = MouseInZone(FVector2D{ pos.X + JG, pos.Y }, FVector2D{ size + size, size });

        if (isHovered)
            hover_element = true;

        float switchWidth = size * 2;
        float switchHeight = size;
        FVector2D switchPos = FVector2D{ pos.X + JG, pos.Y };
        FLinearColor trackColor = *value ? FLinearColor(0.2f,0.6f,1.0f,1) : FLinearColor(0.85f,0.85f,0.85f,1);
        ::绘制圆角矩形(Canvas, switchPos, switchWidth, switchHeight, switchHeight/2, trackColor);

        float knobX = *value ? switchPos.X + switchWidth - switchHeight : switchPos.X;
        float knobY = switchPos.Y;
        ::DrawFilledCircle(Canvas, FVector2D{ knobX + switchHeight/2, knobY + switchHeight/2 }, switchHeight/2 - 2, FLinearColor(1,1,1,1));

        if (!sameLine)
            offset_y += size + padding.Y;

        FVector2D textPos = FVector2D{ pos.X, pos.Y + size / 2 };
        TextLeft(name, textPos, Colors::Text, false);

        sameLine = false;
        last_element_pos = pos;
        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;

        bool clicked = false;
        if (isHovered && MouseDown && !mouseDownAlready[elements_count])
        {
            mouseDownAlready[elements_count] = true;
            pressed_element = elements_count;
            pressed_in_element = true;
        }
        if (pressed_element == elements_count && !MouseDown)
        {
            if (isHovered)
            {
                clicked = true;
            }
            pressed_element = -1;
            pressed_in_element = false;
            mouseDownAlready[elements_count] = false;
        }
        if (pressed_element == elements_count && !isHovered && MouseDown)
        {
            pressed_element = -1;
            pressed_in_element = false;
            mouseDownAlready[elements_count] = false;
        }

        if (!MouseDown)
            mouseDownAlready[elements_count] = false;

        if (clicked) {
            *value = !*value;
            return true;
        }
        return false;
    }

    bool 滑动开关(const char* name, bool* value)
    {
        return ToggleSwitch((char*)name, value);
    }
bool SliderFloat(const char* name, float* value, float min, float max, const char* format = "%.0f")
{
    elements_count++;

    FVector2D size = FVector2D{ 100, 35};
    FVector2D slider_size = FVector2D{ 155, 20};
    FVector2D padding = FVector2D{ 10, 5};
    FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };

    if (sameLine)
    {
        pos.X = last_element_pos.X + last_element_size.X + 90.0f;
        pos.Y = last_element_pos.Y;
    }

    if (pushY)
    {
        pos.Y = pushYvalue;
        pushY = false;
        pushYvalue = 0.0f;
        offset_y = pos.Y - menu_pos.Y;
    }

    FVector2D sliderZonePos = FVector2D{ pos.X, pos.Y + slider_size.Y + padding.Y };
    FVector2D sliderZoneSize = FVector2D{ slider_size.X, slider_size.Y };

    bool isInSliderZone = MouseInZone(sliderZonePos, sliderZoneSize);
    bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y + slider_size.Y + padding.Y - 10 }, FVector2D{ slider_size.X, slider_size.Y + 20 });

    bool change = false;
    static int active_slider = -1;

    if (isInSliderZone && MouseDown && !mouseDownAlready[elements_count])
    {
        mouseDownAlready[elements_count] = true;
        active_slider = elements_count;
    }

    if (active_slider == elements_count)
    {
        if (!MouseDown)
        {
            active_slider = -1;
            mouseDownAlready[elements_count] = false;
        }
        else if (!isInSliderZone)
        {
            active_slider = -1;
            mouseDownAlready[elements_count] = false;
        }
        else
        {
            FVector2D cursorPos = CursorPos();
            *value = ((cursorPos.X - pos.X) * ((max - min) / slider_size.X)) + min;
            if (*value < min) *value = min;
            if (*value > max) *value = max;
            change = true;
        }
    }

    if (!MouseDown)
        mouseDownAlready[elements_count] = false;

    if (isHovered) hover_element = true;

    FVector2D textPos = FVector2D{ pos.X, pos.Y + 10 };
    TextLeft(name, textPos, Colors::Text, false);

    float oneP = slider_size.X / (max - min);
    float progressWidth = oneP * (*value - min);

    float radius = slider_size.Y / 2.0f;
    float centerY = pos.Y + slider_size.Y + padding.Y + radius;

    ::绘制圆角矩形(Canvas, FVector2D{ pos.X, pos.Y + slider_size.Y + padding.Y }, slider_size.X, slider_size.Y, radius, Colors::Slider_Track);

    if (progressWidth > 0)
    {
        ::绘制圆角矩形(Canvas, FVector2D{ pos.X, pos.Y + slider_size.Y + padding.Y }, progressWidth, slider_size.Y, radius, Colors::Slider_Progress);
    }

    float knobX = pos.X + progressWidth;
    if (knobX < pos.X + radius) knobX = pos.X + radius;
    if (knobX > pos.X + slider_size.X - radius) knobX = pos.X + slider_size.X - radius;

    ::DrawFilledCircle(Canvas, FVector2D(knobX, centerY), radius, Colors::Slider_Thumb);
    ::DrawCircle(Canvas, knobX, centerY, radius, 32, Colors::Slider_Border);

    char buffer[64];
    sprintf(buffer, format, *value);
    FVector2D valuePos = FVector2D{ pos.X + slider_size.X + 20, pos.Y + 10 };
    TextCenter(buffer, valuePos, Colors::Text, false);

    offset_y += 20.0f;

    sameLine = false;
    last_element_pos = pos;
    last_element_size = size;
    if (first_element_pos.X == 0.0f)
        first_element_pos = pos;

    return change;
}
    bool checkbox_enabled[256];
bool Combobox(char* name, FVector2D size, int* value, const char* arg, ...)
{
    elements_count++;

    FVector2D padding = FVector2D{ 10, 10 };
    FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
    if (sameLine)
    {
        pos.X = last_element_pos.X + last_element_size.X + padding.X;
        pos.Y = last_element_pos.Y;
    }
    if (pushY)
    {
        pos.Y = pushYvalue;
        pushY = false;
        pushYvalue = 0.0f;
        offset_y = pos.Y - menu_pos.Y;
    }
    bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, size);
    if (isHovered) hover_element = true;

    FLinearColor bgColor = isHovered ? Colors::Combobox_Hovered : Colors::Combobox_Idle;
    const float R = 8.0f;
    ::绘制圆角矩形(Canvas, pos, size.X, size.Y, R, bgColor);

    if (!sameLine)
        offset_y += size.Y + padding.Y;

    int numOptions = 0;
    const char* selectedText = nullptr;
    int currentVal = *value;

    va_list args;
    va_start(args, arg);
    const char* opt = arg;
    while (opt != NULL)
    {
        if (numOptions == currentVal)
            selectedText = opt;
        numOptions++;
        opt = va_arg(args, const char*);
    }
    va_end(args);

    if (selectedText != nullptr)
    {
        FVector2D textPos = FVector2D{ pos.X + 8, pos.Y + size.Y / 2 };
        char buffer[128];
        snprintf(buffer, sizeof(buffer), "%s : %s", name, selectedText);
        TextLeft(buffer, textPos, Colors::Text, false);
    }

    sameLine = false;
    last_element_pos = pos;
    last_element_size = size;
    if (first_element_pos.X == 0.0f)
        first_element_pos = pos;

    if (isHovered && IsMouseClicked(0, elements_count, false))
    {
        if (numOptions > 0)
            *value = (*value + 1) % numOptions;
        return true;
    }
    return false;
}
    bool Checkbox(char* name, bool* value)
    {
        elements_count++;
        float size = 30;
        FVector2D padding = FVector2D{ 15, 10 };
        FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X + padding.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }
        bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, FVector2D{ size, size });
        if (isHovered)
            hover_element = true;

        FLinearColor bgColor = isHovered ? Colors::Checkbox_Hovered : Colors::Checkbox_Idle;
        float R = 8.0f;
        ::绘制圆角矩形(Canvas, pos, size, size, R, bgColor);

        if (!sameLine)
            offset_y += size + padding.Y;

        if (*value)
        {
            float offset = 7.0f;
            FLinearColor checkColor = Colors::Checkbox_Enabled;
            Draw_Line(FVector2D{ pos.X + offset, pos.Y + size - offset },
                      FVector2D{ pos.X + size / 2 - 2, pos.Y + size / 2 + 2 },
                      3.0f, checkColor);
            Draw_Line(FVector2D{ pos.X + size / 2 - 2, pos.Y + size / 2 + 2 },
                      FVector2D{ pos.X + size - offset, pos.Y + offset },
                      3.0f, checkColor);
        }

        FVector2D textPos = FVector2D{ pos.X + size + 5.0f, pos.Y + size / 2 };
        TextLeft(name, textPos, Colors::Text, false);

        sameLine = false;
        last_element_pos = pos;
        last_element_size = FVector2D{ size + padding.X, size };
        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;

        if (isHovered && IsMouseClicked(0, elements_count, false)){
            *value = !*value;
            return true;
        }
        return false;
    }

    int active_picker = -1;
    FLinearColor saved_color;

    bool ColorPixel(FVector2D pos, FVector2D size, FLinearColor* original, FLinearColor color)
    {
        PostRenderer::drawFilledRect(FVector2D{ pos.X, pos.Y }, size.X, size.Y, color);

        if (original->R == color.R && original->G == color.G && original->B == color.B)
        {
            PostRenderer::Draw_Line(FVector2D{ pos.X, pos.Y }, FVector2D{ pos.X + size.X - 1, pos.Y }, 1.0f, FLinearColor{ 0.0f, 0.0f, 0.0f, 1.0f });
            PostRenderer::Draw_Line(FVector2D{ pos.X, pos.Y + size.Y - 1 }, FVector2D{ pos.X + size.X - 1, pos.Y + size.Y - 1 }, 1.0f, FLinearColor{ 0.0f, 0.0f, 0.0f, 1.0f });
            PostRenderer::Draw_Line(FVector2D{ pos.X, pos.Y }, FVector2D{ pos.X, pos.Y + size.Y - 1 }, 1.0f, FLinearColor{ 0.0f, 0.0f, 0.0f, 1.0f });
            PostRenderer::Draw_Line(FVector2D{ pos.X + size.X - 1, pos.Y }, FVector2D{ pos.X + size.X - 1, pos.Y + size.Y - 1 }, 1.0f, FLinearColor{ 0.0f, 0.0f, 0.0f, 1.0f });
        }

        bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, size);
        if (isHovered)
        {
            if (IsMouseClicked(0, elements_count, false))
                *original = color;
        }

        return true;
    }

    void ColorPicker(const char* name, FLinearColor* color)
    {
        elements_count++;

        float size = 25;
        FVector2D padding = FVector2D{ 10, 10 };
        FVector2D pos = FVector2D{ menu_pos.X + padding.X + offset_x, menu_pos.Y + padding.Y + offset_y };
        if (sameLine)
        {
            pos.X = last_element_pos.X + last_element_size.X + padding.X;
            pos.Y = last_element_pos.Y;
        }
        if (pushY)
        {
            pos.Y = pushYvalue;
            pushY = false;
            pushYvalue = 0.0f;
            offset_y = pos.Y - menu_pos.Y;
        }
        bool isHovered = MouseInZone(FVector2D{ pos.X, pos.Y }, FVector2D{ size, size });

        if (!sameLine)
            offset_y += size + padding.Y;

        if (active_picker == elements_count)
        {
            hover_element = true;

            float sizePickerX = 250;
            float sizePickerY = 250;
            bool isHoveredPicker = MouseInZone(FVector2D{ pos.X, pos.Y }, FVector2D{ sizePickerX, sizePickerY - 60 });

            PostRenderer::drawFilledRect(FVector2D{ pos.X, pos.Y }, sizePickerX, sizePickerY - 65, Colors::ColorPicker_Background);

            FVector2D pixelSize = FVector2D{ sizePickerX / 12, sizePickerY / 12 };

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 174 / 255.f, 235 / 255.f, 253 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 136 / 255.f, 225 / 255.f, 251 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 108 / 255.f, 213 / 255.f, 250 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 89 / 255.f, 175 / 255.f, 213 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 76 / 255.f, 151 / 255.f, 177 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 60 / 255.f, 118 / 255.f, 140 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 43 / 255.f, 85 / 255.f, 100 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 32 / 255.f, 62 / 255.f, 74 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 0, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 255 / 255.f, 255 / 255.f, 255 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 175 / 255.f, 205 / 255.f, 252 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 132 / 255.f, 179 / 255.f, 252 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 90 / 255.f, 152 / 255.f, 250 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 55 / 255.f, 120 / 255.f, 250 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 49 / 255.f, 105 / 255.f, 209 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 38 / 255.f, 83 / 255.f, 165 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 28 / 255.f, 61 / 255.f, 120 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 20 / 255.f, 43 / 255.f, 86 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 1, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 247 / 255.f, 247 / 255.f, 247 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 153 / 255.f, 139 / 255.f, 250 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 101 / 255.f, 79 / 255.f, 249 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 64 / 255.f, 50 / 255.f, 230 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 54 / 255.f, 38 / 255.f, 175 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 39 / 255.f, 31 / 255.f, 144 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 32 / 255.f, 25 / 255.f, 116 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 21 / 255.f, 18 / 255.f, 82 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 16 / 255.f, 13 / 255.f, 61 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 2, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 228 / 255.f, 228 / 255.f, 228 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 194 / 255.f, 144 / 255.f, 251 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 165 / 255.f, 87 / 255.f, 249 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 142 / 255.f, 57 / 255.f, 239 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 116 / 255.f, 45 / 255.f, 184 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 92 / 255.f, 37 / 255.f, 154 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 73 / 255.f, 29 / 255.f, 121 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 53 / 255.f, 21 / 255.f, 88 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 37 / 255.f, 15 / 255.f, 63 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 3, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 203 / 255.f, 203 / 255.f, 203 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 224 / 255.f, 162 / 255.f, 197 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 210 / 255.f, 112 / 255.f, 166 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 199 / 255.f, 62 / 255.f, 135 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 159 / 255.f, 49 / 255.f, 105 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 132 / 255.f, 41 / 255.f, 89 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 104 / 255.f, 32 / 255.f, 71 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 75 / 255.f, 24 / 255.f, 51 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 54 / 255.f, 14 / 255.f, 36 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 4, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 175 / 255.f, 175 / 255.f, 175 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 235 / 255.f, 175 / 255.f, 176 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 227 / 255.f, 133 / 255.f, 135 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 219 / 255.f, 87 / 255.f, 88 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 215 / 255.f, 50 / 255.f, 36 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 187 / 255.f, 25 / 255.f, 7 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 149 / 255.f, 20 / 255.f, 6 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 107 / 255.f, 14 / 255.f, 4 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 77 / 255.f, 9 / 255.f, 3 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 5, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 144 / 255.f, 144 / 255.f, 144 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 241 / 255.f, 187 / 255.f, 171 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 234 / 255.f, 151 / 255.f, 126 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 229 / 255.f, 115 / 255.f, 76 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 227 / 255.f, 82 / 255.f, 24 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 190 / 255.f, 61 / 255.f, 15 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 150 / 255.f, 48 / 255.f, 12 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 107 / 255.f, 34 / 255.f, 8 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 79 / 255.f, 25 / 255.f, 6 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 6, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 113 / 255.f, 113 / 255.f, 113 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 245 / 255.f, 207 / 255.f, 169 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 240 / 255.f, 183 / 255.f, 122 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 236 / 255.f, 159 / 255.f, 74 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 234 / 255.f, 146 / 255.f, 37 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 193 / 255.f, 111 / 255.f, 28 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 152 / 255.f, 89 / 255.f, 22 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 110 / 255.f, 64 / 255.f, 16 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 80 / 255.f, 47 / 255.f, 12 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 7, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 82 / 255.f, 82 / 255.f, 82 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 247 / 255.f, 218 / 255.f, 170 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 244 / 255.f, 200 / 255.f, 124 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 241 / 255.f, 182 / 255.f, 77 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 239 / 255.f, 174 / 255.f, 44 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 196 / 255.f, 137 / 255.f, 34 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 154 / 255.f, 108 / 255.f, 27 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 111 / 255.f, 77 / 255.f, 19 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 80 / 255.f, 56 / 255.f, 14 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 8, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 54 / 255.f, 54 / 255.f, 54 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 254 / 255.f, 243 / 255.f, 187 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 253 / 255.f, 237 / 255.f, 153 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 253 / 255.f, 231 / 255.f, 117 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 254 / 255.f, 232 / 255.f, 85 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 242 / 255.f, 212 / 255.f, 53 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 192 / 255.f, 169 / 255.f, 42 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 138 / 255.f, 120 / 255.f, 30 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 101 / 255.f, 87 / 255.f, 22 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 9, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 29 / 255.f, 29 / 255.f, 29 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 247 / 255.f, 243 / 255.f, 185 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 243 / 255.f, 239 / 255.f, 148 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 239 / 255.f, 232 / 255.f, 111 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 235 / 255.f, 229 / 255.f, 76 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 208 / 255.f, 200 / 255.f, 55 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 164 / 255.f, 157 / 255.f, 43 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 118 / 255.f, 114 / 255.f, 31 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 86 / 255.f, 82 / 255.f, 21 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 10, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 9 / 255.f, 9 / 255.f, 9 / 255.f, 1.0f });
            }

            {
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 0 }, pixelSize, color, FLinearColor{ 218 / 255.f, 232 / 255.f, 182 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 1 }, pixelSize, color, FLinearColor{ 198 / 255.f, 221 / 255.f, 143 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 2 }, pixelSize, color, FLinearColor{ 181 / 255.f, 210 / 255.f, 103 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 3 }, pixelSize, color, FLinearColor{ 154 / 255.f, 186 / 255.f, 76 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 4 }, pixelSize, color, FLinearColor{ 130 / 255.f, 155 / 255.f, 64 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 5 }, pixelSize, color, FLinearColor{ 102 / 255.f, 121 / 255.f, 50 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 6 }, pixelSize, color, FLinearColor{ 74 / 255.f, 88 / 255.f, 36 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 7 }, pixelSize, color, FLinearColor{ 54 / 255.f, 64 / 255.f, 26 / 255.f, 1.0f });
                ColorPixel(FVector2D{ pos.X + pixelSize.X * 11, pos.Y + pixelSize.Y * 8 }, pixelSize, color, FLinearColor{ 0 / 255.f, 0 / 255.f, 0 / 255.f, 1.0f });
            }

            if (isHoveredPicker)
            {
                if (IsMouseClicked(0, elements_count, false))
                {
                }
            }
            else
            {
                if (IsMouseClicked(0, elements_count, false))
                {
                    active_picker = -1;
                }
            }
        }
        else
        {
            if (isHovered)
            {
                drawFilledRect(FVector2D{ pos.X, pos.Y }, size, size, Colors::Checkbox_Hovered);
                hover_element = true;
            }
            else
            {
                drawFilledRect(FVector2D{ pos.X, pos.Y }, size, size, Colors::Checkbox_Idle);
            }

            drawFilledRect(FVector2D{ pos.X + 4, pos.Y + 4 }, size - 8, size - 8, *color);

            FVector2D textPos = FVector2D{ pos.X + size + 5.0f, pos.Y + size / 2 };
            TextLeft(name, textPos, Colors::Text, false);

            if (isHovered && IsMouseClicked(0, elements_count, false))
            {
                saved_color = *color;
                active_picker = elements_count;
            }
        }

        sameLine = false;
        last_element_pos = pos;

        if (first_element_pos.X == 0.0f)
            first_element_pos = pos;
    }

    void onEvent(AInputEvent* input_event, FVector2D screen_scale) {
        auto event_type = AInputEvent_getType(input_event);
        if (event_type != AINPUT_EVENT_TYPE_MOTION)
            return;
        int32_t event_action = AMotionEvent_getAction(input_event);
        int32_t event_pointer_index = (event_action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        if (event_pointer_index > 0)
            return;
        event_action &= AMOTION_EVENT_ACTION_MASK;
        switch (event_action) {
        case AMOTION_EVENT_ACTION_DOWN:
        case AMOTION_EVENT_ACTION_UP:
            if ((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER) || (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)) {
                MouseDown = (event_action == AMOTION_EVENT_ACTION_DOWN);
                FVector2D pos(AMotionEvent_getRawX(input_event, event_pointer_index), AMotionEvent_getRawY(input_event, event_pointer_index));
                MousePos = FVector2D(screen_scale.X > 0 ? pos.X / screen_scale.X : pos.X, screen_scale.Y > 0 ? pos.Y / screen_scale.Y : pos.Y);
            }
            break;
        case AMOTION_EVENT_ACTION_BUTTON_PRESS:
        case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
            int32_t button_state = AMotionEvent_getButtonState(input_event);
            MouseDown = ((button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
        }
        break;
        case AMOTION_EVENT_ACTION_HOVER_MOVE:
        case AMOTION_EVENT_ACTION_MOVE: {
            FVector2D pos(AMotionEvent_getRawX(input_event, event_pointer_index), AMotionEvent_getRawY(input_event, event_pointer_index));
            MousePos = FVector2D(screen_scale.X > 0 ? pos.X / screen_scale.X : pos.X, screen_scale.Y > 0 ? pos.Y / screen_scale.Y : pos.Y);
            break;
        }
        default:
            break;
        }
    }

    void Render()
    {
        for (int i = 0; i < 128; i++)
        {
            if (PostRenderer::drawlist[i].type != -1)
            {
                if (PostRenderer::drawlist[i].type == 1)
                {
                    寒冰UI::drawFilledRect(PostRenderer::drawlist[i].pos, PostRenderer::drawlist[i].size.X, PostRenderer::drawlist[i].size.Y, PostRenderer::drawlist[i].color);
                }
                else if (PostRenderer::drawlist[i].type == 2)
                {
                    寒冰UI::TextLeft(PostRenderer::drawlist[i].name, PostRenderer::drawlist[i].pos, PostRenderer::drawlist[i].color, PostRenderer::drawlist[i].outline);
                }
                else if (PostRenderer::drawlist[i].type == 3)
                {
                    寒冰UI::TextCenter(PostRenderer::drawlist[i].name, PostRenderer::drawlist[i].pos, PostRenderer::drawlist[i].color, PostRenderer::drawlist[i].outline);
                }
                else if (PostRenderer::drawlist[i].type == 4)
                {
                    Draw_Line(PostRenderer::drawlist[i].from, PostRenderer::drawlist[i].to, PostRenderer::drawlist[i].thickness, PostRenderer::drawlist[i].color);
                }

                PostRenderer::drawlist[i].type = -1;
            }
        }
    }
}