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

Improving border #447

Open
green-zone opened this issue Dec 21, 2015 · 33 comments
Open

Improving border #447

green-zone opened this issue Dec 21, 2015 · 33 comments
Labels

Comments

@green-zone
Copy link

The original border creates a 3D effect only for himself.
I illustrate this on screenshot:
screen 1
And in the following screenshot you can see what the result I want to receive
screen 2
and another screenshot (what i like)
screen 3

Question: What i need change in RenderFrame() function of imgui.cpp?

Original actions:
window->DrawList->AddRect(p_min+ImVec2(1,1), p_max, window->Color(ImGuiCol_BorderShadow), rounding);
window->DrawList->AddRect(p_min, p_max-ImVec2(1,1), window->Color(ImGuiCol_Border), rounding);

May be remove one of them and add 2 functions AddLine()

Sorry, I'm not a programmer.

@ocornut
Copy link
Owner

ocornut commented Dec 21, 2015

You'd have to add two lines and a parameter to RenderFrame() to decide which of the two effects to use. Not a bad idea, may add that someday.

@green-zone
Copy link
Author

I think it could be interesting also
Out-screen effect for button
In-screen effect for pressed button.
But,it need change the color of the border (locally). May be not good.
GitHub Logo

@ocornut
Copy link
Owner

ocornut commented Dec 21, 2015

I am going to have to bail out on that for master for now, but keep a note to it for when seriously working on #184

Maintaining borders has been already time confusing for little benefit (lots of those changes have subtle effects on five other things) and I would rather see how much we actually use them in an improved visuals. The library won't try to cater for every possible visual design.

Windows-style border work if the background color is known and consistent but above variable or unreliable background color (e.g. transparent window over a game output) they don't, this is why I used a two color scheme for borders.

@ocornut ocornut closed this as completed Dec 21, 2015
@green-zone
Copy link
Author

Also, border can be single-border but with switchable Alpha or Color
border color

@green-zone
Copy link
Author

Current duble-border is visually heavy and useless.
I do small hacks in RenderFrame() function of imgui

Remove one AddRect() function and add two AddLine() functions.
Also, change (bool border) parameter to (enum BorderType) parameter.
BorderType content:
NO (no border)
SOLID (single rectangle border)
OUT (two rectangles Screen-Out effect)
IN (two rectangles Screen-In effect)

On screenshots you can see borders-effects for Headers, Buttons, Input areas.
Dark theme
Dark theme
Light theme
Light theme

@green-zone
Copy link
Author

If the buttons (areas) are flat - visually heavy understand is it action area or do nothing.

@adam4813
Copy link

Looks great! It really helps to give it more of a widget look.

-Adam

@ocornut ocornut reopened this Dec 28, 2015
@ocornut
Copy link
Owner

ocornut commented Dec 28, 2015

That's nice, how do it perform on the default theme?
if you want to polish that into a PR it'd be nice.

@green-zone
Copy link
Author

On default theme i need tweak background color (my viewport is black)
aaa

@green-zone
Copy link
Author

Small note:
Default border can be used for group of elements if switch dark and light borders.
goup1
goup2

@ocornut
Copy link
Owner

ocornut commented Dec 28, 2015

Don't make it look too much like Windows 3.1 :)

@green-zone
Copy link
Author

:) I like XP and Classic theme.
XP developers do it for slow hardware - visual min. and intuitive without detriment to performance and functionality. (unlike 7 and up)
Quadratisch. Praktisch. Gut. :)

@green-zone
Copy link
Author

Next conception:
Maximal change all AddRect() AddLine() functions to AddRectFilled() - it may be good for performance.
On screenshot - top and left line needed for all elements which may leave the zone of the window
(window itself , menu items, etc) Elements in window zone will be without these lines.

concept

@ocornut
Copy link
Owner

ocornut commented Dec 29, 2015

Problem with using layers of filled rectangles is that it won't work with transparent windows.

The hard part isn't coming with one design, but writing code that can be merged back in master for the larger interest. This design is nice but definitively can't become the default visual design for imgui. We should aim for something more modern and flat e.g #184. If the system can handle both types it is a nice extra but we still need to focus on one. So while your work on the code it's better if you can think of it as optional (e.g. the enum for border is a good idea).

