From e1ae49ce9fa55456ce1933c9509f50f2de1cbe44 Mon Sep 17 00:00:00 2001 From: Viktor Kovacs Date: Tue, 10 Nov 2020 10:16:41 +0100 Subject: [PATCH] Connection line disappears if the x coordinate of the end point is lower than the x coordinate of the start point #10 A cubic Bezier curve is completely contained by the bounding box of its control points. --- Sources/NodeEngineTest/GeometryTest.cpp | 63 +++++++++++++++++++ Sources/NodeUIEngine/NUIE_Geometry.cpp | 21 +++++-- Sources/NodeUIEngine/NUIE_Geometry.hpp | 5 +- Sources/NodeUIEngine/NUIE_NodeUIManager.cpp | 2 +- .../NodeUIEngine/NUIE_NodeUIManagerDrawer.cpp | 26 ++++++-- Sources/NodeUIEngine/NUIE_UINodeGroup.cpp | 2 +- 6 files changed, 106 insertions(+), 13 deletions(-) diff --git a/Sources/NodeEngineTest/GeometryTest.cpp b/Sources/NodeEngineTest/GeometryTest.cpp index 2ab63c99..2cca7fda 100644 --- a/Sources/NodeEngineTest/GeometryTest.cpp +++ b/Sources/NodeEngineTest/GeometryTest.cpp @@ -94,4 +94,67 @@ TEST (RectTest) ASSERT (IsEqual (r1.Expand (Size (5.0, 6.0)), Rect::FromCenterAndSize (r1.GetCenter (), r1.GetSize () + Size (5.0, 6.0)))); } +TEST (BoundingRectTest_FromRects) +{ + BoundingRect boundingRect; + ASSERT (!boundingRect.IsValid ()); + + Rect rect1 = Rect::FromPositionAndSize (Point (0, 0), Size (100, 100)); + Rect rect2 = Rect::FromPositionAndSize (Point (10, 10), Size (50, 50)); + Rect rect3 = Rect::FromPositionAndSize (Point (-10, -10), Size (20, 20)); + + boundingRect.AddRect (rect1); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), rect1)); + + boundingRect.AddRect (rect2); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), rect1)); + + boundingRect.AddRect (rect3); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), Rect::FromPositionAndSize (Point (-10, -10), Size (110, 110)))); +} + +TEST (BoundingRectTest_FromPoints) +{ + BoundingRect boundingRect; + ASSERT (!boundingRect.IsValid ()); + + boundingRect.AddPoint (Point (10, 10)); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), Rect::FromPositionAndSize (Point (10, 10), Size (0, 0)))); + + boundingRect.AddPoint (Point (20, 20)); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), Rect::FromPositionAndSize (Point (10, 10), Size (10, 10)))); + + boundingRect.AddPoint (Point (-10, -10)); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), Rect::FromPositionAndSize (Point (-10, -10), Size (30, 30)))); +} + +TEST (BoundingRectTest_FromRectAndPoint) +{ + { + BoundingRect boundingRect; + ASSERT (!boundingRect.IsValid ()); + + boundingRect.AddPoint (Point (-10, -10)); + boundingRect.AddRect (Rect::FromPositionAndSize (Point (0, 0), Size (20, 20))); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), Rect::FromPositionAndSize (Point (-10, -10), Size (30, 30)))); + } + + { + BoundingRect boundingRect; + ASSERT (!boundingRect.IsValid ()); + + boundingRect.AddRect (Rect::FromPositionAndSize (Point (0, 0), Size (20, 20))); + boundingRect.AddPoint (Point (-10, -10)); + ASSERT (boundingRect.IsValid ()); + ASSERT (IsEqual (boundingRect.GetRect (), Rect::FromPositionAndSize (Point (-10, -10), Size (30, 30)))); + } +} + } diff --git a/Sources/NodeUIEngine/NUIE_Geometry.cpp b/Sources/NodeUIEngine/NUIE_Geometry.cpp index 3e40ec1e..6fea6b0b 100644 --- a/Sources/NodeUIEngine/NUIE_Geometry.cpp +++ b/Sources/NodeUIEngine/NUIE_Geometry.cpp @@ -411,13 +411,26 @@ int IntRect::GetHeight () const return height; } -BoundingRectCalculator::BoundingRectCalculator () : +BoundingRect::BoundingRect () : boundingRect (), isValid (false) { } -void BoundingRectCalculator::AddRect (const Rect& rect) +void BoundingRect::AddPoint (const Point& point) +{ + if (!isValid) { + boundingRect = Rect::FromPositionAndSize (point, Size (0.0, 0.0)); + isValid = true; + } else { + boundingRect = Rect::FromTwoPoints ( + Point (std::min (point.GetX (), boundingRect.GetLeft ()), std::min (point.GetY (), boundingRect.GetTop ())), + Point (std::max (point.GetX (), boundingRect.GetRight ()), std::max (point.GetY (), boundingRect.GetBottom ())) + ); + } +} + +void BoundingRect::AddRect (const Rect& rect) { if (!isValid) { boundingRect = rect; @@ -430,12 +443,12 @@ void BoundingRectCalculator::AddRect (const Rect& rect) } } -bool BoundingRectCalculator::IsValid () const +bool BoundingRect::IsValid () const { return isValid; } -const Rect& BoundingRectCalculator::GetRect () const +const Rect& BoundingRect::GetRect () const { DBGASSERT (isValid); return boundingRect; diff --git a/Sources/NodeUIEngine/NUIE_Geometry.hpp b/Sources/NodeUIEngine/NUIE_Geometry.hpp index 5d224715..c66ceb1a 100644 --- a/Sources/NodeUIEngine/NUIE_Geometry.hpp +++ b/Sources/NodeUIEngine/NUIE_Geometry.hpp @@ -150,11 +150,12 @@ class IntRect int height; }; -class BoundingRectCalculator +class BoundingRect { public: - BoundingRectCalculator (); + BoundingRect (); + void AddPoint (const Point& point); void AddRect (const Rect& rect); bool IsValid () const; diff --git a/Sources/NodeUIEngine/NUIE_NodeUIManager.cpp b/Sources/NodeUIEngine/NUIE_NodeUIManager.cpp index 6aab9d1f..e2115f2e 100644 --- a/Sources/NodeUIEngine/NUIE_NodeUIManager.cpp +++ b/Sources/NodeUIEngine/NUIE_NodeUIManager.cpp @@ -460,7 +460,7 @@ void NodeUIManager::ResizeContext (NodeUIDrawingEnvironment& drawingEnv, int new bool NodeUIManager::GetBoundingRect (NodeUIDrawingEnvironment& drawingEnv, Rect& boundingRect) const { - BoundingRectCalculator boundingRectCalculator; + BoundingRect boundingRectCalculator; EnumerateNodes ([&] (const UINodeConstPtr& uiNode) { Rect nodeRect = GetNodeExtendedRect (drawingEnv, uiNode.get ()); boundingRectCalculator.AddRect (nodeRect); diff --git a/Sources/NodeUIEngine/NUIE_NodeUIManagerDrawer.cpp b/Sources/NodeUIEngine/NUIE_NodeUIManagerDrawer.cpp index 1728c0eb..b6b46987 100644 --- a/Sources/NodeUIEngine/NUIE_NodeUIManagerDrawer.cpp +++ b/Sources/NodeUIEngine/NUIE_NodeUIManagerDrawer.cpp @@ -8,6 +8,14 @@ namespace NUIE { +static void GetBezierControlPoints (const Point& beg, const Point& end, Point& controlPoint1, Point& controlPoint2) +{ + double bezierOffsetVal = std::fabs (beg.GetX () - end.GetX ()) / 2.0; + Point bezierOffset (bezierOffsetVal, 0.0); + controlPoint1 = beg + bezierOffset; + controlPoint2 = end - bezierOffset; +} + NodeIdToNodeMap::NodeIdToNodeMap (const NodeUIManager& uiManager) { uiManager.EnumerateNodes ([&] (const UINodeConstPtr& uiNode) { @@ -172,9 +180,9 @@ void NodeUIManagerDrawer::DrawConnections (NodeUIDrawingEnvironment& drawingEnv, void NodeUIManagerDrawer::DrawConnection (NodeUIDrawingEnvironment& drawingEnv, const Pen& pen, const Point& beg, const Point& end) const { DrawingContext& context = drawingEnv.GetDrawingContext (); - double bezierOffsetVal = std::fabs (beg.GetX () - end.GetX ()) / 2.0; - Point bezierOffset (bezierOffsetVal, 0.0); - context.DrawBezier (beg, beg + bezierOffset, end - bezierOffset, end, pen); + Point controlPoint1, controlPoint2; + GetBezierControlPoints (beg, end, controlPoint1, controlPoint2); + context.DrawBezier (beg, controlPoint1, controlPoint2, end, pen); } void NodeUIManagerDrawer::DrawTemporaryConnection (NodeUIDrawingEnvironment& drawingEnv, const Pen& pen, const Point& beg, const Point& end, NodeDrawingModifier::Direction dir) const @@ -274,8 +282,16 @@ void NodeUIManagerDrawer::InitSortedNodeList () const bool NodeUIManagerDrawer::IsConnectionVisible (NodeUIDrawingEnvironment& drawingEnv, const Point& beg, const Point& end) const { - Rect connectionRect = Rect::FromTwoPoints (beg, end); - return IsRectVisible (drawingEnv, connectionRect); + Point controlPoint1, controlPoint2; + GetBezierControlPoints (beg, end, controlPoint1, controlPoint2); + + BoundingRect connectionRect; + connectionRect.AddPoint (beg); + connectionRect.AddPoint (controlPoint1); + connectionRect.AddPoint (controlPoint2); + connectionRect.AddPoint (end); + + return IsRectVisible (drawingEnv, connectionRect.GetRect ()); } bool NodeUIManagerDrawer::IsNodeVisible (NodeUIDrawingEnvironment& drawingEnv, const NodeUIScaleIndependentData& scaleIndependentData, const NodeDrawingModifier* drawModifier, const UINode* uiNode) const diff --git a/Sources/NodeUIEngine/NUIE_UINodeGroup.cpp b/Sources/NodeUIEngine/NUIE_UINodeGroup.cpp index 49f9a638..f54e5a23 100644 --- a/Sources/NodeUIEngine/NUIE_UINodeGroup.cpp +++ b/Sources/NodeUIEngine/NUIE_UINodeGroup.cpp @@ -132,7 +132,7 @@ void UINodeGroup::UpdateDrawingImage (NodeUIDrawingEnvironment& env, const NodeR const SkinParams& skinParams = env.GetSkinParams (); DrawingContext& drawingContext = env.GetDrawingContext (); - BoundingRectCalculator boundingRectCalculator; + BoundingRect boundingRectCalculator; nodes.Enumerate ([&] (const NE::NodeId& nodeId) { Rect nodeRect = rectGetter.GetNodeRect (nodeId); boundingRectCalculator.AddRect (nodeRect);