Skip to content

Commit

Permalink
Add antialiased, draw outline and line color/width properties to Colo…
Browse files Browse the repository at this point in the history
…rRect

This exposes recently-added CanvasItem functionality to the ColorRect node,
so that custom drawing methods don't need to be called if you want to benefit
from antialiasing or non-filled rects.

The outline is drawn on top of the background, which can also now be disabled.
  • Loading branch information
Calinou committed Jun 29, 2024
1 parent 811ce36 commit 0c239bd
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 6 deletions.
2 changes: 1 addition & 1 deletion doc/classes/CanvasItem.xml
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@
<param index="3" name="width" type="float" default="-1.0" />
<param index="4" name="antialiased" type="bool" default="false" />
<description>
Draws a rectangle. If [param filled] is [code]true[/code], the rectangle will be filled with the [param color] specified. If [param filled] is [code]false[/code], the rectangle will be drawn as a stroke with the [param color] and [param width] specified. See also [method draw_texture_rect].
Draws a rectangle. If [param filled] is [code]true[/code], the rectangle will be filled with the [param color] specified. If [param filled] is [code]false[/code], the rectangle will be drawn as a stroke with the [param color] and [param width] specified. See also [method draw_texture_rect] and the [ColorRect] node.
If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code].
If [param antialiased] is [code]true[/code], half transparent "feathers" will be attached to the boundary, making outlines smooth.
[b]Note:[/b] [param width] is only effective if [param filled] is [code]false[/code].
Expand Down
24 changes: 21 additions & 3 deletions doc/classes/ColorRect.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ColorRect" inherits="Control" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A control that displays a solid color rectangle.
A control that displays a colored rectangle, with or without an outline.
</brief_description>
<description>
Displays a rectangle filled with a solid [member color]. If you need to display the border alone, consider using a [Panel] instead.
Displays a rectangle filled with a solid [member color]. See also [ReferenceRect] for an alternative designed for UI debugging.
[b]Tip:[/b] By having a [ColorRect] span the entire viewport, it can be used to create 2D post-processing shaders using a shader of type [code]canvas_item[/code] on the node.
</description>
<tutorials>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/2712</link>
</tutorials>
<members>
<member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased" default="false">
If [code]true[/code], the rectangle's edges and outline are antialiased.
[b]Note:[/b] Antialiasing only works if [member line_width] is greater than [code]0[/code].
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)" keywords="colour">
The fill color of the rectangle.
The rectangle's fill color. Only effective if [member draw_background] is [code]true[/code].
</member>
<member name="draw_background" type="bool" setter="set_draw_background" getter="is_drawing_background" default="true">
If [code]true[/code], draws the fill color defined in [member color] as the node's background.
</member>
<member name="draw_outline" type="bool" setter="set_draw_outline" getter="is_drawing_outline" default="false">
If [code]true[/code], draws the line color defined in [member line_color] as the node's outline. The outline is always drawn on top of the background.
</member>
<member name="line_color" type="Color" setter="set_line_color" getter="get_line_color" default="Color(1, 1, 1, 1)">
The rectangle's outline color. Only effective if [member draw_outline] is [code]true[/code].
</member>
<member name="line_width" type="float" setter="set_line_width" getter="get_line_width" default="1.0">
The outline's width. If set to a negative value, the outline is always drawn 1 pixel wide and does not scale with viewport zoom. Only effective if [member draw_outline] is [code]true[/code].
[b]Note:[/b] Antialiasing (see [member antialiased]) is only supported with positive line widths.
</member>
</members>
</class>
3 changes: 2 additions & 1 deletion doc/classes/ReferenceRect.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
A rectangle hint for designing UIs.
</brief_description>
<description>
A rectangle box that displays only a colored border around its rectangle. It is used to visualize the extents of a [Control].
A rectangle box that displays only a colored border around its rectangle. It is used to visualize the extents of a [Control] and is intended to be used for debugging purposes.
See also [ColorRect] for a more flexible alternative.
</description>
<tutorials>
</tutorials>
Expand Down
106 changes: 105 additions & 1 deletion scene/gui/color_rect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@

#include "color_rect.h"

void ColorRect::set_draw_background(bool p_draw_background) {
if (draw_background == p_draw_background) {
return;
}
draw_background = p_draw_background;
queue_redraw();
notify_property_list_changed();
}

bool ColorRect::is_drawing_background() const {
return draw_background;
}

void ColorRect::set_color(const Color &p_color) {
if (color == p_color) {
return;
Expand All @@ -42,17 +55,108 @@ Color ColorRect::get_color() const {
return color;
}

void ColorRect::set_antialiased(bool p_antialiased) {
if (antialiased == p_antialiased) {
return;
}
antialiased = p_antialiased;
queue_redraw();
}

bool ColorRect::is_antialiased() const {
return antialiased;
}

void ColorRect::set_draw_outline(bool p_draw_outline) {
if (draw_outline == p_draw_outline) {
return;
}
draw_outline = p_draw_outline;
queue_redraw();
notify_property_list_changed();
}

bool ColorRect::is_drawing_outline() const {
return draw_outline;
}

void ColorRect::set_line_color(const Color &p_line_color) {
if (line_color == p_line_color) {
return;
}
line_color = p_line_color;
queue_redraw();
}

Color ColorRect::get_line_color() const {
return line_color;
}

void ColorRect::set_line_width(float p_line_width) {
if (line_width == p_line_width) {
return;
}
line_width = p_line_width;
queue_redraw();
}

float ColorRect::get_line_width() const {
return line_width;
}

void ColorRect::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
draw_rect(Rect2(Point2(), get_size()), color);
if (draw_background) {
draw_rect(Rect2(Point2(), get_size()), color, true, -1.0f, antialiased);
}

if (draw_outline) {
// Draw the rect's line on top of the fill shape.
// Avoid warning message when antialiasing is enabled if line width does not support antialiasing.
draw_rect(Rect2(Point2(), get_size()), line_color, false, line_width, line_width >= 0.0 ? antialiased : false);
}
} break;
}
}

void ColorRect::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "color") {
if (!draw_background) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
}

if (p_property.name == "line_color" || p_property.name == "line_width") {
if (!draw_outline) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
}
}

void ColorRect::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_background", "draw_background"), &ColorRect::set_draw_background);
ClassDB::bind_method(D_METHOD("is_drawing_background"), &ColorRect::is_drawing_background);

ClassDB::bind_method(D_METHOD("set_color", "color"), &ColorRect::set_color);
ClassDB::bind_method(D_METHOD("get_color"), &ColorRect::get_color);

ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &ColorRect::set_antialiased);
ClassDB::bind_method(D_METHOD("is_antialiased"), &ColorRect::is_antialiased);

ClassDB::bind_method(D_METHOD("set_draw_outline", "draw_outline"), &ColorRect::set_draw_outline);
ClassDB::bind_method(D_METHOD("is_drawing_outline"), &ColorRect::is_drawing_outline);

ClassDB::bind_method(D_METHOD("set_line_color", "color"), &ColorRect::set_line_color);
ClassDB::bind_method(D_METHOD("get_line_color"), &ColorRect::get_line_color);

ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &ColorRect::set_line_width);
ClassDB::bind_method(D_METHOD("get_line_width"), &ColorRect::get_line_width);

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_background"), "set_draw_background", "is_drawing_background");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_outline"), "set_draw_outline", "is_drawing_outline");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "line_color"), "set_line_color", "get_line_color");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_width", PROPERTY_HINT_RANGE, "-1.0,100.0,0.01,or_greater"), "set_line_width", "get_line_width");
}
21 changes: 21 additions & 0 deletions scene/gui/color_rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,36 @@
class ColorRect : public Control {
GDCLASS(ColorRect, Control);

bool draw_background = true;
Color color = Color(1, 1, 1);
bool antialiased = false;
bool draw_outline = false;
Color line_color = Color(1, 1, 1);
float line_width = 1.0f;

protected:
void _notification(int p_what);
void _validate_property(PropertyInfo &p_property) const;
static void _bind_methods();

public:
void set_draw_background(bool p_draw_background);
bool is_drawing_background() const;

void set_color(const Color &p_color);
Color get_color() const;

void set_antialiased(bool p_antialiased);
bool is_antialiased() const;

void set_draw_outline(bool p_draw_outline);
bool is_drawing_outline() const;

void set_line_color(const Color &p_color);
Color get_line_color() const;

void set_line_width(float p_width);
float get_line_width() const;
};

#endif // COLOR_RECT_H

0 comments on commit 0c239bd

Please sign in to comment.