Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplified styling #438

Open
ocornut opened this issue Dec 13, 2015 · 14 comments
Open

Simplified styling #438

ocornut opened this issue Dec 13, 2015 · 14 comments
Labels

Comments

@ocornut
Copy link
Owner

ocornut commented Dec 13, 2015

Following tweet https://twitter.com/relativetoyou/status/675856390070644737
Trying to find a way to setup styles neatly with minimal amount of parameters

Original code is https://github.com/ofnode/ofxImgui/blob/2a3c2a7/src/ofxImgui.cpp#L79-L138

I adjusted it, made some fix but missing stuff, trying to make it more readable. Also added more parameters for testing. which pretty much going against the point but it is trying to figure how what minimal set of parameters could be exposed. Perhaps only "Hue" and some sort of single "Variance"? Some really sure what's right, need some fiddling if anybody wants to play with that and make a definitive "simplified" version with very few parameters that gives decent results.

It doesn't actually look too great now - at some hue it's ok but not all.

Ideally we could add those controls as part of the regular Style Editor so you can use the simplified mode or go advanced to overwrite individual stuff. Then again I somehow expect styling settings to change noticeably when heading toward #184

hue styling

void SetupStyleFromHue()
{
#if 1
    // FIXME: those should become parameters to the function
    static int hue = 140;
    static float col_main_sat = 180.f/255.f;
    static float col_main_val = 161.f/255.f;
    static float col_area_sat = 124.f/255.f;
    static float col_area_val = 100.f/255.f;
    static float col_back_sat = 59.f/255.f;
    static float col_back_val = 40.f/255.f;

    ImGui::Begin("Hue Style");
    ImGui::SliderInt("master hue", &hue, 0, 255);

    float dummy;
    ImVec4 rgb; 
    ImGui::ColorEditMode(ImGuiColorEditMode_HSV);

    ImGui::ColorConvertHSVtoRGB(hue/255.f, col_main_sat, col_main_val, rgb.x, rgb.y, rgb.z);
    ImGui::ColorEdit3("main", &rgb.x);
    ImGui::ColorConvertRGBtoHSV(rgb.x, rgb.y, rgb.z, dummy, col_main_sat, col_main_val);

    ImGui::ColorConvertHSVtoRGB(hue/255.f, col_area_sat, col_area_val, rgb.x, rgb.y, rgb.z);
    ImGui::ColorEdit3("area", &rgb.x);
    ImGui::ColorConvertRGBtoHSV(rgb.x, rgb.y, rgb.z, dummy, col_area_sat, col_area_val);

    ImGui::ColorConvertHSVtoRGB(hue/255.f, col_back_sat, col_back_val, rgb.x, rgb.y, rgb.z);
    ImGui::ColorEdit3("back", &rgb.x);
    ImGui::ColorConvertRGBtoHSV(rgb.x, rgb.y, rgb.z, dummy, col_back_sat, col_back_val);

    ImGui::End();
#endif

    ImGuiStyle& style = ImGui::GetStyle();

    ImVec4 col_text = ImColor::HSV(hue/255.f,  20.f/255.f, 235.f/255.f);
    ImVec4 col_main = ImColor::HSV(hue/255.f, col_main_sat, col_main_val);
    ImVec4 col_back = ImColor::HSV(hue/255.f, col_back_sat, col_back_val);
    ImVec4 col_area = ImColor::HSV(hue/255.f, col_area_sat, col_area_val);

    style.Colors[ImGuiCol_Text]                  = ImVec4(col_text.x, col_text.y, col_text.z, 1.00f);
    style.Colors[ImGuiCol_TextDisabled]          = ImVec4(col_text.x, col_text.y, col_text.z, 0.58f);
    style.Colors[ImGuiCol_WindowBg]              = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
    style.Colors[ImGuiCol_ChildWindowBg]         = ImVec4(col_area.x, col_area.y, col_area.z, 0.00f);
    style.Colors[ImGuiCol_Border]                = ImVec4(col_text.x, col_text.y, col_text.z, 0.30f);
    style.Colors[ImGuiCol_BorderShadow]          = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
    style.Colors[ImGuiCol_FrameBg]               = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
    style.Colors[ImGuiCol_FrameBgHovered]        = ImVec4(col_main.x, col_main.y, col_main.z, 0.68f);
    style.Colors[ImGuiCol_FrameBgActive]         = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_TitleBg]               = ImVec4(col_main.x, col_main.y, col_main.z, 0.45f);
    style.Colors[ImGuiCol_TitleBgCollapsed]      = ImVec4(col_main.x, col_main.y, col_main.z, 0.35f);
    style.Colors[ImGuiCol_TitleBgActive]         = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
    style.Colors[ImGuiCol_MenuBarBg]             = ImVec4(col_area.x, col_area.y, col_area.z, 0.57f);
    style.Colors[ImGuiCol_ScrollbarBg]           = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
    style.Colors[ImGuiCol_ScrollbarGrab]         = ImVec4(col_main.x, col_main.y, col_main.z, 0.31f);
    style.Colors[ImGuiCol_ScrollbarGrabHovered]  = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
    style.Colors[ImGuiCol_ScrollbarGrabActive]   = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_ComboBg]               = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
    style.Colors[ImGuiCol_CheckMark]             = ImVec4(col_main.x, col_main.y, col_main.z, 0.80f);
    style.Colors[ImGuiCol_SliderGrab]            = ImVec4(col_main.x, col_main.y, col_main.z, 0.24f);
    style.Colors[ImGuiCol_SliderGrabActive]      = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_Button]                = ImVec4(col_main.x, col_main.y, col_main.z, 0.44f);
    style.Colors[ImGuiCol_ButtonHovered]         = ImVec4(col_main.x, col_main.y, col_main.z, 0.86f);
    style.Colors[ImGuiCol_ButtonActive]          = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_Header]                = ImVec4(col_main.x, col_main.y, col_main.z, 0.76f);
    style.Colors[ImGuiCol_HeaderHovered]         = ImVec4(col_main.x, col_main.y, col_main.z, 0.86f);
    style.Colors[ImGuiCol_HeaderActive]          = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_Column]                = ImVec4(col_text.x, col_text.y, col_text.z, 0.32f);
    style.Colors[ImGuiCol_ColumnHovered]         = ImVec4(col_text.x, col_text.y, col_text.z, 0.78f);
    style.Colors[ImGuiCol_ColumnActive]          = ImVec4(col_text.x, col_text.y, col_text.z, 1.00f);
    style.Colors[ImGuiCol_ResizeGrip]            = ImVec4(col_main.x, col_main.y, col_main.z, 0.20f);
    style.Colors[ImGuiCol_ResizeGripHovered]     = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
    style.Colors[ImGuiCol_ResizeGripActive]      = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_CloseButton]           = ImVec4(col_text.x, col_text.y, col_text.z, 0.16f);
    style.Colors[ImGuiCol_CloseButtonHovered]    = ImVec4(col_text.x, col_text.y, col_text.z, 0.39f);
    style.Colors[ImGuiCol_CloseButtonActive]     = ImVec4(col_text.x, col_text.y, col_text.z, 1.00f);
    style.Colors[ImGuiCol_PlotLines]             = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
    style.Colors[ImGuiCol_PlotLinesHovered]      = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_PlotHistogram]         = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
    style.Colors[ImGuiCol_PlotHistogramHovered]  = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
    style.Colors[ImGuiCol_TextSelectedBg]        = ImVec4(col_main.x, col_main.y, col_main.z, 0.43f);
    style.Colors[ImGuiCol_TooltipBg]             = ImVec4(col_main.x, col_main.y, col_main.z, 0.92f);
    style.Colors[ImGuiCol_ModalWindowDarkening]  = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
}
@thennequin
Copy link

