* feat: working on focusable
* feat: text events to rive native
* feat: runtime text from editor
* feat: text input in the editor
* chore: cleanup
* chore: fix non text builds
* chore: fix warning
* fix: key import in rive_native_web
* feat: text input for web rive_native
* chore: fixes
* chore: cleanup
* fix: remove unused imports
* chore: more tests for missed lines
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
* make file ref counted
* migrate File to refcnt
* add bindable artboard class to keep file reference
* feat(unity): support rcp file and BindableArtboard class (#10228)
* refactor(apple): use updated file bindable artboard apis (#10229)
* update command queue to support bindable artboards
* use bindable artboards on command queue
* self manage view model instances in js runtime
* change remaining viewModelInstanceRuntimes to rcp
* refactor(apple): update view model instances to use rcp (#10298)
* refactor(unity): support rcp ViewModelInstanceRuntime (#10309)
* rebase fix
* deprecate getArtboard in favor of getBindableArtboard
* fix merge
* remove unused lambda capture
* fix rive binding
* feat(Android): RCP File, VMI, and add bindable artboards (#10456)
* refactor: C++ refactors
- Import from long (incorrect) -> jlong
- Header clang-tidy fix
- Use reinterpret_cast instead of C-style cast
- Break out some variables instead of long one liners
- Use auto
- Remove unused env and thisObj
# Conflicts:
# packages/runtime_android/kotlin/src/main/cpp/src/helpers/general.cpp
* docs: Improve documentation on the File class
* feat: Support bindable artboard type and RCP VMIs
# Conflicts:
# packages/runtime_android/kotlin/src/androidTest/java/app/rive/runtime/kotlin/core/RiveDataBindingTest.kt
* feat: Support RCP files
* refactor: Change from +1/-1 ref to just release
* fix: Moved to the more appropriate null pointer for GetStringUTFChars
* replace unref with release
Co-authored-by: Adam <67035612+damzobridge@users.noreply.github.com>
Co-authored-by: David Skuza <david@rive.app>
Co-authored-by: Erik <erik@rive.app>
Co-authored-by: hernan <hernan@rive.app>
Currently, when items are inside a scroll view, when the scroll view is dragged and released, the item's click event will still trigger its listener if the same item is hovered. This adds a way to disable pointer events. In this implementation, when a scroll drag begins, we set the GestureClickPhase to disabled which prevents clicks from being captured.
Co-authored-by: Philip Chung <philterdesign@gmail.com>
Add support for List virtualization as well as a parameter to the ScrollConstraint to support infinite scrolling (Carousel).
There are important caveats with Virtualization enabled:
The List instances enough artboards to fit into their parent's bounds and when not rendered, they are pooled and reused as necessary. Lists can be non-uniform meaning they can consist of more than 1 Artboard (ViewModel) type
Does not currently work when its parent is set to wrap because more complex computations may result when wrapping
In order to use Carousel, virtualization must also be enabled
Infinite scroll only works in a single direction, not both at the same time
Co-authored-by: Philip Chung <philterdesign@gmail.com>
In Flutter, due to how the pointer events are captured, using DateTime.now or Stopwatch at the time the StateMachine receives the pointer event does not provide accurate timestamps, thus the calculation of the pointer delta and elapsed time were inaccurate in the editor. For example, while dragging, the relative x/y delta between mouse move events may be steady, but the difference between DateTime.now and the previous now could vary widely, leading to inconsistent scroll behavior.
This PR updates to use the PointerEvent's timeStamp instead which is more representative of when the pointer event was dispatched. We capture the timeStamp and pass it through to both the Dart and C++ ScrollConstraints in order to correctly do the computation.
Co-authored-by: Philip Chung <philterdesign@gmail.com>
first batch of data bind tests
it covers converterts, binding properties and state machine conditions
also fix some deletion of instances surfaced by tests
Diffs=
c8441a6f67 Nnnn data bind tests (#9180)
Co-authored-by: hernan <hernan@rive.app>
The PR has a lot of file changes, but most of them are updates of the API.
Added comments on the relevant parts of the code.
Currently, triggers used in conditions are only evaluated during the first state transition of a state machine layer.
This prevents, for example, using multiple triggers in the same frame.
Another recurring issue with our current implementation is that if a user has a state machine that initializes like this:
```
Entry ----> Idle --[trigger condition] --> Animation
```
And they fire the trigger before the animation plays, or at the same frame that the animation starts, the trigger will be ignored.
This is not expected, as users want to be able to set all their inputs beforehand and then play the animation.
This PR changes the approach, and instead of ignoring triggers after the first state update, it keeps track of which state machine layers have used the trigger. This allows for all triggers to be used once if they are available regardless of when they the condition is tested.
**Note: the order in which triggers are fired doesn't affect the outcome. It could be an improvement later if we do care about the order.**
Added a test for input triggers, I will add a test for view models once I finish the setup needed for testing view models overall.
Diffs=
f33a5984e2 use triggers per state machine layer (#8853)
Co-authored-by: hernan <hernan@rive.app>
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 <susan@rive.app>
triggers were not being correctly reset, so they would trickle onto the next frame.
This essentially resets triggers on every frame to make sure they are user only once.
In order to support ignoring triggers, the interface of some classes has changed to propagate the boolean down to whoever needs to handle it.
Diffs=
f69757c8dd fix triggers reset (#8732)
Co-authored-by: hernan <hernan@rive.app>
with our new rendering cycle (option C), state machines were sorting their hit components on every frame in some scenarios because the artboard wouldn't reset its flag.
This decouples how state machines check for the sorting status at the cost of one extra byte per state machine instance.
Diffs=
00e9ad43a7 fix sorting hittable components (#8690)
Co-authored-by: hernan <hernan@rive.app>
This PR addresses a runtime limitation where we previously needed to trigger a pointer event to confirm if a listener existed at a specific location. With this update, users in game engines can choose whether pointer events in Rive should block raycasts from hitting items behind a Rive graphic. This change allows for hit testing without triggering the event itself.
I believe this is already available in Flutter, so this PR extends it to other runtimes as well
Diffs=
17474d3e2c feat: expose hit test to runtimes (#8598)
Co-authored-by: Adam <67035612+damzobridge@users.noreply.github.com>
this fixes an issue where we were consuming all loops of option C even if there were no changes.
in order to avoid looping the state machine more times than what is needed, before advancing a nested state machine in the inner loop of the state machine changes attempt, we check if the state has changed.
Diffs=
8296d87711 conditionnally add dirt and advance (#8516)
Co-authored-by: hernan <hernan@rive.app>
This gives better support for smaller screens and side-by-side windows.
Also standardize the formatting check on GitHub on version 17.
Diffs=
e52e9fff29 Drop the ColumnLimit to 80 for clang-format (#8320)
Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
this PR changes multiple files addressing three things:
the first two are pretty basic changes: rename the method `dataContextFromInstance` to `setDataContextFromInstance` and remove the side effect of setting the parent of the data context in `internalDataContext`.
The other change is commented in the code: instead of creating a new data context for nested state machines, it is shared between the nested artboard and its state machines. This was already so in the cpp runtime, but the flutter bridge wasn't doing the same.
Diffs=
eed8230f8 use shared data context between artboard and state machine (#8299)
Co-authored-by: hernan <hernan@rive.app>
It's the dart implementation of the first converters.
It's very similar to the c++ implementation.
Except some commented details of this PR, the rest is basically the same.
Diffs=
727e0ba8b Add data converters to flutter runtime (#8029)
Co-authored-by: hernan <hernan@rive.app>
this PR adds click support to listeners.
Click is a new event type (like pointer down, pointer move).
It encompasses two stages (pointer down + pointer up) in the same object or group of objects that belong to the listener.
It processes all the phases of a click gesture
this PR also:
- guarantees that the click gesture is applied only once per frame (no double actions from overlapping shapes)
- supports starting the click gesture in one shape and ending it in another shape of the same listener (by promoting the hover state to the group and not on individual shapes)
Diffs=
405ca998b add click event support (#7668)
Co-authored-by: hernan <hernan@rive.app>
adds support for viewmodel based transition conditions.
added some comments on the most relevant parts.
The rest is mostly boilerplate code from core objects.
Diffs=
d25b9097d viewmodel transitions runtime (#7680)
Co-authored-by: hernan <hernan@rive.app>
In certain scenarios, there is no need to perform a hit test, so we precompute the conditions and early out from calculating the hit test.
If a shape has only listeners of type PointerDown and PointerUp, and is not an opaque target, it doesn't need to check for move events or exit events, which can save a lot of computations since it will skip most frames.
Diffs=
50bc398c4 Xxxx improve hittest performance (#7584)
Co-authored-by: hernan <hernan@rive.app>
This PR sets the fundamental pieces for PRs that will be coming afterward to support data binding state machines.
The most important parts are:
- bindable properties that will be used as binding points for conditions, listeners, and blend animations
- data bind objects don't extend from Component anymore to decouple them from artboards
- because of that, now data bind objects are written in the context of their bound object so there is a unified way for setting data bind targets
The rest is the usual boilerplate code from core objects and some inheritance changes
Diffs=
b5f342002 add bindable properties for state machines (#7640)
Co-authored-by: hernan <hernan@rive.app>
Replaces computeIntrinsicSize with measureLayout which lets the layout engine call the measure function as necessary to allow the objects that can respond to changes in size to fit as best as they can given the constraints. This allow for better handling of line wrapping, ellipsis, and pushing content under text to the exact boundary of the text when using max width/height options in the layout engine.
I also tied in a few other fixes for how we allocate layout nodes and styles.
Diffs=
da0b71559 Replace computeIntrinsicSize with measureLayout (#7410)
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
Previously, only nested state machines could report events so that listeners in parent artboards could listen for them. This PR adds event reporting for nested simple animations. Had to refactor some stuff to genericize in order for both state machines and linear animations to have similar functionality.
I'm not sure if its possible, or desirable, for nested remap animations to have the same functionality, but that is not included in this PR.
Diffs=
097b68f56 Nested linear animations report events up to parent artboards (#7310)
Co-authored-by: Philip Chung <philterdesign@gmail.com>
First version of randomization to get in UAT for validation.
Diffs=
edac19b06 support randomizing transitions (#7082)
Co-authored-by: hernan <hernan@rive.app>
Race condition when completing in the audio completed callback thread!
Want to add a test here but ran out of time!
Diffs=
8ecc99130 Fixing audio runtimes. (#7007)
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
sort hit shapes when draw order changes and stop propagation on hit success
Diffs=
8bca56dca sort hit shapes when draw order changes and stop propagation on hit s… (#6624)
Co-authored-by: hernan <hernan@rive.app>
Adds an audio engine abstraction (implemented with miniaudio) in Rive. We can selectively replace it with other abstractions later if we find miniaudio isn't well suited everywhere but I'm confident it will be based on flexibility with getting it working in the recorder.
Adds audio support in:
- packages/rive_common
- WASM: rive_audio_wasm.dart
- FFI: rive_audio_ffi.dart
- packages/runtime
- packages/recorder
Subsequent PR will add support in:
- packages/rive_unity
- This is getting meaty enough...
- packages/rive_flutter
- This requires publishing rive_common so I want to make sure this is reviewed and accepted before publishing
- I'd also prefer to merge layout constraints into rive_common before this lands.
Editor features:
- Updated preview window:
<img width="248" alt="CleanShot 2024-01-15 at 14 44 31@2x" src="https://github.com/rive-app/rive/assets/454182/a9588be6-8370-4e22-ab32-af1e9ed71183">
- Preview waveforms in the timeline:
<img width="651" alt="CleanShot 2024-01-15 at 14 44 53@2x" src="https://github.com/rive-app/rive/assets/454182/2710667f-838f-483d-9647-e2bcb9e0237a">
- Subsequent PR will also use threads in web editor build (currently uses a time/frame based decoder to offload ui). I can't do that until I can verify the Shared Memory access is granted once rive_common lands in pub.dev and then we can push to UAT.
Diffs=
73bf11db3 Audio engine (#6454)
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
The [[ syntax requires bash, not merely sh. This patch fixes this by simply running the script and letting it use the binary declared inside.
Diffs=
c5cde614b Fixed clang check. (#6125)
Co-authored-by: Dragoș Tiselice <dragos@rive.app>
- Propagate events up to parent Artboard state machines
- Add Event to Listener types and display in combobox
- Add support for StateMachineListeners to listen for events
Still needs implementation on CPP runtime.
In this example, the rectangles are in a nested artboard. Clicking them fires an event from the nested artboard up to the parent artboard which has a listener which updates an input triggering the animation.
https://github.com/rive-app/rive/assets/186340/22bfb00e-8d1e-46f0-8faa-d2d5e5a1bbfb
Diffs=
1a9dd7e97 Add support to Listeners for events from nested artboards (#5923)
Co-authored-by: Philip Chung <philterdesign@gmail.com>
Follow on to https://github.com/rive-app/rive/pull/5877! Does similar work for the C++ runtime and reconsiders some naming, will likely need to fix some higher level runtimes @zplata.
I renamed the fired to reportedEvent and added in the time delay too.
Diffs=
f96c86fcc Timeline Events for runtime (#5951)
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
Explores an API for triggering events and querying them at runtime.
For Flutter we expose an onEvent callback that you can add a callback to on the StateMachineController:
```dart
final controller = StateMachineController.fromArtboard(artboard, 'bumpy', onEvent: {);
controller.onEvent = (event) {
// Do something with event. Like:
if(event is OpenURLEvent) {
launchUrl(event.url);
}
};
artboard.addController(controller!);
```
Note that I haven't piped onEvent to the Flutter runtime yet but you'll see it in the StateMachineController in core.
In C++:
```c++
auto count = stateMachineInstance->firedEventCount();
for(auto i = 0; i < count; i++) {
auto event = stateMachineInstance->firedEventAt(i);
if(event->is<OpenURLEvent>()) {
// Do something with the url.
auto url = event->as<OpenURLEvent>()->url();
}
}
```
You can see some of this in action in the state_machine_event_test.cpp.
You can also see the events in the console in the editor:
<img width="717" alt="CleanShot 2023-08-10 at 18 03 22@2x" src="https://github.com/rive-app/rive/assets/454182/af21902a-424d-435b-b5b0-2a43701fe186">
In a follow up PR:
- Ability to trigger events from State (in/out) and Transition (start/end).
- Add custom properties to Events C++ API (currently they are loaded but not tracked against their respective events).
Diffs=
8caa7d377 Event triggering (#5793)
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>