From 2491c87f8658696509c58985c3c075d32e585305 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 9 Jul 2019 15:22:01 +0200 Subject: [PATCH] Add `width` and `antialiased` parameters to CanvasItem `draw_rect()` This also removes some duplicated editor code which is now obsoleted by the new parameters in `draw_rect()`. --- doc/classes/CanvasItem.xml | 7 +++- editor/plugins/curve_editor_plugin.cpp | 19 +-------- editor/plugins/curve_editor_plugin.h | 2 - editor/plugins/spatial_editor_plugin.cpp | 21 +--------- scene/2d/canvas_item.cpp | 52 +++++++++++++++++++++--- scene/2d/canvas_item.h | 2 +- 6 files changed, 56 insertions(+), 47 deletions(-) diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 5ac825ddcda..79e36760684 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -223,8 +223,13 @@ + + + + - Draws a colored rectangle. + Draws a rectangle. If [code]filled[/code] is [code]true[/code], the rectangle will be filled with the [code]color[/code] specified. If [code]filled[/code] is [code]false[/code], the rectangle will be drawn as a stroke with the [code]color[/code] and [code]width[/code] specified. If [code]antialiased[/code] is [code]true[/code], the lines will be antialiased. + [b]Note:[/b] [code]width[/code] and [code]antialiased[/code] are only effective if [code]filled[/code] is [code]false[/code]. diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index d2d2b8f1303..33f685892c1 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -715,7 +715,7 @@ void CurveEditor::_draw() { if (_hover_point != -1) { const Color hover_color = line_color; Vector2 pos = curve.get_point_position(_hover_point); - stroke_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(_hover_radius), hover_color); + draw_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(_hover_radius), hover_color, false, Math::round(EDSCALE)); } // Help text @@ -726,23 +726,6 @@ void CurveEditor::_draw() { } } -// TODO That should be part of the drawing API... -void CurveEditor::stroke_rect(Rect2 rect, Color color) { - - // a---b - // | | - // c---d - Vector2 a(rect.position); - Vector2 b(rect.position.x + rect.size.x, rect.position.y); - Vector2 c(rect.position.x, rect.position.y + rect.size.y); - Vector2 d(rect.position + rect.size); - - draw_line(a, b, color, Math::round(EDSCALE)); - draw_line(b, d, color, Math::round(EDSCALE)); - draw_line(d, c, color, Math::round(EDSCALE)); - draw_line(c, a, color, Math::round(EDSCALE)); -} - void CurveEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &CurveEditor::on_gui_input); ClassDB::bind_method(D_METHOD("_on_preset_item_selected"), &CurveEditor::on_preset_item_selected); diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index be774a96968..2e2bf1c26fe 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -97,8 +97,6 @@ private: void _draw(); - void stroke_rect(Rect2 rect, Color color); - private: Transform2D _world_to_view; diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index fc72f25b04f..66663d0cd9a 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2348,23 +2348,6 @@ void SpatialEditorViewport::_notification(int p_what) { } } -// TODO That should be part of the drawing API... -static void stroke_rect(CanvasItem &ci, Rect2 rect, Color color, real_t width = 1.0) { - - // a---b - // | | - // c---d - Vector2 a(rect.position); - Vector2 b(rect.position.x + rect.size.x, rect.position.y); - Vector2 c(rect.position.x, rect.position.y + rect.size.y); - Vector2 d(rect.position + rect.size); - - ci.draw_line(a, b, color, width); - ci.draw_line(b, d, color, width); - ci.draw_line(d, c, color, width); - ci.draw_line(c, a, color, width); -} - static void draw_indicator_bar(Control &surface, real_t fill, Ref icon) { // Adjust bar size from control height @@ -2379,7 +2362,7 @@ static void draw_indicator_bar(Control &surface, real_t fill, Ref icon) // Draw both neutral dark and bright colors to account this surface.draw_rect(r, Color(1, 1, 1, 0.2)); surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6)); - stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7)); + surface.draw_rect(r.grow(1), Color(0, 0, 0, 0.7), false, Math::round(EDSCALE)); Vector2 icon_size = icon->get_size(); Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2); @@ -2460,7 +2443,7 @@ void SpatialEditorViewport::_draw() { draw_rect = Rect2(Vector2(), s).clip(draw_rect); - stroke_rect(*surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0); + surface->draw_rect(draw_rect, Color(0.6, 0.6, 0.1, 0.5), false, Math::round(2 * EDSCALE)); } else { diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 23f6404e3ef..7d1cf957ed3 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -759,7 +759,7 @@ void CanvasItem::draw_multiline_colors(const Vector &p_points, const Vec VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); } -void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled) { +void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -767,13 +767,53 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil } if (p_filled) { + if (p_width != 1.0) { + WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\"."); + } + + if (p_antialiased) { + WARN_PRINT("The draw_rect() \"antialiased\" argument has no effect when \"filled\" is \"true\"."); + } VisualServer::get_singleton()->canvas_item_add_rect(canvas_item, p_rect, p_color); } else { - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position, p_rect.position + Size2(p_rect.size.width, 0), p_color); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position, p_rect.position + Size2(0, p_rect.size.height), p_color); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position + Point2(0, p_rect.size.height), p_rect.position + p_rect.size, p_color); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position + Point2(p_rect.size.width, 0), p_rect.position + p_rect.size, p_color); + // Thick lines are offset depending on their width to avoid partial overlapping. + // Thin lines don't require an offset, so don't apply one in this case + float offset; + if (p_width >= 2) { + offset = p_width / 2.0; + } else { + offset = 0.0; + } + + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(-offset, 0), + p_rect.position + Size2(p_rect.size.width + offset, 0), + p_color, + p_width, + p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(0, offset), + p_rect.position + Size2(0, p_rect.size.height - offset), + p_color, + p_width, + p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(-offset, p_rect.size.height), + p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height), + p_color, + p_width, + p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(p_rect.size.width, offset), + p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), + p_color, + p_width, + p_antialiased); } } @@ -1158,7 +1198,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled"), &CanvasItem::draw_rect, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle); ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 2604eb04e41..9c6799a441d 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -307,7 +307,7 @@ public: void draw_polyline_colors(const Vector &p_points, const Vector &p_colors, float p_width = 1.0, bool p_antialiased = false); void draw_multiline(const Vector &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_multiline_colors(const Vector &p_points, const Vector &p_colors, float p_width = 1.0, bool p_antialiased = false); - void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true); + void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false); void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); void draw_texture(const Ref &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref &p_normal_map = Ref()); void draw_texture_rect(const Ref &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref());