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

Add a Skew property to StyleBoxFlat (3.x) #60592

Merged
merged 1 commit into from
Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion doc/classes/StyleBoxFlat.xml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
</methods>
<members>
<member name="anti_aliasing" type="bool" setter="set_anti_aliased" getter="is_anti_aliased" default="true">
Antialiasing draws a small ring around the edges, which fades to transparency. As a result, edges look much smoother. This is only noticeable when using rounded corners.
Antialiasing draws a small ring around the edges, which fades to transparency. As a result, edges look much smoother. This is only noticeable when using rounded corners or [member skew].
[b]Note:[/b] When using beveled corners with 45-degree angles ([member corner_detail] = 1), it is recommended to set [member anti_aliasing] to [code]false[/code] to ensure crisp visuals and avoid possible visual glitches.
</member>
<member name="anti_aliasing_size" type="float" setter="set_aa_size" getter="get_aa_size" default="0.625">
Expand Down Expand Up @@ -168,15 +168,19 @@
</member>
<member name="expand_margin_bottom" type="float" setter="set_expand_margin" getter="get_expand_margin" default="0.0">
Expands the stylebox outside of the control rect on the bottom edge. Useful in combination with [member border_width_bottom] to draw a border outside the control rect.
[b]Note:[/b] Unlike [member StyleBox.content_margin_bottom], [member expand_margin_bottom] does [i]not[/i] affect the size of the clickable area for [Control]s. This can negatively impact usability if used wrong, as the user may try to click an area of the StyleBox that cannot actually receive clicks.
</member>
<member name="expand_margin_left" type="float" setter="set_expand_margin" getter="get_expand_margin" default="0.0">
Expands the stylebox outside of the control rect on the left edge. Useful in combination with [member border_width_left] to draw a border outside the control rect.
[b]Note:[/b] Unlike [member StyleBox.content_margin_left], [member expand_margin_left] does [i]not[/i] affect the size of the clickable area for [Control]s. This can negatively impact usability if used wrong, as the user may try to click an area of the StyleBox that cannot actually receive clicks.
</member>
<member name="expand_margin_right" type="float" setter="set_expand_margin" getter="get_expand_margin" default="0.0">
Expands the stylebox outside of the control rect on the right edge. Useful in combination with [member border_width_right] to draw a border outside the control rect.
[b]Note:[/b] Unlike [member StyleBox.content_margin_right], [member expand_margin_right] does [i]not[/i] affect the size of the clickable area for [Control]s. This can negatively impact usability if used wrong, as the user may try to click an area of the StyleBox that cannot actually receive clicks.
</member>
<member name="expand_margin_top" type="float" setter="set_expand_margin" getter="get_expand_margin" default="0.0">
Expands the stylebox outside of the control rect on the top edge. Useful in combination with [member border_width_top] to draw a border outside the control rect.
[b]Note:[/b] Unlike [member StyleBox.content_margin_top], [member expand_margin_top] does [i]not[/i] affect the size of the clickable area for [Control]s. This can negatively impact usability if used wrong, as the user may try to click an area of the StyleBox that cannot actually receive clicks.
</member>
<member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 0.6 )">
The color of the shadow. This has no effect if [member shadow_size] is lower than 1.
Expand All @@ -187,6 +191,10 @@
<member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0">
The shadow size in pixels.
</member>
<member name="skew" type="Vector2" setter="set_skew" getter="get_skew" default="Vector2( 0, 0 )">
If set to a non-zero value on either axis, [member skew] distorts the StyleBox horizontally and/or vertically. This can be used for "futuristic"-style UIs. Positive values skew the StyleBox towards the right (X axis) and upwards (Y axis), while negative values skew the StyleBox towards the left (X axis) and downwards (Y axis).
[b]Note:[/b] To ensure text does not touch the StyleBox's edges, consider increasing the [StyleBox]'s content margin (see [member StyleBox.content_margin_bottom]). It is preferable to increase the content margin instead of the expand margin (see [member expand_margin_bottom]), as increasing the expand margin does not increase the size of the clickable area for [Control]s.
</member>
</members>
<constants>
</constants>
Expand Down
50 changes: 34 additions & 16 deletions scene/resources/style_box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,15 @@ bool StyleBoxFlat::is_draw_center_enabled() const {
return draw_center;
}

void StyleBoxFlat::set_skew(Vector2 p_skew) {
skew = p_skew;
emit_changed();
}

Vector2 StyleBoxFlat::get_skew() const {
return skew;
}

void StyleBoxFlat::set_shadow_color(const Color &p_color) {
shadow_color = p_color;
emit_changed();
Expand Down Expand Up @@ -546,7 +555,7 @@ inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_re
}

inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const real_t corner_radius[4],
const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const bool fill_center = false) {
const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const Vector2 &skew, bool fill_center = false) {
int vert_offset = verts.size();
if (!vert_offset) {
vert_offset = 0;
Expand Down Expand Up @@ -589,9 +598,12 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color
color = outer_color;
corner_point = outer_points[corner_index];
}
float x = radius * (float)cos((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.x;
float y = radius * (float)sin((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.y;
verts.push_back(Vector2(x, y));

const float x = radius * (float)cos((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.x;
const float y = radius * (float)sin((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.y;
const float x_skew = -skew.x * (y - ring_rect.get_center().y);
const float y_skew = -skew.y * (x - ring_rect.get_center().x);
verts.push_back(Vector2(x + x_skew, y + y_skew));
colors.push_back(color);
}
}
Expand Down Expand Up @@ -669,10 +681,12 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
return;
}

bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0);
bool aa_on = rounded_corners && anti_aliased;
const bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0);
// Only enable antialiasing if it is actually needed. This improve performances
// and maximizes sharpness for non-skewed StyleBoxes with sharp corners.
const bool aa_on = (rounded_corners || !skew.is_equal_approx(Vector2())) && anti_aliased;

bool blend_on = blend_border && draw_border;
const bool blend_on = blend_border && draw_border;

Color border_color_alpha = Color(border_color.r, border_color.g, border_color.b, 0);
Color border_color_blend = (draw_center ? bg_color : border_color_alpha);
Expand Down Expand Up @@ -719,24 +733,24 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
Color shadow_color_transparent = Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);

draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner,
shadow_rect, shadow_inner_rect, shadow_color, shadow_color_transparent, corner_detail);
shadow_rect, shadow_inner_rect, shadow_color, shadow_color_transparent, corner_detail, skew);

if (draw_center) {
draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner,
shadow_inner_rect, shadow_inner_rect, shadow_color, shadow_color, corner_detail, true);
shadow_inner_rect, shadow_inner_rect, shadow_color, shadow_color, corner_detail, skew, true);
}
}

// Create border (no AA).
if (draw_border && !aa_on) {
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
border_style_rect, infill_rect, border_color_inner, border_color, corner_detail);
border_style_rect, infill_rect, border_color_inner, border_color, corner_detail, skew);
}

// Create infill (no AA).
if (draw_center && (!aa_on || blend_on || !draw_border)) {
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
infill_rect, infill_rect, bg_color, bg_color, corner_detail, true);
infill_rect, infill_rect, bg_color, bg_color, corner_detail, skew, true);
}

if (aa_on) {
Expand Down Expand Up @@ -768,7 +782,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
aa_border_width[MARGIN_RIGHT], aa_border_width[MARGIN_BOTTOM]);
// Create infill within AA border.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
infill_inner_rect_aa, infill_inner_rect_aa, bg_color, bg_color, corner_detail, true);
infill_inner_rect_aa, infill_inner_rect_aa, bg_color, bg_color, corner_detail, skew, true);
}

if (!blend_on || !draw_border) {
Expand All @@ -779,7 +793,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {

// Create infill fake AA gradient.
draw_ring(verts, indices, colors, style_rect, adapted_corner,
infill_rect_aa, infill_rect, bg_color, alpha_bg, corner_detail);
infill_rect_aa, infill_rect, bg_color, alpha_bg, corner_detail, skew);
}
}

Expand All @@ -793,17 +807,17 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {

// Create border.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
border_style_rect_aa, ((blend_on) ? infill_rect : infill_rect_aa), border_color_inner, border_color, corner_detail);
border_style_rect_aa, ((blend_on) ? infill_rect : infill_rect_aa), border_color_inner, border_color, corner_detail, skew);

if (!blend_on) {
// Create inner border fake AA gradient.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
infill_rect_aa, infill_rect, border_color_blend, border_color, corner_detail);
infill_rect_aa, infill_rect, border_color_blend, border_color, corner_detail, skew);
}

// Create outer border fake AA gradient.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
style_rect_aa, border_style_rect_aa, border_color, border_color_alpha, corner_detail);
style_rect_aa, border_style_rect_aa, border_color, border_color_alpha, corner_detail, skew);
}
}

Expand Down Expand Up @@ -854,6 +868,9 @@ void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &StyleBoxFlat::set_draw_center);
ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxFlat::is_draw_center_enabled);

ClassDB::bind_method(D_METHOD("set_skew", "skew"), &StyleBoxFlat::set_skew);
ClassDB::bind_method(D_METHOD("get_skew"), &StyleBoxFlat::get_skew);

ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &StyleBoxFlat::set_shadow_color);
ClassDB::bind_method(D_METHOD("get_shadow_color"), &StyleBoxFlat::get_shadow_color);

Expand All @@ -875,6 +892,7 @@ void StyleBoxFlat::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "bg_color"), "set_bg_color", "get_bg_color");

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "skew"), "set_skew", "get_skew");

ADD_GROUP("Border Width", "border_width_");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_left", PROPERTY_HINT_RANGE, "0,1024,1"), "set_border_width", "get_border_width", MARGIN_LEFT);
Expand Down
4 changes: 4 additions & 0 deletions scene/resources/style_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class StyleBoxFlat : public StyleBox {

bool draw_center;
bool blend_border;
Vector2 skew;
bool anti_aliased;

int corner_detail;
Expand Down Expand Up @@ -198,6 +199,9 @@ class StyleBoxFlat : public StyleBox {
void set_draw_center(bool p_enabled);
bool is_draw_center_enabled() const;

void set_skew(Vector2 p_skew);
Vector2 get_skew() const;

void set_shadow_color(const Color &p_color);
Color get_shadow_color() const;

Expand Down