Immediate-Mode-UI / Nuklear

A single-header ANSI C immediate mode cross-platform GUI library
https://immediate-mode-ui.github.io/Nuklear/doc/index.html
8.89k stars 533 forks source link

Don't draw outside the bounds of a button. #587

Closed mackron closed 7 months ago

mackron commented 8 months ago

When drawing the border of a button it's done so via nk_stroke_rect(). The problem with this is when a line is stroked, half of the width of the line is on one side, and the other half is on the other side. In the case of a button, this results in half of the border being drawn outside the bounds of the button. This commit pulls in the border rectangle by half the border width before performing the stroke so as to avoid any overflow.

The practical issue with this is clipping against the parent. Consider the layout below:

    if (nk_begin(&ctx, "Menu", nk_recti(300, 64, 400, 400), NK_WINDOW_BORDER | NK_WINDOW_TITLE | NK_WINDOW_NO_SCROLLBAR)) {
        nk_layout_row_dynamic(&ctx, 64, 1);
        if (nk_button_label(&ctx, "Single Player")) {
            ...
        }
    }
    nk_end(&ctx);

With this code, the left side of the button is clipped against the parent window, but because half of the border is overflowing the button's bounds, it's resulting in one pixel being clipped. I've set the border to 2 pixels to demonstrate: image

You can see that the left border is thinner compared to the others. With the change in this PR it now looks like this which looks a lot cleaner and professional: image

Note that this change will result in slightly different visual output to previous versions. I'd be happy to to add a flag somewhere to explicitly enable this particular change if that's preferable. Either way, in my opinion there needs to be some way to control this behavior, be it by default or via flag, because in my mind drawing outside the bounds of a control should be considered very bad practice.