Also note that I made fixes a few days about about the positioning of AddRect, it was off by 1 (#457).

@green-zone
Copy link
Author

Yes, but i do what i need. I am not a programmer - i am a user
For example:
I do not use transparent of windows never. It is enough to roll headline of windows.
And rounded elements good look but may be bad for performance.
It need be practical enough.
(imho)

@Cthutu
Copy link

Cthutu commented Dec 29, 2015

True, but that's not what Omar is saying. He cannot put your changes in the main code base because it causes problems with transparent windows. So your code has to stay your code.

@ocornut
Copy link
Owner

ocornut commented Dec 29, 2015

Well ideally green-zone's code could be designed in a way that I will want and be able to merge it because it is beneficial to ImGui for everyone. But it is also fine if you fork and it stays your code only. Either way are possible :)

@ZahlGraf
Copy link

@green-zone This is really a nice work you did. :)

@Cthutu
Copy link

Cthutu commented Dec 29, 2015

The correct way is to render off-screen to an image then render the image
afterwards. That way there won't be a problem with transparency. Not sure
how that would work with imgui as I am not 100% with the workings yet.

On Tue, 29 Dec 2015 at 07:56 omar notifications@github.com wrote:

Well ideally green-zone's code could be designed in a way that I will want
and be able to merge it because it is beneficial to ImGui for everyone. But
it is also fine if you fork and it stays your code only. Either way are
possible :)


Reply to this email directly or view it on GitHub
#447 (comment).

@ocornut
Copy link
Owner

ocornut commented Dec 29, 2015

That wouldn't be practical nor efficient with the current system.
Another possibility are that visuals could be pre-rendered into the atlas texture, split into 9 parts, and then all sort of frames can be rendered quickly using 9 quads. We could even render rounded corners of various size into the atlas texture.

@green-zone
Copy link
Author

Small screen
smscr
And i found screens from Torque game engine (old version) This is ingame UI.
a1
a2

@ocornut
Copy link
Owner

ocornut commented Dec 30, 2015

Not my cup of tea, but I'm afraid if you go this path you will be faced with a sort of uncanny valley where people have different expectation of what the UI library can and should do for do. We have a lot of work to do with fill those features gap :)

@green-zone
Copy link
Author

I'm doing it for themselves :) (developer interface - not for final-user)

@green-zone
Copy link
Author

I solved all their questions with the border.
This works well (as I expected)
Maybe close?

@ocornut
Copy link
Owner

ocornut commented Dec 30, 2015

Could you post your patch here, at least for the records?

@green-zone
Copy link
Author

//  IT QUICK DEV (NOT CLEAN)
// Need:
// 1 BorderType enum with (NO SOLID OUT_I OUT_II IN_I IN_II EXT) types in imgui_internal.h
// 2 In imgui.cpp found and change all RenderFrame functions (replace bool border param to BorderType) 
void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, BorderType b_type, float rounding)
{
    ImGuiWindow* window = GetCurrentWindow();

    if (b_type != NO)
    {
        ImVec2 offset_i = ImVec2(1,1);
        ImVec2 offset_ii = ImVec2(2,2);

        if (b_type == SOLID) // single-border
        {
            // Black rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_i, GetColorU32(ImGuiCol_BorderShadow), rounding);
        }
        else if (b_type == OUT_I) // Out-screen level 1
        {
            // Black rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_i, GetColorU32(ImGuiCol_BorderShadow), rounding);
            // White rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max, GetColorU32(ImGuiCol_Border), 1.0f);
        }
        else if (b_type == IN_I) // In-screen level 1
        {    
            // White rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_i, GetColorU32(ImGuiCol_Border), 1.0f);
            // Black rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max, GetColorU32(ImGuiCol_BorderShadow), rounding);
        }
        else if (b_type == OUT_II) // Out-screen level 2
        {
            ImGuiStyle& style = ImGui::GetStyle();
            ImVec4 color = style.Colors[ImGuiCol_Button];
            ImVec4 mid_col = ImVec4(color.x * 0.5f, color.y * 0.5f, color.z * 0.5f, 1.0f);

            // Black rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_ii, GetColorU32(ImGuiCol_BorderShadow), rounding);            
            // White rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_i, GetColorU32(ImGuiCol_Border), rounding); 
            // Middle rectangle
            style.Colors[ImGuiCol_Button] = mid_col;
            window->DrawList->AddRectFilled(p_min, p_max + offset_i, GetColorU32(ImGuiCol_Button), rounding); 
            style.Colors[ImGuiCol_Button] = color;
        }
        else if (b_type == IN_II) // In-screen level 2
        {
            // White rectangle
            window->DrawList->AddRectFilled(p_min - offset_ii, p_max + offset_ii, GetColorU32(ImGuiCol_Border), rounding);

            ImGuiStyle& style = ImGui::GetStyle();
            ImVec4 color = style.Colors[ImGuiCol_WindowBg];
            ImVec4 mid_col = ImVec4(color.x * 0.5f, color.y * 0.5f, color.z * 0.5f, 1.0f);

            // Middle rectangle
            style.Colors[ImGuiCol_WindowBg] = mid_col;
            window->DrawList->AddRectFilled(p_min - offset_ii, p_max + offset_i, GetColorU32(ImGuiCol_WindowBg), rounding); 
            style.Colors[ImGuiCol_WindowBg] = color;

            // Neitral rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_i, GetColorU32(ImGuiCol_WindowBg), rounding); 

            // Black rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max, GetColorU32(ImGuiCol_BorderShadow), rounding); 
        }
        else if (b_type == EXT) // OUT_II with advanced left and top border
        {
            // Black rectangle
            window->DrawList->AddRectFilled(p_min - offset_ii, p_max + offset_ii, GetColorU32(ImGuiCol_BorderShadow), rounding);             

            // Neitral rectangle
            window->DrawList->AddRectFilled(p_min - offset_ii, p_max + offset_i, GetColorU32(ImGuiCol_WindowBg), rounding); 

            ImGuiStyle& style = ImGui::GetStyle();
            ImVec4 color = style.Colors[ImGuiCol_WindowBg];
            ImVec4 mid_col = ImVec4(color.x * 0.5f, color.y * 0.5f, color.z * 0.5f, 1.0f);

            // Middle rectangle
            style.Colors[ImGuiCol_WindowBg] = mid_col;
            window->DrawList->AddRectFilled(p_min - offset_i, p_max + offset_i, GetColorU32(ImGuiCol_WindowBg), rounding); 
            style.Colors[ImGuiCol_WindowBg] = color;

            // White rectangle
            window->DrawList->AddRectFilled(p_min - offset_i, p_max, GetColorU32(ImGuiCol_Border), rounding);
        }
    }
    // target rectangle        
    window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);

}

@ocornut
Copy link
Owner

ocornut commented Dec 31, 2015

Thanks! I'll keep this for reference.

@ocornut ocornut closed this as completed Dec 31, 2015
@ocornut ocornut reopened this Aug 15, 2017
@ocornut ocornut removed the dropped label Nov 17, 2017
ocornut added a commit that referenced this issue Nov 19, 2017
…rs are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. (#707, fix #819, #1031, ref #1019, ref #447)
@ocornut ocornut mentioned this issue Jan 5, 2018
@green-zone
Copy link
Author

Borders
Small experiment - Border for Group
It is easy to use Spacing(), Dummy() and SameLine() functions.
For arrange the elements and provide space for the frame.
Then, draw border with GetItemRectMin() (Max) and Style.ItemSpacing
Only, Left - Right buttons positions must be higher and no Label (maybe not needed)

Good, but my question is different.
Many people come to terms with me that I need a way to render small fonts without antialiasing (at all).
Here (in the picture) one font - ProggyClean.ttf
The smoothed version is also loaded as the default font (compressed data)

We need a way to do the same as the default.
How did you do that?

@ocornut
Copy link
Owner

ocornut commented Feb 11, 2019

How to embed font exactly the same way as the default font is implemented? (without smoothing)

ProggyClean is a bitmap font so it can be rendered pixel perfect easily.

For any other font, you can try with OversampleH=2, OversampleV=1, higher size, or use imgui_freetype to improve sharpness. It's not an easy problem to solve with the current rendering technique.

@ocornut
Copy link
Owner

ocornut commented Feb 12, 2019

This is all off-topic in a thread called "Improving border".

@ocornut ocornut reopened this Feb 12, 2019
@ocornut
Copy link
Owner

ocornut commented Feb 12, 2019

I am reopening because the border discussion/references are useful. Please discuss fonts in a different thread.

@green-zone
Copy link
Author

fonts_done
Sorry me.
I deleted 3 posts about fonts (were above) and publish this as a solution.

-1- Make (or download) a pixel font (fon, fnt or ttf).
Or bitmap pictures of the letters of the font in any editor.
The font (should) be pixel.

-2- Create a vector font based on it (ttf)
Font creation programs (FontLab, FontForge and others)
let you create a vector font from a raster.
In the font settings, set the desired size.

-3- In Dear imgui generate multiple fonts
from one ttf file, but with different sizes.
One of the sizes will look sharp (as the default font)

Note:
There will be no smoothing for just one size.
With other sizes, the font will be smoothed.
You need to experimentally choose the right size.
in the font creation program and in the Dear imgui
The default font for other sizes is also smeared :)
ProggyClean also is not a bitmap font (it is Outline vector ttf font)

@ocornut
Copy link
Owner

ocornut commented Feb 25, 2019 via email

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

5 participants