Very cool, thanks

@ghost
Copy link

ghost commented Dec 14, 2015

I use such method, it allow to start from a "base" color and derivate Active color / Hover colors etc...

ImVec4 ColorFade(ImVec4 rgb, float percents)
{
    ImVec4 r;

    percents /= 100.f;

    r.x = min(1.f, rgb.x * (1.f + percents));
    r.y = min(1.f, rgb.y * (1.f + percents));
    r.z = min(1.f, rgb.z * (1.f + percents));
    r.w = rgb.w;

    return r;
}

@r-lyeh-archived
Copy link

@dougbinks has stated in twitter that you can inverse V if S < 0.1f too to get an alternative (negative) theme for both default and Itamago's themes.

For future reference, this is how I am achieving that (by shadowing ImVec4 locally):

void ApplyItamagosTheme( bool alt = false ) {

    auto ImVec4 = [&alt]( float r, float g, float b, float a ) {
        float h, s, v;
        ImGui::ColorConvertRGBtoHSV( r, g, b, h, s, v );
        if( alt && (s < 0.1f) ) v = 1 - v;
        ImGui::ColorConvertHSVtoRGB( h, s, v, r, g, b );
        return ImColor(r,g,b,a);
    };

    ImGuiStyle& style = ImGui::GetStyle();
    style.Colors[ImGuiCol_Text]                  = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
    style.Colors[ImGuiCol_TextDisabled]          = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
    style.Colors[ImGuiCol_WindowBg]              = ImVec4(0.94f, 0.94f, 0.94f, 1.00f);
    style.Colors[ImGuiCol_ChildWindowBg]         = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
    style.Colors[ImGuiCol_Border]                = ImVec4(0.00f, 0.00f, 0.00f, 0.39f);
    // [ ... ] omitted
}

