-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Better flat stylebox with rounded corners #8899
Conversation
DEPRECATED! applying rounded corners to everything (older version -> broken ...) how top left right bottom colors and border blend behave with rounded corners: |
@volzhs since you are very familiar with style boxes could you do some testing? I can't change line width so I'm using multiple lines. I think performance wise the whole rounded style box thing is a desaster.. if someone could give some tips/fix some gels 3 functions to make it work would be highly appreciated. |
Fixed a couple of more things performance wise and added a couple of more features. |
ec5ca8c
to
f4fb105
Compare
Yo, found few problems :) Things that may be unnoticed. There are also problems when you modulate color to change Opacity. Original StyleBoxFlat also had problem with it ^_^' |
Here is a branch with some theme changes using rounded style boxes: |
@n-pigeon Thank you! |
@n-pigeon I also draw 10 lines max, reason is, that you can get it really buggy and slow if you allow more... I think at the end I will have to go for full polygons anyways... damn that will be a little more work ;) or I limit border radius to 10.. or 20 might still run fine. too big of a limitation? |
65c21df
to
3fc41b7
Compare
rebased. on master @akien-mga should I squash all the commits? or separate them in 1-3? |
Full polygon will be probably needed sooner or later :) If you will need some help with this stuff I would gladly help. |
@toger5 did you see my code comments? |
@Zylann sorry I did not. and I think the rebase removed them. let me check my mail if I still can get them. -- also no email |
scene/resources/style_box.cpp
Outdated
if (filled) { | ||
//the circle has to be drawn twice, otherwise the circles for the corners are not visible | ||
//super buggy ;) | ||
vs->canvas_item_add_circle(p_canvas_item, corners[i], (float)corner_radius[i], col); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could have a draw_filled_arc to divide polycount by 4.
Also drawing twice sounds like a bug to fix in rendering, we should keep track of it so that we revert it to one draw later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is one draw now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filled arc is a really good idea!! also fixes some of the artefacts when drawing with transparency
scene/resources/style_box.cpp
Outdated
rad = 0; | ||
inner_corner_radius[i] = rad; | ||
} | ||
int *p = &inner_corner_radius[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, are you returning a pointer to a local here? Also why not using it internally to functions instead of expecting a pointer in others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inline PoolIntArray get_offset_corner_radius(int offset, PoolIntArray corner_radius) {
PoolIntArray inner_corner_radius = PoolIntArray();
for (int i = 0; i < 4; i++) {
int rad = corner_radius[i] - offset;
if (rad < 0)
rad = 0;
inner_corner_radius.append(rad);
}
return inner_corner_radius;
}
is what I changed it to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well it's not that good either, you are allocating an array (which is also locking a mutex at every append) everytime you draw a corner. I don't understand why you created this function in the first place tbh, I feel like you don't really need it (or there must be a better way to prevent copy/paste)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to recalculate the corner radius in a couple of situations: drawing inner part of the box + drawing the border lines...
Should I allocate the memory inside the draw_rounded_rect function and just pass a ref to the function which modifies it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is you probably don't need to allocate any memory^^ you could do that to an int[4]
allocated on the stack. I see you use this function just to not copy/paste a reduction or increase in radius, so better make it so it's a zero-cost compression ;)
Also, some advice about PoolVectors: if you want to access them by index, whenever possible, use Read and Write objects, they will lock the array only once, resulting in faster access ;) (because using operator [] directly on the vector is slower if done repeatedly in a loop)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for the explanation on read write objects. At the beginning I thought that would be the only way to use poolArray. than I found out you can use []... seemed so much simpler ;)
But now I know...
scene/resources/style_box.cpp
Outdated
ClassDB::bind_method(D_METHOD("get_corner_radius_TL"), &StyleBoxFlat::get_corner_radius_TL); | ||
ClassDB::bind_method(D_METHOD("get_corner_radius_TR"), &StyleBoxFlat::get_corner_radius_TR); | ||
ClassDB::bind_method(D_METHOD("get_corner_radius_BL"), &StyleBoxFlat::get_corner_radius_BL); | ||
ClassDB::bind_method(D_METHOD("get_corner_radius_BR"), &StyleBoxFlat::get_corner_radius_BR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming convention should be lowercase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that makes a lot of sense since it also looks super wired in the inspector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
Looks like I forgot to click the "Submit review" button. I'm not used to this yet^^ |
I was thinking that I might switch to a full polygon implementation. This results in better performance, cleaner code, better looks and also the option for border thickness. border thickness would be great: |
I was thinking about ability to control thickness for all sides not just one global. |
Yea thats also what I was proposing I have decided now to reimplement the whole thing with polygons. Hope ill find time soon |
What do you mean with polygons? Also I implemented a line mesh builder in scene/2d/ if you need one ;) |
@Zylann Currently I'm using draw rect, draw circle, draw line (of course the circle is using polygons too at the end) For the border I literally draw lines around the center... (got inspired by the super Hacky previous implementation of style box rendering: for the blend border multiple boxes were just drawn on top of each other with different sizes and colors) |
@toger5 I like that approach. |
Reimplemented the whole thing with polygons! |
@volzhs I the branch with the poly implementation is uploaded. Ready for testing. |
This is the current naming for styleBoxFlat:
Thoughts? I renames |
I'm not sure about Maybe |
I did another big renaming. Can't get it to compile right now though: Some issue with bindings to ClassDB... |
62f1965
to
af51c7e
Compare
@karroffel @akien-mga |
Oh @toger5 there are conflicts now, can you resolve them? Then I'll merge :) |
Nice. Cant do it right now bu i will tomorrow! |
af51c7e
to
17d3058
Compare
Although there are no conflicts anymore don't merge yet. |
17d3058
to
177b1ef
Compare
sbflat->set_dark_color(dark); | ||
sbflat->set_light_color(bright); | ||
sbflat->set_border_color_all(bright); | ||
// sbflat->set_dark_color(dark); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is no longer relevant, best just remove it.
scene/resources/style_box.cpp
Outdated
} | ||
//DRAW OUTER BORDER AA | ||
if (!(border_width[0] == 0 && border_width[1] == 0 && border_width[2] == 0 && border_width[3] == 0)) { | ||
// for (int i = 0; i < 4; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove commented out code.
scene/resources/style_box.cpp
Outdated
} | ||
} else if (!(border_width[0] == 0 && border_width[1] == 0 && border_width[2] == 0 && border_width[3] == 0)) { | ||
//DRAW INNER BORDER AA | ||
// for (int i = 0; i < 4; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
@@ -43,6 +43,14 @@ enum Margin { | |||
MARGIN_BOTTOM | |||
}; | |||
|
|||
enum Corner { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's used only for StyleBoxFlat, should it really go in math_2d.h or could it be kept in style_box_flat.h?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I though it might could be used some where else so it does not hurt to give access to it by just importing math 2d...
But if you think it is improbable that it will be used seomwhere else I move it to style box
I'd prefer to have the two documentation commits in a separate PR after this one is merged. If there were big issues in this one and we wanted to partially or totally revert it, the documentation changes would make it very difficult (also if anyone changes the documentation before this PR is merged, you might have to rebase). |
scene/resources/style_box.cpp
Outdated
|
||
ClassDB::bind_method(D_METHOD("set_border_color", "margin", "color"), &StyleBoxFlat::set_border_color); | ||
ClassDB::bind_method(D_METHOD("get_border_color", "margin"), &StyleBoxFlat::get_border_color); | ||
// ClassDB::bind_method(D_METHOD("set_border_color", "margin", "color"), &StyleBoxFlat::set_border_color); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just get rid of comments, really.
scene/resources/style_box.cpp
Outdated
ADD_PROPERTYI(PropertyInfo(Variant::COLOR, "border_color_bottom"), "set_border_color", "get_border_color", MARGIN_BOTTOM); | ||
ADD_GROUP("Border", "border_"); | ||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "border_color"), "set_border_color", "get_border_color"); | ||
// ADD_PROPERTYI(PropertyInfo(Variant::COLOR, "border_color_top"), "set_border_color", "get_border_color", MARGIN_TOP); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get rid of those.
I still think there are too many commits for the overall changes. A rebase like this would be better IMO:
|
@akien ty for thw review! |
- now use polygons! - renamed blend -> blend_border - draw_center -> filled - GDScript biding
- corner radius bindings - shadow - antiAliasing - CornerDetail
177b1ef
to
b7689d9
Compare
- corner and border are decreased if necassary to achoieve clean stylboxes - prohibits wired drawing artifacts when using wrong values - corner radius are relative to the partner corner when they would result in glitches
- removed only the bindings because the drawing code is not done yet - kept c++ functions for setting individual border color for future implementation
@akien-mga rebased + squashed + removed comments. |
b7689d9
to
701fb55
Compare
from the meeting: @reduz approves but would like to hear also @karroffel and @akien-mga voice |
This is still kind of WIP
NOW it's almost done though, it can be used but some features would still be nice to get added, check issues at the end of this post
what is supported for now:
UPDATED:
most of this is relatively easy to understand.
basically allows for rounded corners and different color for each corner.
how it works:
old version:
I draw rounded rectangles by first adding circles in the corners with the right offset and the right radius. than I draw four rectangles for each edge. (need for because it supports different radius for each corner).I draw rounded rings by creating two arrays of certs which have a defined gap between them and fill them with polygons + set the color according to settings (if border_blend inner and outer arrays have different colors)
I also use that function to draw the shadow. with outer color = transparent
The aa will be done by creating another outer ring around the border and the center which will fade to transparent too.
The infill has other indexing logic but I also generate a vertex array in the shape of a rounded ring. just one though and than fill it with triangles from right to left.
issues:
empty centers are not possible with rounded corners the circles are no than inside the circle:
this could be fixed if I have some kind of masking feature, or if I draw 90 degree arc's instead of circles for style boxes without center... (second might be easiest)
the history needs some cleanup
There is an issue with the circle drawing. it seems like only every second (or random...) circle is drawn. It works when I just do draw 2 circles on top of each other... which I do right not.
the polygon drawing is broken... so I copied code from this pr: Update color_picker and implement _draw_polygon. Fixes #8372 #8425
there are still some comments which should get removed
border color for rounded is still off
wrong type for GDScript and Inspector (float should be color)
reimplementing everything with polygons
make blend and fill work with polygons
shadows
different border colors with polygons
different border width with polygons
expand margin
rename: set_all_border_width -> set_border_width_all
rename set_all_corner_radius -> set_corner_radius_all
rename set_all_border_color -> set_border_color_all
decide to only allow half_height corner radius and border or improove the limit calculation (also take the corner radius + the border into account) (needs to be done I NEED FEEDBACK WHAT BEHAVIOUR IS WANTED)
antiAliasing
anti_aliasing sizing (grow(-1)) (@n-pigeon)
corner_segments as a property ( @n-pigeon )
corner bug which only shows 100 * (corner_detail - 1) / corner_detail
infill not fully drawn (missing last try)
additional border is not supported anymore. need to use expand margin + border width. Change that in the default theme!
individual corner and border color
CANCELD FOR FIRST VERSION
color gradient (needed?)
CANCELD FOR FIRST VERSION
added documentation.