CedricGuillemet / ImGuizmo

Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui
MIT License
3.22k stars 907 forks source link

Tried out ImGradient; not sure how it works #200

Closed idbrii closed 3 years ago

idbrii commented 3 years ago

ImGradient isn't in README or example, so I guess it's not ready for use and very subject to change? I wanted to mess around with it anyway, but couldn't figure it out.

I assumed it would be a gradient editor like this one where you set key colors and it creates a gradient between each of them, but I could only get it to look like the top bar here:

image

You can slide the colors around (which changes their alpha value) and double click to add another one, but I don't see how you could edit any of them.

To give anyone else poking around a head start, I thought I'd share my (probably wrong) code.

ImGradient Delegate implementation:

#include "imgui.h"
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui_internal.h"

#include <vector>
#include "ImGradient.h"

struct Gradient : ImGradient::Delegate
{
    std::vector<ImVec4> m_Points;

    virtual size_t GetPointCount() {
        return m_Points.size();
    }

    virtual ImVec4* GetPoints() {
        return &m_Points[0];
    }

    virtual int EditPoint(int pointIndex, ImVec4 value) {
        // Don't understand how this is supposed to work.
        if (ImGui::Begin("Selected Color", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::ColorEdit4("Color", &m_Points[pointIndex].x);
        }
        ImGui::End();

        m_Points[pointIndex] = value;
        return 0;
    }

    virtual ImVec4 GetPoint(float t) {
        float index = 0.f;
        float progress = std::modf(t*(GetPointCount() - 1), &index);
        if (0 <= index && index < GetPointCount()) {
            return ImLerp(m_Points[index], m_Points[index + 1], progress);
        }
        return m_Points[0];
    }

    virtual void AddPoint(ImVec4 value) {
        m_Points.push_back(value);
    }
};

and it's invoked like this:

            static Gradient d;
            static int selection = 1;
            static bool needs_init = true;
            if (needs_init) {
                needs_init = false;
                d.m_Points.push_back(ImVec4(1,1,1,1));
                d.m_Points.push_back(ImVec4(0,1,1,1));
                d.m_Points.push_back(ImVec4(1,0,1,1));
                d.m_Points.push_back(ImVec4(1,1,0,1));
            }

            const ImVec2 size(200,20);
            bool b = ImGradient::Edit(d, size, selection);
            // draw more stuff to see what's going on
            selection = ImGui::DragInt("Selection", &selection, 0, d.GetPointCount());

            char label[] = "Color 1";
            for (int i = 0; i < d.m_Points.size(); ++i) {
                label[6] = '0' + i;
                ImGui::ColorEdit4(label, &d.m_Points[i].x);
            }
idbrii commented 3 years ago

I don't need a response. just posting for anyone else searching the issues for "ImGradient".