-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
editor: allow hit testing over text and text runs
This PR includes all the changes on the editor and the runtime side to make text and text runs listen to mouse events. This PR is best reviewed commit-by-commit. Roughly the changes include, 1. Previously, all hit targets had to be world transform components. I had to relax this and added a `isEligibleListenerTarget` function on Component 2. I refactored the adding listener logic to be... recursive. I thought this was easier to reason than to add the same text run logic in many places, since the scrolling handler part would also use this. I'm not sure if they should actually be different though. Moreover, because of HitDrawable's set up to hold a reference to both a drawable and the component, I changed the constructor to account for both. AFAIK, it needs a drawable for the opaque objects check. For text runs, the drawable is actually the parent, not itself. I'm not super happy about this, suggestions welcome. 3. The actual text run hit logic is that I added a 'cached' contours property on the text run, and it is calculated whenever the text recalculates its render styles. I did it here because only the Text object has context on what glyphs should render when clipping or ellipsis is applied. 4. I made sure that only the text runs that are targets would store contours. This is captured in the `Hittable` abstraction. I also made Shapes hittable, and reused the shape's _HitShape for both shapes and text runs. 5. All this logic is also applied to the runtime side. I also ported over the contour finding logic from dart. I made sure that a hover effect works on a text run, as well as on the whole text (which just delegates to its constituent text runs), both in the editor playback and in a nested artboard. I'd like to write some editor tests to make sure the hover gets captured ok. But it could take me a while, so I'm sending this out first. Some relevant Slack discussion: https://2dimensions.slack.com/archives/C07HQ4GS0BH/p1733523977504739 Testing 1. New editor tests 2. Verified hit testing works in scrolling containers and in layouts Diffs= f19a9c9399 editor: allow hit testing over text and text runs (#8719) Co-authored-by: Susan Wang <[email protected]>
- Loading branch information
1 parent
9fdfcf0
commit 819348d
Showing
14 changed files
with
780 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
e37a0f285f937042974686b5022c002b0dd143bb | ||
f19a9c9399997a1e1b4571fe860faf2ed60b7d49 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#ifndef _RIVE_HITTABLE_HPP_ | ||
#define _RIVE_HITTABLE_HPP_ | ||
|
||
#include "rive/math/aabb.hpp" | ||
|
||
namespace rive | ||
{ | ||
class Component; | ||
|
||
// A Component that can be hit-tested via two passes: a faster AABB pass, and a | ||
// more accurate HiFi pass. | ||
class Hittable | ||
{ | ||
public: | ||
static Hittable* from(Component* component); | ||
virtual bool hitTestAABB(const Vec2D& position) = 0; | ||
virtual bool hitTestHiFi(const Vec2D& position, float hitRadius) = 0; | ||
virtual ~Hittable() {} | ||
}; | ||
} // namespace rive | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef _RIVE_RECT_HPP_ | ||
#define _RIVE_RECT_HPP_ | ||
|
||
namespace rive | ||
{ | ||
struct Rect | ||
{ | ||
float left, top, right, bottom; | ||
|
||
Rect(float l, float t, float r, float b) : | ||
left(l), top(t), right(r), bottom(b) | ||
{} | ||
|
||
float width() const { return right - left; } | ||
float height() const { return bottom - top; } | ||
|
||
static Rect fromLTRB(float l, float t, float r, float b) | ||
{ | ||
return Rect(l, t, r, b); | ||
} | ||
}; | ||
} // namespace rive | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#ifndef _RIVE_RECTANGLES_TO_CONTOUR_HPP_ | ||
#define _RIVE_RECTANGLES_TO_CONTOUR_HPP_ | ||
#include <vector> | ||
#include <unordered_set> | ||
#include "rive/math/mat2d.hpp" | ||
#include "rive/math/rect.hpp" | ||
|
||
namespace rive | ||
{ | ||
struct PolygonPoint | ||
{ | ||
Vec2D vec; | ||
int dir; // 0 for horizontal, 1 for vertical | ||
|
||
PolygonPoint(const Vec2D& vec, int dir) : vec(vec), dir(dir) {} | ||
|
||
bool operator==(const PolygonPoint& other) const | ||
{ | ||
return vec == other.vec && dir == other.dir; | ||
} | ||
}; | ||
|
||
struct RectanglesToContour | ||
{ | ||
private: | ||
std::unordered_set<Vec2D> uniquePoints; | ||
std::vector<Rect> rects; | ||
void addUniquePoint(const Vec2D& point); | ||
void addRect(const Rect& rect); | ||
std::vector<std::vector<Vec2D>> computeContours(); | ||
|
||
public: | ||
static std::vector<std::vector<Vec2D>> makeSelectionContours( | ||
const std::vector<Rect>& rects); | ||
}; | ||
} // namespace rive | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include "rive/animation/hittable.hpp" | ||
#include "rive/component.hpp" | ||
#include "rive/shapes/shape.hpp" | ||
#include "rive/text/text_value_run.hpp" | ||
|
||
using namespace rive; | ||
|
||
Hittable* Hittable::from(Component* component) | ||
{ | ||
switch (component->coreType()) | ||
{ | ||
case Shape::typeKey: | ||
return component->as<Shape>(); | ||
case TextValueRun::typeKey: | ||
return component->as<TextValueRun>(); | ||
} | ||
return nullptr; | ||
} |
Oops, something went wrong.