ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.67k stars 10.16k forks source link

Gradient Begin #1160

Closed BushidoDigital closed 7 years ago

BushidoDigital commented 7 years ago

Hey, I was wondering if there was any way to make the style ImGuiCol_TitleBgActive work with gradients. I tried writing a function but it didn't work in the end and I gave up and deleted it, any help would be appreciated.

ocornut commented 7 years ago

It's not possible without a (trivial) code modification and dear imgui isn't aimed at doing that sort of thing so the additional styling option or code wouldn't be merged into master.

MrSapps commented 7 years ago

Even in a debug UI a gradient would be nice - how come this kind of thing wouldn't be merged? Is it due to performance impact or is just somehow against the nature of the library?

ocornut commented 7 years ago

A little because of performance impact, a little because it would make skinning more work, a lot because of the work/maintenance impact on me. Every feature tends to push toward a direction, if we start pushing in that direction it is a never ending push. It's not really the nature of the library. I would much rather avoid the extra users and cost it would bring, since I don't have the resources to handle them.

Note that the poster comes from a background of making overlay/hacks for cheating in network games (which itself is unethical), and that population is mostly interested in the look of their interface, because they take pride in making their hack look different from the neighbour hack, and lately several of those users of imgui have been trying to hide the fact that they are using dear imgui as a sort of badge of pride for "doing it themselves". While they can do what they want, it's not really in the wider interest of imgui to cater to that population and try to stretch toward being fully skinnable. Because that stretch has a huge cost on me and the other features of imgui.

I implicitly mostly take hint/directions from people using imgui to make games and create tools related to making games.

ocornut commented 7 years ago

It's actually made a little non-trivial when using rounded frames, because the color needs to be set in every vertices. So for a rectangle you can just set the bottom vertices colors and that's trivial, but not for shapes with more vertices it's not. Perhaps for any-shape we could use a "paint" function, seeded by e.g. a gradient structure given 2 colors and 2 points, which can calculate a color given a point in space. Then we apply this function over new vertices as we create them.

I have an old stash with an idea like that, which I'm posting for reference (this is a very rough draft of an idea that needs a fuller implementation).

struct ImDrawPaint
{
    ImVec4 Col0;
    ImVec4 Col1;
    ImVec2 Start;
    ImVec2 Extent;

    void SetLinearGradient(const ImVec2& start, const ImVec2& end, const ImVec4& col0, const ImVec4& col1)
    {
        Col0 = col0;
        Col1 = col1;
        Start = start;
        Extent.x = end.x - start.x;
        Extent.y = end.y - start.y;
    }
    ImU32 Calc(const ImVec2& pos) const;
};

Then add optional const ImDrawPaint* parameter to functions like AddConvexPolyFilled, PathFillConvex, etc. And in those functions when adding a new vertices:

    // Add vertices
    if (paint)
    {
        col = paint->Calc(points[i1]);
        col_trans = col & 0x00ffffff;
    }

Again just a rough idea, it might be a useful feature for the ImDrawList API in general (not necessarily to achieve the idea in OP but a generic tool).

I'm closing it as the OP idea isn't being implemented. If you want to do it and happy to give up on rounded shapes, you may want to replace the calls to AddRectFilled() (e.g the one using ImGuiCol_TitleBgActive) to calling a function that instead of doing PrimReserve(6,4) + PrimRect(a, b, col) does the same PrimReserve but emit the 2 bottom vertices with a different color (either passed as parameter, either computed).