@dougbinks
Copy link
Contributor

I just do this:

void StyleInvert()
{
    ImGuiStyle& style = ImGui::GetStyle();
    for (int i = 0; i < ImGuiCol_COUNT; i++)
    {
        ImVec4& col = style.Colors[i];
        float H, S, V;
        ImGui::ColorConvertRGBtoHSV( col.x, col.y, col.z, H, S, V );
        if( S < 0.1f )  { V = 1.0 - V; }
        ImGui::ColorConvertHSVtoRGB( H, S, V, col.x, col.y, col.z );
    }
}

@r-lyeh-archived
Copy link

👍

@r-lyeh-archived
Copy link

r-lyeh-archived commented Jan 10, 2018

Random thoughts.

Some more tips for styling:

  • Now that there is some kind of drag'n'drop support: allow drag'n'drop themes like How do themes work hundredrabbits/Themes#2
  • I also like the simplified theming support they provide. Does imgui really need to use that variable list so long?

And since you are using HSL/HSV in the color editor menus, why dont...?:

  • Add buttons for [ slighty shift HUE | random mutate HUE ] for each color.
  • Add button for [ slighty shift HUE | random mutate HUE ] for whole theme.
  • Button for colors.ini export (that can be dragged later! :)

@ocornut
Copy link
Owner Author

ocornut commented Jan 10, 2018

Allow drag'n'drop themes like hundredrabbits/Themes#2

You are free to do so. To me it seems superfluous compared to actually getting the Style system reworked. (Whenever I even see a Style Editor open in an imgui screenshot/video, which is too many times, I know that I haven't done my job of making people able to use the library as-is!)

Does imgui really need to use that variable list so long?

Probably not.
But it also support more features than the HundredRabbits stuff which are carefully crafted design. Some people want simple styling, some people will want to make pro tools with hundred of daily users and will want to tweak every shape, borders and colors for readability.

And since you are using HSL/HSV in the color editor menus, why dont...?:

May use delta in HSL/HSV space but it has to be done in a way that don't cost back-and-forth dozens of HSV conversion every time someone does a couple of Push/Pop for items in a loop.

Essentially I agree with your sentiment, style will be reworked to go toward this direction. I just have so much on my plate already. Also see #1223.

@r-lyeh-archived
Copy link

Just throwing a few easy ideas to complement the new reworking direction.
Not meant in any way to use it as primary direction :)

Btw, the HSV buttons, and the shift/mutate/conversion are meant to be used in the style editor to simplify customizing a bit. Not meant to be used in the end-user API at all! :)

@r-lyeh-archived
Copy link

r-lyeh-archived commented Jan 10, 2018

Also, another idea:

  • Quantize and serialize and z85 encode colors into a long string to allow sharing themes even easier. (with string io.style.SaveTheme() maybe).
  • Then, io.style.LoadTheme("bi^Oc^2n<bhPmUkMw>%t<)'mEVkezsx...etc..."); :)
  • If theming fits a tweet this way would be great for sharing, I guess.

@ocornut
Copy link
Owner Author

ocornut commented Jan 10, 2018

Btw, the HSV buttons, and the shift/mutate/conversion are meant to be used in the style editor to simplify customizing a bit. Not meant to be used in the end-user API at all! :)

Would be good, though it would create an extra gap between the data you see in style editor and the programmatic side, so the UI would need to show data in multiple forms (luckily writing UI is easy for us).

I'm not particularly interested about optimize for "sharing themes", and fluff like "drag and drop a theme", I think it detract us from using dear imgui. Ideally I'd rather have 5-6 themes that are great enough that no one feels the need to spend time thinking about styling. The way toward that is long enough we could focus on this... if someone wants to encode theme in whatever z85 they feel is a fun thing to do, why not.

@ImguiPower
Copy link

Hi, i need something like this but in lua, can someone help me please?

@haldean
Copy link
Contributor

haldean commented Feb 21, 2019

I wrote something similar to this as well, but with a slightly different set of parameters; I found you could get better results if you had separate hues for the accent color and the frame/window color. I posted the code in the gallery thread: #2265 (comment)

@maximvl
Copy link

maximvl commented May 9, 2019

Hi, is it possible to set a theme for a specific window? Thanks!

@LuanDevecchi
Copy link

Hi, is it possible to set a theme for a specific window? Thanks!

you can simply set new style before rendering it then restore the old style

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants